Merge pull request #2053 from SiboVG/issue-2040

[#2040] Fix CM of launch lug & rail button instances
This commit is contained in:
Sibo Van Gool 2023-02-21 23:32:39 +01:00 committed by GitHub
commit 9618fdb400
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 540 additions and 21 deletions

View File

@ -102,7 +102,7 @@ public abstract class ExternalComponent extends RocketComponent {
*/
@Override
public double getComponentMass() {
return material.getDensity() * getComponentVolume();
return material.getDensity() * getComponentVolume() * getInstanceCount();
}
/**

View File

@ -20,7 +20,7 @@ public class LaunchLug extends Tube implements AnglePositionable, BoxBounded, Li
private double radius;
private double thickness;
private double angleOffsetRadians = Math.PI;
private double angleOffsetRad = Math.PI;
private double radialOffset = 0;
private int instanceCount = 1;
@ -97,7 +97,7 @@ public class LaunchLug extends Tube implements AnglePositionable, BoxBounded, Li
@Override
public double getAngleOffset() {
return this.angleOffsetRadians;
return this.angleOffsetRad;
}
@Override
@ -109,9 +109,9 @@ public class LaunchLug extends Tube implements AnglePositionable, BoxBounded, Li
}
double clamped_rad = MathUtil.clamp( newAngleRadians, -Math.PI, Math.PI);
if (MathUtil.equals(this.angleOffsetRadians, clamped_rad))
if (MathUtil.equals(this.angleOffsetRad, clamped_rad))
return;
this.angleOffsetRadians = clamped_rad;
this.angleOffsetRad = clamped_rad;
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
}
@ -159,8 +159,8 @@ public class LaunchLug extends Tube implements AnglePositionable, BoxBounded, Li
public Coordinate[] getInstanceOffsets(){
Coordinate[] toReturn = new Coordinate[this.getInstanceCount()];
final double yOffset = Math.cos(angleOffsetRadians) * (radialOffset);
final double zOffset = Math.sin(angleOffsetRadians) * (radialOffset);
final double yOffset = Math.cos(angleOffsetRad) * (radialOffset);
final double zOffset = Math.sin(angleOffsetRad) * (radialOffset);
for ( int index=0; index < this.getInstanceCount(); index++){
toReturn[index] = new Coordinate(index*this.instanceSeparation, yOffset, zOffset);
@ -228,7 +228,10 @@ public class LaunchLug extends Tube implements AnglePositionable, BoxBounded, Li
@Override
public Coordinate getComponentCG() {
return new Coordinate(length / 2, 0, 0, getComponentMass());
final double CMx = length / 2 + (instanceSeparation * (instanceCount-1)) / 2;
final double CMy = Math.cos(this.angleOffsetRad)*getOuterRadius();
final double CMz = Math.sin(this.angleOffsetRad)*getOuterRadius();
return new Coordinate(CMx, CMy, CMz, getComponentMass());
}
@Override

View File

@ -51,7 +51,7 @@ public class RailButton extends ExternalComponent implements AnglePositionable,
private double radialDistance_m=0;
protected static final AngleMethod angleMethod = AngleMethod.RELATIVE;
private double angle_rad = Math.PI;
private double angleOffsetRad = Math.PI;
private int instanceCount = 1;
private double instanceSeparation = 0; // front-front along the positive rocket axis. i.e. [1,0,0];
@ -210,7 +210,7 @@ public class RailButton extends ExternalComponent implements AnglePositionable,
@Override
public double getAngleOffset(){
return angle_rad;
return angleOffsetRad;
}
@Override
@ -234,9 +234,9 @@ public class RailButton extends ExternalComponent implements AnglePositionable,
double clamped_rad = MathUtil.clamp(angle_rad, -Math.PI, Math.PI);
if (MathUtil.equals(this.angle_rad, clamped_rad))
if (MathUtil.equals(this.angleOffsetRad, clamped_rad))
return;
this.angle_rad = clamped_rad;
this.angleOffsetRad = clamped_rad;
fireComponentChangeEvent(ComponentChangeEvent.AERODYNAMIC_CHANGE);
}
@ -265,8 +265,8 @@ public class RailButton extends ExternalComponent implements AnglePositionable,
public Coordinate[] getInstanceOffsets(){
Coordinate[] toReturn = new Coordinate[this.getInstanceCount()];
final double yOffset = Math.cos(this.angle_rad) * ( this.radialDistance_m );
final double zOffset = Math.sin(this.angle_rad) * ( this.radialDistance_m );
final double yOffset = Math.cos(this.angleOffsetRad) * ( this.radialDistance_m );
final double zOffset = Math.sin(this.angleOffsetRad) * ( this.radialDistance_m );
for ( int index=0; index < this.getInstanceCount(); index++){
toReturn[index] = new Coordinate(index*this.instanceSeparation, yOffset, zOffset);
@ -384,13 +384,14 @@ public class RailButton extends ExternalComponent implements AnglePositionable,
if (heightCM > this.totalHeight_m + this.screwHeight_m) {
throw new BugException(" bug found while computing the CG of a RailButton: "+this.getName()+"\n height of CG: "+heightCM);
}
final double CMx = (instanceSeparation * (instanceCount-1)) / 2;
final double CMy = Math.cos(this.angleOffsetRad)*heightCM;
final double CMz = Math.sin(this.angleOffsetRad)*heightCM;
final double CMy = Math.cos(this.angle_rad)*heightCM;
final double CMz = Math.sin(this.angle_rad)*heightCM;
return new Coordinate( 0, CMy, CMz, getComponentMass());
return new Coordinate( CMx, CMy, CMz, getComponentMass());
}
@Override
public String getComponentName() {
return trans.get("RailButton.RailButton");

View File

@ -65,7 +65,8 @@ public class MassCalculatorTest extends BaseTestCase {
assertEquals(" Alpha III Empty Mass is incorrect: ", expRocketDryMass, actualRocketDryMass, EPSILON);
double expCMx = 0.1917685523;
Coordinate expCM = new Coordinate(expCMx, 0, 0, expRocketDryMass);
double expCMy = -0.00006340812673; // Slight offset due to launch lug
Coordinate expCM = new Coordinate(expCMx, expCMy, 0, expRocketDryMass);
assertEquals("Simple Rocket CM.x is incorrect: ", expCM.x, actualRocketDryCM.x, EPSILON);
assertEquals("Simple Rocket CM.y is incorrect: ", expCM.y, actualRocketDryCM.y, EPSILON);
assertEquals("Simple Rocket CM.z is incorrect: ", expCM.z, actualRocketDryCM.z, EPSILON);
@ -117,7 +118,8 @@ public class MassCalculatorTest extends BaseTestCase {
assertEquals(" Alpha III Total Mass (with motor: " + desig + ") is incorrect: ", expRocketLaunchMass, actualRocketLaunchMass, EPSILON);
double expCMx = 0.20996455968266833;
Coordinate expCM = new Coordinate(expCMx, 0, 0, expRocketLaunchMass);
double expCMy = -0.00003845163503; // Slight offset due to launch lug
Coordinate expCM = new Coordinate(expCMx, expCMy, 0, expRocketLaunchMass);
assertEquals("Simple Rocket CM.x is incorrect: ", expCM.x, actualRocketLaunchCM.x, EPSILON);
assertEquals("Simple Rocket CM.y is incorrect: ", expCM.y, actualRocketLaunchCM.y, EPSILON);
assertEquals("Simple Rocket CM.z is incorrect: ", expCM.z, actualRocketLaunchCM.z, EPSILON);

View File

@ -63,5 +63,255 @@ public class LaunchLugTest extends BaseTestCase {
assertEquals(" LaunchLug #2 is in the wrong place: ", expPos, actPos[1]);
}
}
@Test
public void testCMSingleInstance() {
BodyTube bodyTube = new BodyTube();
LaunchLug lug = new LaunchLug();
lug.setLength(0.1);
lug.setOuterRadius(0.02);
bodyTube.addChild(lug);
// Test normal CG
Coordinate CG = lug.getCG();
assertEquals(" LaunchLug CG has the wrong x value: ", 0.05, CG.x, EPSILON);
assertEquals(" LaunchLug CG has the wrong y value: ", -0.02, CG.y, EPSILON);
assertEquals(" LaunchLug CG has the wrong z value: ", 0, CG.z, EPSILON);
assertEquals(" LaunchLug CM has the wrong value: ", 0.008331504, CG.weight, EPSILON);
// Test rotated CG
lug.setAngleOffset(Math.PI / 2);
CG = lug.getCG();
assertEquals(" LaunchLug CG has the wrong x value: ", 0.05, CG.x, EPSILON);
assertEquals(" LaunchLug CG has the wrong y value: ", 0, CG.y, EPSILON);
assertEquals(" LaunchLug CG has the wrong z value: ", 0.02, CG.z, EPSILON);
assertEquals(" LaunchLug CM has the wrong value: ", 0.008331504, CG.weight, EPSILON);
lug.setAngleOffset(-Math.PI / 3);
CG = lug.getCG();
assertEquals(" LaunchLug CG has the wrong x value: ", 0.05, CG.x, EPSILON);
assertEquals(" LaunchLug CG has the wrong y value: ", 0.01, CG.y, EPSILON);
assertEquals(" LaunchLug CG has the wrong z value: ", -0.0173205, CG.z, EPSILON);
assertEquals(" LaunchLug CM has the wrong value: ", 0.008331504, CG.weight, EPSILON);
// Change dimensions
lug.setLength(0.05);
lug.setOuterRadius(0.015);
lug.setAngleOffset(0);
CG = lug.getCG();
assertEquals(" LaunchLug CG has the wrong x value: ", 0.025, CG.x, EPSILON);
assertEquals(" LaunchLug CG has the wrong y value: ", 0.015, CG.y, EPSILON);
assertEquals(" LaunchLug CG has the wrong z value: ", 0, CG.z, EPSILON);
assertEquals(" LaunchLug CM has the wrong value: ", 0.00309761, CG.weight, EPSILON);
// Test rotated CG
lug.setAngleOffset(Math.PI / 2);
CG = lug.getCG();
assertEquals(" LaunchLug CG has the wrong x value: ", 0.025, CG.x, EPSILON);
assertEquals(" LaunchLug CG has the wrong y value: ", 0, CG.y, EPSILON);
assertEquals(" LaunchLug CG has the wrong z value: ", 0.015, CG.z, EPSILON);
assertEquals(" LaunchLug CM has the wrong value: ", 0.00309761, CG.weight, EPSILON);
lug.setAngleOffset(-Math.PI / 3);
CG = lug.getCG();
assertEquals(" LaunchLug CG has the wrong x value: ", 0.025, CG.x, EPSILON);
assertEquals(" LaunchLug CG has the wrong y value: ", 0.0075, CG.y, EPSILON);
assertEquals(" LaunchLug CG has the wrong z value: ", -0.01299038, CG.z, EPSILON);
assertEquals(" LaunchLug CM has the wrong value: ", 0.00309761, CG.weight, EPSILON);
}
@Test
public void testCMSingleInstanceOverride() {
BodyTube bodyTube = new BodyTube();
LaunchLug lug = new LaunchLug();
lug.setLength(0.1);
lug.setOuterRadius(0.02);
lug.setCGOverridden(true);
lug.setOverrideCGX(0.0123);
bodyTube.addChild(lug);
// Test normal CG
Coordinate CG = lug.getCG();
assertEquals(" LaunchLug CG has the wrong x value: ", 0.0123, CG.x, EPSILON);
assertEquals(" LaunchLug CG has the wrong y value: ", -0.02, CG.y, EPSILON);
assertEquals(" LaunchLug CG has the wrong z value: ", 0, CG.z, EPSILON);
assertEquals(" LaunchLug CM has the wrong value: ", 0.008331504, CG.weight, EPSILON);
// Test rotated CG
lug.setAngleOffset(Math.PI / 2);
CG = lug.getCG();
assertEquals(" LaunchLug CG has the wrong x value: ", 0.0123, CG.x, EPSILON);
assertEquals(" LaunchLug CG has the wrong y value: ", 0, CG.y, EPSILON);
assertEquals(" LaunchLug CG has the wrong z value: ", 0.02, CG.z, EPSILON);
assertEquals(" LaunchLug CM has the wrong value: ", 0.008331504, CG.weight, EPSILON);
lug.setAngleOffset(-Math.PI / 3);
CG = lug.getCG();
assertEquals(" LaunchLug CG has the wrong x value: ", 0.0123, CG.x, EPSILON);
assertEquals(" LaunchLug CG has the wrong y value: ", 0.01, CG.y, EPSILON);
assertEquals(" LaunchLug CG has the wrong z value: ", -0.0173205, CG.z, EPSILON);
assertEquals(" LaunchLug CM has the wrong value: ", 0.008331504, CG.weight, EPSILON);
// Change dimensions
lug.setLength(0.05);
lug.setOuterRadius(0.015);
lug.setAngleOffset(0);
lug.setOverrideCGX(0.0321);
lug.setMassOverridden(true);
lug.setOverrideMass(0.1);
CG = lug.getCG();
assertEquals(" LaunchLug CG has the wrong x value: ", 0.0321, CG.x, EPSILON);
assertEquals(" LaunchLug CG has the wrong y value: ", 0.015, CG.y, EPSILON);
assertEquals(" LaunchLug CG has the wrong z value: ", 0, CG.z, EPSILON);
assertEquals(" LaunchLug CM has the wrong value: ", 0.1, CG.weight, EPSILON);
// Test rotated CG
lug.setAngleOffset(Math.PI / 2);
CG = lug.getCG();
assertEquals(" LaunchLug CG has the wrong x value: ", 0.0321, CG.x, EPSILON);
assertEquals(" LaunchLug CG has the wrong y value: ", 0, CG.y, EPSILON);
assertEquals(" LaunchLug CG has the wrong z value: ", 0.015, CG.z, EPSILON);
assertEquals(" LaunchLug CM has the wrong value: ", 0.1, CG.weight, EPSILON);
lug.setAngleOffset(-Math.PI / 3);
CG = lug.getCG();
assertEquals(" LaunchLug CG has the wrong x value: ", 0.0321, CG.x, EPSILON);
assertEquals(" LaunchLug CG has the wrong y value: ", 0.0075, CG.y, EPSILON);
assertEquals(" LaunchLug CG has the wrong z value: ", -0.01299038, CG.z, EPSILON);
assertEquals(" LaunchLug CM has the wrong value: ", 0.1, CG.weight, EPSILON);
}
@Test
public void testCMMultipleInstances() {
BodyTube bodyTube = new BodyTube();
LaunchLug lug = new LaunchLug();
lug.setLength(0.1);
lug.setOuterRadius(0.02);
lug.setInstanceCount(3);
lug.setInstanceSeparation(0.2);
bodyTube.addChild(lug);
// Test normal CG
Coordinate CG = lug.getCG();
assertEquals(" LaunchLug CG has the wrong x value: ", 0.25, CG.x, EPSILON);
assertEquals(" LaunchLug CG has the wrong y value: ", -0.02, CG.y, EPSILON);
assertEquals(" LaunchLug CG has the wrong z value: ", 0, CG.z, EPSILON);
assertEquals(" LaunchLug CM has the wrong value: ", 0.024994512, CG.weight, EPSILON);
// Test rotated CG
lug.setAngleOffset(Math.PI / 2);
CG = lug.getCG();
assertEquals(" LaunchLug CG has the wrong x value: ", 0.25, CG.x, EPSILON);
assertEquals(" LaunchLug CG has the wrong y value: ", 0, CG.y, EPSILON);
assertEquals(" LaunchLug CG has the wrong z value: ", 0.02, CG.z, EPSILON);
assertEquals(" LaunchLug CM has the wrong value: ", 0.024994512, CG.weight, EPSILON);
lug.setAngleOffset(-Math.PI / 3);
CG = lug.getCG();
assertEquals(" LaunchLug CG has the wrong x value: ", 0.25, CG.x, EPSILON);
assertEquals(" LaunchLug CG has the wrong y value: ", 0.01, CG.y, EPSILON);
assertEquals(" LaunchLug CG has the wrong z value: ", -0.0173205, CG.z, EPSILON);
assertEquals(" LaunchLug CM has the wrong value: ", 0.024994512, CG.weight, EPSILON);
// Change dimensions
lug.setLength(0.05);
lug.setOuterRadius(0.015);
lug.setAngleOffset(0);
lug.setInstanceCount(2);
lug.setInstanceSeparation(0.15);
CG = lug.getCG();
assertEquals(" LaunchLug CG has the wrong x value: ", 0.1, CG.x, EPSILON);
assertEquals(" LaunchLug CG has the wrong y value: ", 0.015, CG.y, EPSILON);
assertEquals(" LaunchLug CG has the wrong z value: ", 0, CG.z, EPSILON);
assertEquals(" LaunchLug CM has the wrong value: ", 0.00619522, CG.weight, EPSILON);
// Test rotated CG
lug.setAngleOffset(Math.PI / 2);
CG = lug.getCG();
assertEquals(" LaunchLug CG has the wrong x value: ", 0.1, CG.x, EPSILON);
assertEquals(" LaunchLug CG has the wrong y value: ", 0, CG.y, EPSILON);
assertEquals(" LaunchLug CG has the wrong z value: ", 0.015, CG.z, EPSILON);
assertEquals(" LaunchLug CM has the wrong value: ", 0.00619522, CG.weight, EPSILON);
lug.setAngleOffset(-Math.PI / 3);
CG = lug.getCG();
assertEquals(" LaunchLug CG has the wrong x value: ", 0.1, CG.x, EPSILON);
assertEquals(" LaunchLug CG has the wrong y value: ", 0.0075, CG.y, EPSILON);
assertEquals(" LaunchLug CG has the wrong z value: ", -0.01299038, CG.z, EPSILON);
assertEquals(" LaunchLug CM has the wrong value: ", 0.00619522, CG.weight, EPSILON);
}
@Test
public void testCMMultipleInstancesOverride() {
BodyTube bodyTube = new BodyTube();
LaunchLug lug = new LaunchLug();
lug.setLength(0.1);
lug.setOuterRadius(0.02);
lug.setInstanceCount(3);
lug.setInstanceSeparation(0.2);
lug.setCGOverridden(true);
lug.setOverrideCGX(0.0123);
bodyTube.addChild(lug);
// Test normal CG
Coordinate CG = lug.getCG();
assertEquals(" LaunchLug CG has the wrong x value: ", 0.0123, CG.x, EPSILON);
assertEquals(" LaunchLug CG has the wrong y value: ", -0.02, CG.y, EPSILON);
assertEquals(" LaunchLug CG has the wrong z value: ", 0, CG.z, EPSILON);
assertEquals(" LaunchLug CM has the wrong value: ", 0.024994512, CG.weight, EPSILON);
// Test rotated CG
lug.setAngleOffset(Math.PI / 2);
CG = lug.getCG();
assertEquals(" LaunchLug CG has the wrong x value: ", 0.0123, CG.x, EPSILON);
assertEquals(" LaunchLug CG has the wrong y value: ", 0, CG.y, EPSILON);
assertEquals(" LaunchLug CG has the wrong z value: ", 0.02, CG.z, EPSILON);
assertEquals(" LaunchLug CM has the wrong value: ", 0.024994512, CG.weight, EPSILON);
lug.setAngleOffset(-Math.PI / 3);
CG = lug.getCG();
assertEquals(" LaunchLug CG has the wrong x value: ", 0.0123, CG.x, EPSILON);
assertEquals(" LaunchLug CG has the wrong y value: ", 0.01, CG.y, EPSILON);
assertEquals(" LaunchLug CG has the wrong z value: ", -0.0173205, CG.z, EPSILON);
assertEquals(" LaunchLug CM has the wrong value: ", 0.024994512, CG.weight, EPSILON);
// Change dimensions
lug.setLength(0.05);
lug.setOuterRadius(0.015);
lug.setAngleOffset(0);
lug.setInstanceCount(2);
lug.setInstanceSeparation(0.15);
lug.setOverrideCGX(0.0321);
lug.setMassOverridden(true);
lug.setOverrideMass(0.2);
CG = lug.getCG();
assertEquals(" LaunchLug CG has the wrong x value: ", 0.0321, CG.x, EPSILON);
assertEquals(" LaunchLug CG has the wrong y value: ", 0.015, CG.y, EPSILON);
assertEquals(" LaunchLug CG has the wrong z value: ", 0, CG.z, EPSILON);
assertEquals(" LaunchLug CM has the wrong value: ", 0.2, CG.weight, EPSILON);
// Test rotated CG
lug.setAngleOffset(Math.PI / 2);
CG = lug.getCG();
assertEquals(" LaunchLug CG has the wrong x value: ", 0.0321, CG.x, EPSILON);
assertEquals(" LaunchLug CG has the wrong y value: ", 0, CG.y, EPSILON);
assertEquals(" LaunchLug CG has the wrong z value: ", 0.015, CG.z, EPSILON);
assertEquals(" LaunchLug CM has the wrong value: ", 0.2, CG.weight, EPSILON);
lug.setAngleOffset(-Math.PI / 3);
CG = lug.getCG();
assertEquals(" LaunchLug CG has the wrong x value: ", 0.0321, CG.x, EPSILON);
assertEquals(" LaunchLug CG has the wrong y value: ", 0.0075, CG.y, EPSILON);
assertEquals(" LaunchLug CG has the wrong z value: ", -0.01299038, CG.z, EPSILON);
assertEquals(" LaunchLug CM has the wrong value: ", 0.2, CG.weight, EPSILON);
}
}

View File

@ -0,0 +1,263 @@
package net.sf.openrocket.rocketcomponent;
import net.sf.openrocket.util.BaseTestCase.BaseTestCase;
import net.sf.openrocket.util.Coordinate;
import net.sf.openrocket.util.MathUtil;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class RailButtonTest extends BaseTestCase {
protected final double EPSILON = MathUtil.EPSILON;
@Test
public void testCMSingleInstance() {
BodyTube bodyTube = new BodyTube();
RailButton button = new RailButton();
button.setOuterDiameter(0.05);
button.setTotalHeight(0.05);
bodyTube.addChild(button);
// Test normal CG
Coordinate CG = button.getCG();
assertEquals(" RailButton CG has the wrong x value: ", 0, CG.x, EPSILON);
assertEquals(" RailButton CG has the wrong y value: ", -0.025, CG.y, EPSILON);
assertEquals(" RailButton CG has the wrong z value: ", 0, CG.z, EPSILON);
assertEquals(" RailButton CM has the wrong value: ", 0.014435995, CG.weight, EPSILON);
// Test rotated CG
button.setAngleOffset(Math.PI / 2);
CG = button.getCG();
assertEquals(" RailButton CG has the wrong x value: ", 0, CG.x, EPSILON);
assertEquals(" RailButton CG has the wrong y value: ", 0, CG.y, EPSILON);
assertEquals(" RailButton CG has the wrong z value: ", 0.025, CG.z, EPSILON);
assertEquals(" RailButton CM has the wrong value: ", 0.014435995, CG.weight, EPSILON);
button.setAngleOffset(-Math.PI / 3);
CG = button.getCG();
assertEquals(" RailButton CG has the wrong x value: ", 0, CG.x, EPSILON);
assertEquals(" RailButton CG has the wrong y value: ", 0.0125, CG.y, EPSILON);
assertEquals(" RailButton CG has the wrong z value: ", -0.02165064, CG.z, EPSILON);
assertEquals(" RailButton CM has the wrong value: ", 0.014435995, CG.weight, EPSILON);
// Change dimensions
button.setOuterDiameter(0.025);
button.setTotalHeight(0.02);
button.setAngleOffset(0);
CG = button.getCG();
assertEquals(" RailButton CG has the wrong x value: ", 0, CG.x, EPSILON);
assertEquals(" RailButton CG has the wrong y value: ", 0.01, CG.y, EPSILON);
assertEquals(" RailButton CG has the wrong z value: ", 0, CG.z, EPSILON);
assertEquals(" RailButton CM has the wrong value: ", 0.003930195, CG.weight, EPSILON);
// Test rotated CG
button.setAngleOffset(Math.PI / 2);
CG = button.getCG();
assertEquals(" RailButton CG has the wrong x value: ", 0, CG.x, EPSILON);
assertEquals(" RailButton CG has the wrong y value: ", 0, CG.y, EPSILON);
assertEquals(" RailButton CG has the wrong z value: ", 0.01, CG.z, EPSILON);
assertEquals(" RailButton CM has the wrong value: ", 0.003930195, CG.weight, EPSILON);
button.setAngleOffset(-Math.PI / 3);
CG = button.getCG();
assertEquals(" RailButton CG has the wrong x value: ", 0, CG.x, EPSILON);
assertEquals(" RailButton CG has the wrong y value: ", 0.005, CG.y, EPSILON);
assertEquals(" RailButton CG has the wrong z value: ", -0.00866025, CG.z, EPSILON);
assertEquals(" RailButton CM has the wrong value: ", 0.003930195, CG.weight, EPSILON);
}
@Test
public void testCMSingleInstanceOverride() {
BodyTube bodyTube = new BodyTube();
RailButton button = new RailButton();
button.setOuterDiameter(0.05);
button.setTotalHeight(0.05);
button.setCGOverridden(true);
button.setOverrideCGX(0.0123);
bodyTube.addChild(button);
// Test normal CG
Coordinate CG = button.getCG();
assertEquals(" RailButton CG has the wrong x value: ", 0.0123, CG.x, EPSILON);
assertEquals(" RailButton CG has the wrong y value: ", -0.025, CG.y, EPSILON);
assertEquals(" RailButton CG has the wrong z value: ", 0, CG.z, EPSILON);
assertEquals(" RailButton CM has the wrong value: ", 0.014435995, CG.weight, EPSILON);
// Test rotated CG
button.setAngleOffset(Math.PI / 2);
CG = button.getCG();
assertEquals(" RailButton CG has the wrong x value: ", 0.0123, CG.x, EPSILON);
assertEquals(" RailButton CG has the wrong y value: ", 0, CG.y, EPSILON);
assertEquals(" RailButton CG has the wrong z value: ", 0.025, CG.z, EPSILON);
assertEquals(" RailButton CM has the wrong value: ", 0.014435995, CG.weight, EPSILON);
button.setAngleOffset(-Math.PI / 3);
CG = button.getCG();
assertEquals(" RailButton CG has the wrong x value: ", 0.0123, CG.x, EPSILON);
assertEquals(" RailButton CG has the wrong y value: ", 0.0125, CG.y, EPSILON);
assertEquals(" RailButton CG has the wrong z value: ", -0.02165064, CG.z, EPSILON);
assertEquals(" RailButton CM has the wrong value: ", 0.014435995, CG.weight, EPSILON);
// Change dimensions
button.setOuterDiameter(0.025);
button.setTotalHeight(0.02);
button.setAngleOffset(0);
button.setOverrideCGX(0.0321);
button.setMassOverridden(true);
button.setOverrideMass(0.1);
CG = button.getCG();
assertEquals(" RailButton CG has the wrong x value: ", 0.0321, CG.x, EPSILON);
assertEquals(" RailButton CG has the wrong y value: ", 0.01, CG.y, EPSILON);
assertEquals(" RailButton CG has the wrong z value: ", 0, CG.z, EPSILON);
assertEquals(" RailButton CM has the wrong value: ", 0.1, CG.weight, EPSILON);
// Test rotated CG
button.setAngleOffset(Math.PI / 2);
CG = button.getCG();
assertEquals(" RailButton CG has the wrong x value: ", 0.0321, CG.x, EPSILON);
assertEquals(" RailButton CG has the wrong y value: ", 0, CG.y, EPSILON);
assertEquals(" RailButton CG has the wrong z value: ", 0.01, CG.z, EPSILON);
assertEquals(" RailButton CM has the wrong value: ", 0.1, CG.weight, EPSILON);
button.setAngleOffset(-Math.PI / 3);
CG = button.getCG();
assertEquals(" RailButton CG has the wrong x value: ", 0.0321, CG.x, EPSILON);
assertEquals(" RailButton CG has the wrong y value: ", 0.005, CG.y, EPSILON);
assertEquals(" RailButton CG has the wrong z value: ", -0.00866025, CG.z, EPSILON);
assertEquals(" RailButton CM has the wrong value: ", 0.1, CG.weight, EPSILON);
}
@Test
public void testCMMultipleInstances() {
BodyTube bodyTube = new BodyTube();
RailButton button = new RailButton();
button.setOuterDiameter(0.05);
button.setTotalHeight(0.05);
button.setInstanceCount(3);
button.setInstanceSeparation(0.2);
bodyTube.addChild(button);
// Test normal CG
Coordinate CG = button.getCG();
assertEquals(" RailButton CG has the wrong x value: ", 0.2, CG.x, EPSILON);
assertEquals(" RailButton CG has the wrong y value: ", -0.025, CG.y, EPSILON);
assertEquals(" RailButton CG has the wrong z value: ", 0, CG.z, EPSILON);
assertEquals(" RailButton CM has the wrong value: ", 0.043307985, CG.weight, EPSILON);
// Test rotated CG
button.setAngleOffset(Math.PI / 2);
CG = button.getCG();
assertEquals(" RailButton CG has the wrong x value: ", 0.2, CG.x, EPSILON);
assertEquals(" RailButton CG has the wrong y value: ", 0, CG.y, EPSILON);
assertEquals(" RailButton CG has the wrong z value: ", 0.025, CG.z, EPSILON);
assertEquals(" RailButton CM has the wrong value: ", 0.043307985, CG.weight, EPSILON);
button.setAngleOffset(-Math.PI / 3);
CG = button.getCG();
assertEquals(" RailButton CG has the wrong x value: ", 0.2, CG.x, EPSILON);
assertEquals(" RailButton CG has the wrong y value: ", 0.0125, CG.y, EPSILON);
assertEquals(" RailButton CG has the wrong z value: ", -0.02165064, CG.z, EPSILON);
assertEquals(" RailButton CM has the wrong value: ", 0.043307985, CG.weight, EPSILON);
// Change dimensions
button.setOuterDiameter(0.025);
button.setTotalHeight(0.02);
button.setAngleOffset(0);
button.setInstanceCount(2);
button.setInstanceSeparation(0.15);
CG = button.getCG();
assertEquals(" RailButton CG has the wrong x value: ", 0.075, CG.x, EPSILON);
assertEquals(" RailButton CG has the wrong y value: ", 0.01, CG.y, EPSILON);
assertEquals(" RailButton CG has the wrong z value: ", 0, CG.z, EPSILON);
assertEquals(" RailButton CM has the wrong value: ", 0.00786039, CG.weight, EPSILON);
// Test rotated CG
button.setAngleOffset(Math.PI / 2);
CG = button.getCG();
assertEquals(" RailButton CG has the wrong x value: ", 0.075, CG.x, EPSILON);
assertEquals(" RailButton CG has the wrong y value: ", 0, CG.y, EPSILON);
assertEquals(" RailButton CG has the wrong z value: ", 0.01, CG.z, EPSILON);
assertEquals(" RailButton CM has the wrong value: ", 0.00786039, CG.weight, EPSILON);
button.setAngleOffset(-Math.PI / 3);
CG = button.getCG();
assertEquals(" RailButton CG has the wrong x value: ", 0.075, CG.x, EPSILON);
assertEquals(" RailButton CG has the wrong y value: ", 0.005, CG.y, EPSILON);
assertEquals(" RailButton CG has the wrong z value: ", -0.00866025, CG.z, EPSILON);
assertEquals(" RailButton CM has the wrong value: ", 0.00786039, CG.weight, EPSILON);
}
@Test
public void testCMMultipleInstancesOverride() {
BodyTube bodyTube = new BodyTube();
RailButton button = new RailButton();
button.setOuterDiameter(0.05);
button.setTotalHeight(0.05);
button.setInstanceCount(3);
button.setInstanceSeparation(0.2);
button.setCGOverridden(true);
button.setOverrideCGX(0.0123);
bodyTube.addChild(button);
// Test normal CG
Coordinate CG = button.getCG();
assertEquals(" RailButton CG has the wrong x value: ", 0.0123, CG.x, EPSILON);
assertEquals(" RailButton CG has the wrong y value: ", -0.025, CG.y, EPSILON);
assertEquals(" RailButton CG has the wrong z value: ", 0, CG.z, EPSILON);
assertEquals(" RailButton CM has the wrong value: ", 0.043307985, CG.weight, EPSILON);
// Test rotated CG
button.setAngleOffset(Math.PI / 2);
CG = button.getCG();
assertEquals(" RailButton CG has the wrong x value: ", 0.0123, CG.x, EPSILON);
assertEquals(" RailButton CG has the wrong y value: ", 0, CG.y, EPSILON);
assertEquals(" RailButton CG has the wrong z value: ", 0.025, CG.z, EPSILON);
assertEquals(" RailButton CM has the wrong value: ", 0.043307985, CG.weight, EPSILON);
button.setAngleOffset(-Math.PI / 3);
CG = button.getCG();
assertEquals(" RailButton CG has the wrong x value: ", 0.0123, CG.x, EPSILON);
assertEquals(" RailButton CG has the wrong y value: ", 0.0125, CG.y, EPSILON);
assertEquals(" RailButton CG has the wrong z value: ", -0.02165064, CG.z, EPSILON);
assertEquals(" RailButton CM has the wrong value: ", 0.043307985, CG.weight, EPSILON);
// Change dimensions
button.setOuterDiameter(0.025);
button.setTotalHeight(0.02);
button.setAngleOffset(0);
button.setInstanceCount(2);
button.setInstanceSeparation(0.15);
button.setOverrideCGX(0.0321);
button.setMassOverridden(true);
button.setOverrideMass(0.2);
CG = button.getCG();
assertEquals(" RailButton CG has the wrong x value: ", 0.0321, CG.x, EPSILON);
assertEquals(" RailButton CG has the wrong y value: ", 0.01, CG.y, EPSILON);
assertEquals(" RailButton CG has the wrong z value: ", 0, CG.z, EPSILON);
assertEquals(" RailButton CM has the wrong value: ", 0.2, CG.weight, EPSILON);
// Test rotated CG
button.setAngleOffset(Math.PI / 2);
CG = button.getCG();
assertEquals(" RailButton CG has the wrong x value: ", 0.0321, CG.x, EPSILON);
assertEquals(" RailButton CG has the wrong y value: ", 0, CG.y, EPSILON);
assertEquals(" RailButton CG has the wrong z value: ", 0.01, CG.z, EPSILON);
assertEquals(" RailButton CM has the wrong value: ", 0.2, CG.weight, EPSILON);
button.setAngleOffset(-Math.PI / 3);
CG = button.getCG();
assertEquals(" RailButton CG has the wrong x value: ", 0.0321, CG.x, EPSILON);
assertEquals(" RailButton CG has the wrong y value: ", 0.005, CG.y, EPSILON);
assertEquals(" RailButton CG has the wrong z value: ", -0.00866025, CG.z, EPSILON);
assertEquals(" RailButton CM has the wrong value: ", 0.2, CG.weight, EPSILON);
}
}