Hello Orekit community,
I have a question regarding how to use FieldVector3D to obtain a Transform. For giving a bit more of context I am trying to create a new eventDetector that will trigger whenever the sun is in the field of view of the satellite’s sensor.
Prior to start working with derivatives, the method worked as expected. However, I did not get the readings related to the rotation rate and acceleration. That is why I am trying to implement the derivatives to the model.
Now, I am not able to apply properly the FieldRotation method, so the resulting transform does not have the expected values of rotation. Furthermore, the rotation rate and acceleration obtained are still zero.
Is there an error in the way I am defining the respective FieldVector3D for the rotation? The goal is to have the solar arrays always pointing in the sun direction.
Here is an example of the test I am running to compare the obtained rotation:
public class FieldRotationTest{
@Test
public void testFieldRotation() {
AbsoluteDate date = new AbsoluteDate();
Frame eme2000 = FramesFactory.getEME2000();
KeplerianOrbit kep = new KeplerianOrbit(7000.e3, 1e-3, 1.60, 1, 2, 0, PositionAngle.MEAN,
eme2000, date, Constants.EGM96_EARTH_MU);
// relative sun pvCoord
// in inertial frame
Vector3D satSunDirection = computeSunDirection(kep, date, eme2000);
FieldVector3D<DerivativeStructure> pointingSat = kep.getPVCoordinates(date, eme2000).toDerivativeStructureVector(2).normalize();
DerivativeStructure zeroWithDerivatives = pointingSat.getX().getFactory().variable(0, 0.0);
FieldAbsoluteDate fDate = new FieldAbsoluteDate(date, zeroWithDerivatives);
FieldVector3D<DerivativeStructure> solarPanelNormalSatFieldVector = new FieldVector3D<>(fDate.getField(), Vector3D.PLUS_J).normalize();
Vector3D solarPanelNormalSatVector = solarPanelNormalSatFieldVector.toVector3D();
Rotation expectedRotation = buildRotation(satSunDirection, solarPanelNormalSatVector);
Transform derivativeFieldTransform = buildRotationWithFieldDerivatives(satSunDirection, fDate, solarPanelNormalSatFieldVector);
boolean equal = compareRotations(expectedRotation, derivativeFieldTransform.getRotation());
System.out.println("Both cases represent the same rotation? " + equal);
System.out.println("Rotation rate: " + ArrayUtils.toString(derivativeFieldTransform.getRotationRate()));
System.out.println("Acceleration rate: " + ArrayUtils.toString(derivativeFieldTransform.getRotationAcceleration()));
}
public Vector3D computeSunDirection(PVCoordinatesProvider pvProv, AbsoluteDate date, Frame frame) {
PVCoordinates sunPVCoord = new PVCoordinates(pvProv.getPVCoordinates(date, frame),
CelestialBodyFactory.getSun().getPVCoordinates(date, frame));
return sunPVCoord.getPosition();
}
public Rotation buildRotation(Vector3D satSunDirection, Vector3D solarPanelNormalSat) {
Rotation inertial2BodyRotation = new Rotation(satSunDirection, solarPanelNormalSat);
return inertial2BodyRotation;
}
public Transform buildRotationWithFieldDerivatives(Vector3D satSunDirection, FieldAbsoluteDate fDate, FieldVector3D<DerivativeStructure> solarPanelNormalSatFieldVector) {
FieldVector3D<DerivativeStructure> pointedBody = new FieldVector3D<>(fDate.getField(), satSunDirection).normalize();
FieldVector3D<DerivativeStructure> solarPanelSat = new FieldVector3D<>(fDate.getField(), Vector3D.PLUS_K).normalize();
FieldRotation<DerivativeStructure> celToSatRotationDS =
new FieldRotation<DerivativeStructure>(pointedBody, solarPanelSat, solarPanelNormalSatFieldVector, solarPanelSat);
Transform transform = new Transform(fDate.toAbsoluteDate(), new AngularCoordinates(celToSatRotationDS));
return transform;
}
public boolean compareRotations(Rotation r1, Rotation r2) {
// Compare the rotation angles
double angleTolerance = 1e-12; // Tolerance for comparing angles
double angleDifference = r1.getAngle() - r2.getAngle();
if (Math.abs(angleDifference) > angleTolerance) {
return false;
}
// Compare the rotation axes
Vector3D axis1 = r1.getAxis(RotationConvention.VECTOR_OPERATOR);
Vector3D axis2 = r2.getAxis(RotationConvention.VECTOR_OPERATOR);
if (!axis1.equals(axis2)) {
return false;
}
return true;
}
}
Thank you very much for the help.
Adrian