@petrus.hyvonen @luc would you have some test file in Python showing creation of a class using PythonAttitudeProviderModifier ?
In a nutshell I want to perform yaw-steering using CelestialBodyPointed as an underlying provider (so as I can point Z axis towards another SC, while managing remaining degree of freedom to maximize sun illumination), but the current implementation does not allow it, because type of underlying provider for YawSteering is restricted to GroundPointing, while CelestialBodyPointed is not of that type (its type is AttitudeProvider)
I thus created a python class YawSteering2 overloading required functions using PythonAttitudeProviderModifier, but I get a run time error (invalid args on getAttitude), and I don’t know why.
Here is the code of the class:
class YawSteering2(PythonAttitudeProviderModifier):
PLUS_Z = PVCoordinates(Vector3D.PLUS_K, Vector3D.ZERO, Vector3D.ZERO);
def __init__(self, inertialFrame, groundPointingLaw, sun, phasingAxis):
self.sun = sun
self.groundPointingLaw = groundPointingLaw
self.inertialFrame = inertialFrame
self.phasingNormal = PVCoordinates(Vector3D.crossProduct(Vector3D.PLUS_K, phasingAxis).normalize(),
Vector3D.ZERO,
Vector3D.ZERO);
super(YawSteering2, self).__init__()
def getUnderlyingAttitudeProvider(self)->AttitudeProvider :
return self.groundPointingLaw
def getAttitude(self, pVCoordinatesProvider, absoluteDate, frame) -> Attitude:
base = self.getBaseState(pVCoordinatesProvider, absoluteDate, frame)
sunDirection = PVCoordinates(pVCoordinatesProvider.getPVCoordinates(absoluteDate, frame),
self.sun.getPVCoordinates(absoluteDate, frame))
sunNormal = PVCoordinates.crossProduct(self.PLUS_Z, base.getOrientation().applyTo(sunDirection))
compensation = TimeStampedAngularCoordinates(absoluteDate, self.PLUS_Z, sunNormal.normalize(),
self.PLUS_Z, self.phasingNormal,
1.0e-9)
return Attitude(frame, compensation.addOffset(base.getOrientation()))
def getAttitude_FFF(self, fieldPVCoordinatesProvider, fieldAbsoluteDate, frame) -> FieldAttitude:
field = fieldAbsoluteDate.getField()
zero = FieldVector3D.getZero(field)
plusZ = FieldPVCoordinates(FieldVector3D.getPlusK(field), zero, zero)
base = self.getBaseState(fieldPVCoordinatesProvider, fieldAbsoluteDate, frame)
sunDirection = FieldPVCoordinates(fieldPVCoordinatesProvider.getPVCoordinates(fieldAbsoluteDate, frame),
FieldPVCoordinates(self.sun.getPVCoordinates(fieldAbsoluteDate, frame)))
sunNormal = plusZ.crossProduct(base.getOrientation().applyTo(sunDirection))
compensation = TimeStampedFieldAngularCoordinates(fieldAbsoluteDate, plusZ, sunNormal.normalize(),
plusZ, FieldPVCoordinates(field,self.phasingNormal),
1.0e-9)
return FieldAttitude(frame, compensation.addOffset(base.getOrientation()))
def finalize(self):
pass
and how it is used (later on it is integrated in an AttitudeSequence):
# attitude provider pointing towards targetSc
targetSc_pointing = CelestialBodyPointed(FramesFactory.getEME2000(), targetSc.prop,
Vector3D.PLUS_K,# phasing dir in EME2000
Vector3D.PLUS_K, # SC vector to be pointed
Vector3D.PLUS_I) # phasing dir in SC frame
# with yaw steering (not working currently using CelestialBodyPointed as underlying provider)
sat_r_pointed_YS = YawSteering2(FramesFactory.getEME2000(), targetSc_pointing,
CelestialBodyFactory.getSun(), Vector3D.PLUS_I)
the runtime error occurs during propagation (I’m using NumericalPropagator):
<super: <class 'JavaError'>, <JavaError object>>
Java stacktrace:
java.lang.RuntimeException: AttributeError
at org.orekit.attitudes.PythonAttitudeProviderModifier.getAttitude(Native Method)
at org.orekit.attitudes.AttitudesSequence.getAttitude(AttitudesSequence.java:292)
at
I checked it was properly working with the ‘normal’ YawSteering and using a GroundPointing-type underlying provider (such as BodyCenterPointing).