completely revamped attitude models

parent 56b20638
#Fri Mar 21 16:33:31 MET 2008
#Thu Mar 27 11:10:50 GMT+01:00 2008
eclipse.preferences.version=1
org.eclipse.jdt.core.codeComplete.argumentPrefixes=
org.eclipse.jdt.core.codeComplete.argumentSuffixes=
......
......@@ -106,13 +106,22 @@
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>2.1</version>
<configuration>
<configLocation>checkstyle.xml</configLocation>
<enableRulesSummary>false</enableRulesSummary>
</configuration>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<excludes>
<exclude>**/Chunk*Test.java</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>2.1</version>
<configuration>
<configLocation>checkstyle.xml</configLocation>
<enableRulesSummary>false</enableRulesSummary>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
......
......@@ -2,6 +2,9 @@ package fr.cs.orekit.bodies;
import org.apache.commons.math.geometry.Vector3D;
import fr.cs.orekit.errors.OrekitException;
import fr.cs.orekit.frames.Frame;
import fr.cs.orekit.time.AbsoluteDate;
import fr.cs.orekit.utils.Line;
/** Interface representing the rigid surface shape of a natural body.
......@@ -11,18 +14,27 @@ import fr.cs.orekit.utils.Line;
*/
public interface BodyShape {
/** Get body frame related to body shape.
* @return body frame related to body shape
*/
public Frame getBodyFrame();
/** Get the intersection point of a line with the surface of the body.
* @param line test line in inertial frame (may intersect the body or not)
* @param frame frame in which line is expressed
* @return intersection point at altitude zero or null if the line does
* not intersect the surface
*/
public GeodeticPoint getIntersectionPoint(Line line);
public GeodeticPoint getIntersectionPoint(Line line, Frame frame, AbsoluteDate date)
throws OrekitException ;
/** Transform a cartesian point to a surface-relative point.
* @param point cartesian point
* @param frame frame in which cartesian point is expressed
* @return point at the same location but as a surface-relative point
*/
public GeodeticPoint transform(Vector3D point);
public GeodeticPoint transform(Vector3D point, Frame frame, AbsoluteDate date)
throws OrekitException ;
/** Transform a surface-relative point to a cartesian point.
* @param point surface-relative point
......
package fr.cs.orekit.bodies;
import org.apache.commons.math.geometry.Vector3D;
import fr.cs.orekit.errors.OrekitException;
import fr.cs.orekit.frames.Frame;
import fr.cs.orekit.frames.Transform;
import fr.cs.orekit.time.AbsoluteDate;
import fr.cs.orekit.utils.Line;
/** Modeling of one-axis ellipsoid.
......@@ -23,6 +28,9 @@ public class OneAxisEllipsoid implements BodyShape {
/** One third. */
private static final double ot = 1.0 / 3.0;
/** Body frame related to body shape. */
private final Frame bodyFrame;
/** Equatorial radius. */
private final double ae;
......@@ -45,16 +53,17 @@ public class OneAxisEllipsoid implements BodyShape {
private double angularThreshold;
/** Simple constructor.
* <p> Freqently used parameters for earth are :
* <p> Frequently used parameters for earth are :
* <pre>
* ae = 6378136.460 m
* f = 1 / 298.257222101
* </pre>
* </p>
* @param ae earth equatorial radius
* @param f the flatening ( f = (a-b)/a )
* @param f the flattening ( f = (a-b)/a )
* @param bodyFrame body frame related to body shape
*/
public OneAxisEllipsoid(double ae, double f) {
public OneAxisEllipsoid(double ae, double f, Frame bodyFrame) {
this.ae = ae;
e2 = f * (2.0 - f);
g = 1.0 - f;
......@@ -62,6 +71,7 @@ public class OneAxisEllipsoid implements BodyShape {
ae2 = ae * ae;
setCloseApproachThreshold(1.0e-10);
setAngularThreshold(1.0e-14);
this.bodyFrame = bodyFrame;
}
/** Set the close approach threshold.
......@@ -106,14 +116,29 @@ public class OneAxisEllipsoid implements BodyShape {
return ae;
}
/** Get the body frame related to body shape
* @return body frame related to body shape
*/
public Frame getBodyFrame() {
return bodyFrame;
}
/** Get the intersection point of a line with the surface of the body.
* @param line test line in inertial frame (may intersect the body or not)
* @param frame frame in which line is expressed
* @param date date of the line in given frame
* @return intersection point at altitude zero or null if the line does
* not intersect the surface
*/
public GeodeticPoint getIntersectionPoint(Line line) {
public GeodeticPoint getIntersectionPoint(Line line, Frame frame, AbsoluteDate date)
throws OrekitException {
// transform line to body frame
Transform t = frame.getTransformTo(bodyFrame, date);
Line lineInBodyFrame = t.transformLine(line);
// compute some miscellaneous variables outside of the loop
final Vector3D point = line.getOrigin();
final Vector3D point = lineInBodyFrame.getOrigin();
final double z = point.getZ();
final double z2 = z * z;
final double r2 = point.getX() * point.getX() + point.getY() * point.getY();
......@@ -121,7 +146,7 @@ public class OneAxisEllipsoid implements BodyShape {
final double g2r2ma2 = g2 * (r2 - ae2);
final double g2r2ma2pz2 = g2r2ma2 + z2;
final Vector3D direction = line.getDirection();
final Vector3D direction = lineInBodyFrame.getDirection();
final double cz =
Math.sqrt(direction.getX() * direction.getX() + direction.getY() * direction.getY());
final double sz =
......@@ -164,14 +189,21 @@ public class OneAxisEllipsoid implements BodyShape {
/** Transform a cartesian point to a surface-relative point.
* @param point cartesian point
* @return point at the same location but as a surface-relative point
* @param frame frame in which cartesian point is expressed
* @param date date of the point in given frame
* @return point at the same location but as a surface-relative point, expressed in body frame
*/
public GeodeticPoint transform(Vector3D point) {
public GeodeticPoint transform(Vector3D point, Frame frame, AbsoluteDate date)
throws OrekitException {
// transform line to body frame
Transform transf = frame.getTransformTo(bodyFrame, date);
Vector3D pointInBodyFrame = transf.transformPosition(point);
// compute some miscellaneous variables outside of the loop
final double z = point.getZ();
final double z = pointInBodyFrame.getZ();
final double z2 = z * z;
final double r2 = point.getX() * point.getX() + point.getY() * point.getY();
final double r2 = pointInBodyFrame.getX() * pointInBodyFrame.getX() + pointInBodyFrame.getY() * pointInBodyFrame.getY();
final double r = Math.sqrt(r2);
final double g2r2ma2 = g2 * (r2 - ae2);
final double g2r2ma2pz2 = g2r2ma2 + z2;
......@@ -196,7 +228,7 @@ public class OneAxisEllipsoid implements BodyShape {
double b2 = b * b;
final double ac = a * c;
double k = c / (b + Math.sqrt(b2 - ac));
final double lambda = Math.atan2(point.getY(), point.getX());
final double lambda = Math.atan2(pointInBodyFrame.getY(), pointInBodyFrame.getX());
double phi = Math.atan2(z - k * sz, g2 * (r - k * cz));
// point on the ellipse
......
......@@ -5,6 +5,7 @@ import java.io.Serializable;
import org.apache.commons.math.geometry.Rotation;
import org.apache.commons.math.geometry.Vector3D;
import fr.cs.orekit.utils.Line;
import fr.cs.orekit.utils.PVCoordinates;
/** Transformation class in three dimensional space.
......@@ -195,6 +196,20 @@ public class Transform implements Serializable {
return rotation.applyTo(vector);
}
/** Transform a line.
* @param line to transform
* @return transformed line
*/
public Line transformLine(Line line) {
Vector3D origin = line.getOrigin();
Vector3D direction = line.getDirection();
Vector3D transformedOrigin = transformPosition(origin);
Vector3D transformedDirection = transformVector(direction);
return new Line(transformedOrigin, transformedDirection);
}
/** Transform {@link PVCoordinates} including kinematic effects.
* @param pv the couple position-velocity to transform.
* @return transformed position/velocity
......
......@@ -110,7 +110,7 @@ public class Development implements Serializable {
// skip blank lines
line = reader.readLine();
++lineNumber;
while ((line != null) && line.trim().isEmpty()) {
while ((line != null) && (line.trim().length() == 0)) {
line = reader.readLine();
++lineNumber;
}
......@@ -231,7 +231,8 @@ public class Development implements Serializable {
// parse the nutation serie term
final String[] fields = line.split("\\p{Space}+");
final int l = fields.length;
if ((l == 17) || ((l == 18) && fields[0].isEmpty())) {
// if ((l == 17) || ((l == 18) && fields[0].isEmpty())) {
if ((l == 17) || ((l == 18) && (fields[0].length() == 0))) {
return SeriesTerm.buildTerm(Double.parseDouble(fields[l - 16]) * factor,
Double.parseDouble(fields[l - 15]) * factor,
Integer.parseInt(fields[l - 14]), Integer.parseInt(fields[l -13]),
......
......@@ -23,7 +23,7 @@ import java.io.Serializable;
* </p>
* <p>
* The parameters are defined in a frame specified by the user. It is important
* to make sure this frame is coherent : it probably is inertial and centered
* to make sure this frame is consistent : it probably is inertial and centered
* on the central body. This information is used for example by some
* force models.
* </p>
......
......@@ -2,7 +2,6 @@ package fr.cs.orekit.propagation;
import fr.cs.orekit.attitudes.AttitudeKinematics;
import fr.cs.orekit.attitudes.AttitudeKinematicsProvider;
import fr.cs.orekit.attitudes.models.IdentityAttitude;
import fr.cs.orekit.propagation.numerical.forces.ForceModel;
......
......@@ -298,25 +298,15 @@ public class TargetPointingTest extends TestCase {
// Compute difference between both attitude laws
// *********************************************
// "Difference" between axes
Vector3D crossProd = Vector3D.crossProduct(rotSatJ2000.getAxis(), rotSatRefJ2000.getAxis());
double norm = Math.sqrt(Vector3D.dotProduct(crossProd, crossProd));
System.out.println("Cross product = " + crossProd.getX()
+ " " + crossProd.getY()
+ " " + crossProd.getZ());
System.out.println("Norm = " + norm);
assertEquals(norm, 0.0, 1.e-2);
// Difference between axes
// Difference between attitudes
// expected
double tanDeltaExpected = (6378136.460/(42164000.0-6378136.460))*Math.tan(Math.toRadians(5));
double deltaExpected = Math.atan(tanDeltaExpected);
System.out.println("Delta expected = " + Math.toDegrees(deltaExpected));
System.out.println("Delta expected (deg) = " + Math.toDegrees(deltaExpected));
// real
double deltaReal = rotSatJ2000.applyInverseTo(rotSatRefJ2000).getAngle();
System.out.println("Delta real = " + Math.toDegrees(deltaReal));
System.out.println("Delta real (deg) = " + Math.toDegrees(deltaReal));
assertEquals(deltaReal, deltaExpected, 1.e-4);
......
......@@ -4,6 +4,9 @@ package fr.cs.orekit.bodies;
import org.apache.commons.math.geometry.Vector3D;
import org.apache.commons.math.util.MathUtils;
import fr.cs.orekit.errors.OrekitException;
import fr.cs.orekit.frames.Frame;
import fr.cs.orekit.time.AbsoluteDate;
import fr.cs.orekit.utils.Line;
import junit.framework.Test;
import junit.framework.TestCase;
......@@ -15,63 +18,66 @@ public class OneAxisEllipsoidTest extends TestCase {
super(name);
}
public void testOrigin() {
public void testOrigin() throws OrekitException {
double ae = 6378137.0;
checkCartesianToEllipsoidic(ae, 1.0 / 298.257222101,
ae, 0, 0,
0, 0, 0);
}
public void testStandard() {
public void testStandard() throws OrekitException {
checkCartesianToEllipsoidic(6378137.0, 1.0 / 298.257222101,
4637885.347, 121344.608, 4362452.869,
0.026157811533131, 0.757987116290729, 260.455572965555);
}
public void testLongitudeZero() {
public void testLongitudeZero() throws OrekitException {
checkCartesianToEllipsoidic(6378137.0, 1.0 / 298.257222101,
6378400.0, 0, 6379000.0,
0.0, 0.787815771252351, 2653416.77864152);
}
public void testLongitudePi() {
public void testLongitudePi() throws OrekitException {
checkCartesianToEllipsoidic(6378137.0, 1.0 / 298.257222101,
-6379999.0, 0, 6379000.0,
3.14159265358979, 0.787690146758403, 2654544.7767725);
}
public void testNorthPole() {
public void testNorthPole() throws OrekitException {
checkCartesianToEllipsoidic(6378137.0, 1.0 / 298.257222101,
0.0, 0.0, 7000000.0,
0.0, 1.57079632679490, 643247.685859644);
}
public void testEquator() {
public void testEquator() throws OrekitException {
checkCartesianToEllipsoidic(6378137.0, 1.0 / 298.257222101,
6379888.0, 6377000.0, 0.0,
0.785171775899913, 0.0, 2642345.24279301);
}
public void testInside3Roots() {
public void testInside3Roots() throws OrekitException {
checkCartesianToEllipsoidic(6378137.0, 1.0 / 298.257,
9219.0, -5322.0, 6056743.0,
5.75963470503781, 1.56905114598949, -300000.009586231);
}
public void testInsideLessThan3Roots() {
public void testInsideLessThan3Roots() throws OrekitException {
checkCartesianToEllipsoidic(6378137.0, 1.0 / 298.257,
1366863.0, -789159.0, -5848.988,
-0.523598928689, -0.00380885831963, -4799808.27951);
}
public void testOutside() {
public void testOutside() throws OrekitException {
checkCartesianToEllipsoidic(6378137.0, 1.0 / 298.257,
5722966.0, -3304156.0, -24621187.0,
5.75958652642615, -1.3089969725151, 19134410.3342696);
}
public void testGeoCar() {
OneAxisEllipsoid model = new OneAxisEllipsoid(6378137.0, 1.0 / 298.257222101);
public void testGeoCar() throws OrekitException {
OneAxisEllipsoid model =
new OneAxisEllipsoid(6378137.0, 1.0 / 298.257222101,
Frame.getReferenceFrame(Frame.ITRF2000B,
AbsoluteDate.J2000Epoch));
GeodeticPoint nsp =
new GeodeticPoint(0.0423149994747243, 0.852479154923577, 111.6);
Vector3D p = model.transform(nsp);
......@@ -80,57 +86,65 @@ public class OneAxisEllipsoidTest extends TestCase {
assertEquals(4779203.64408617, p.getZ(), 1.0e-6);
}
public void testLineIntersection() {
OneAxisEllipsoid model = new OneAxisEllipsoid(100.0, 0.9);
public void testLineIntersection() throws OrekitException {
AbsoluteDate date = AbsoluteDate.J2000Epoch;
Frame frame = Frame.getReferenceFrame(Frame.ITRF2000B, date);
OneAxisEllipsoid model =
new OneAxisEllipsoid(100.0, 0.9, frame);
Line line = new Line(new Vector3D(0.0, 93.7139699, 3.5930796),
new Vector3D(0.0, 1.0, 1.0));
GeodeticPoint gp = model.getIntersectionPoint(line);
GeodeticPoint gp = model.getIntersectionPoint(line, frame, date);
assertEquals(gp.altitude, 0.0, 1.0e-12);
assertTrue(line.contains(model.transform(gp)));
model = new OneAxisEllipsoid(100.0, 0.9);
model = new OneAxisEllipsoid(100.0, 0.9, frame);
line = new Line(new Vector3D(0.0, -93.7139699, -3.5930796),
new Vector3D(0.0, -1.0, -1.0));
gp = model.getIntersectionPoint(line);
gp = model.getIntersectionPoint(line, frame, date);
assertTrue(line.contains(model.transform(gp)));
model = new OneAxisEllipsoid(100.0, 0.9);
model = new OneAxisEllipsoid(100.0, 0.9, frame);
line = new Line(new Vector3D(0.0, -93.7139699, 3.5930796),
new Vector3D(0.0, -1.0, 1.0));
gp = model.getIntersectionPoint(line);
gp = model.getIntersectionPoint(line, frame, date);
assertTrue(line.contains(model.transform(gp)));
model = new OneAxisEllipsoid(100.0, 0.9);
model = new OneAxisEllipsoid(100.0, 0.9, frame);
line = new Line(new Vector3D(-93.7139699, 0.0, 3.5930796),
new Vector3D(-1.0, 0.0, 1.0));
gp = model.getIntersectionPoint(line);
gp = model.getIntersectionPoint(line, frame, date);
assertTrue(line.contains(model.transform(gp)));
line = new Line(new Vector3D(0.0, 0.0, 110),
new Vector3D(0.0, 0.0, 1.0));
gp = model.getIntersectionPoint(line);
gp = model.getIntersectionPoint(line, frame, date);
assertEquals(gp.latitude, Math.PI/2, 1.0e-12);
line = new Line(new Vector3D(0.0, 110, 0),
new Vector3D(0.0, 1.0, 0.0));
gp = model.getIntersectionPoint(line);
gp = model.getIntersectionPoint(line, frame, date);
assertEquals(gp.latitude,0, 1.0e-12);
}
public void testNoLineIntersection() {
OneAxisEllipsoid model = new OneAxisEllipsoid(100.0, 0.9);
public void testNoLineIntersection() throws OrekitException {
AbsoluteDate date = AbsoluteDate.J2000Epoch;
Frame frame = Frame.getReferenceFrame(Frame.ITRF2000B, date);
OneAxisEllipsoid model = new OneAxisEllipsoid(100.0, 0.9, frame);
Line line = new Line(new Vector3D(0.0, 93.7139699, 3.5930796),
new Vector3D(0.0, 9.0, -2.0));
assertNull(model.getIntersectionPoint(line));
assertNull(model.getIntersectionPoint(line, frame, date));
}
private void checkCartesianToEllipsoidic(double ae, double f,
double x, double y, double z,
double longitude, double latitude,
double altitude) {
double altitude)
throws OrekitException {
OneAxisEllipsoid model = new OneAxisEllipsoid(ae, f);
GeodeticPoint gp = model.transform(new Vector3D(x, y, z));
AbsoluteDate date = AbsoluteDate.J2000Epoch;
Frame frame = Frame.getReferenceFrame(Frame.ITRF2000B, date);
OneAxisEllipsoid model = new OneAxisEllipsoid(ae, f, frame);
GeodeticPoint gp = model.transform(new Vector3D(x, y, z), frame, date);
assertEquals(longitude, MathUtils.normalizeAngle(gp.longitude, longitude), 1.0e-10);
assertEquals(latitude, gp.latitude, 1.0e-10);
assertEquals(altitude, gp.altitude, 1.0e-10 * Math.abs(altitude));
......
......@@ -364,7 +364,7 @@ public class EquinoctialParametersTest extends TestCase {
public void testSymmetry() {
// elliptic and non equatorail orbit
// elliptic and non equatorial orbit
Vector3D position = new Vector3D(4512.9, 18260., -5127.);
Vector3D velocity = new Vector3D(134664.6, 90066.8, 72047.6);
double mu = 3.9860047e14;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment