I face the problem of generating an attitude law, that points an arbitrary satellite axis always along the velocity vector with constraining a second axis in another direction (e.g. the sun direction, if not aligned with the velocity). The problem is similar as this but not the same and I just can’t get my head around the class PointingAndPhasingProvider.

Just to see if I would do it correctly my plan is to:

Implement an interface DirectionProvider with a method Vector3D getDirection(AbsoluteDate date, Frame frame, Target target); where Target could be an enum holding different targets (e.g. velocity direction, sun, earth) and a similar method Vector3D getPhasing(AbsoluteDate date, Frame frame, Target target)

Implement a class DirectionToTarget that implements DirectionProvider and has a PVCoordinatesProvider (which basically is an orbit) as a member class and calculates the directions in the getDirection and getPhasing methods.

Implement the class PointingAndPhasingProvider that implements AttitudeProvider and takes two DirectionProviders as input. This class calculates the FieldRotation<UnivariateDerivative2> from the two sets of vectors hence giving me the Rotations and rotationRates.

If this is the correct way, I would still be stuck with point 3 and how to calculate the FieldRotation and actually apply the pointing then?

Your design seems fine to me. Our celestial body pointing attitude law is indeed clunky and should be fully redesigned. Your proposal seems a good way to do this. I had another idea, based on an ooooold design for generic attitude simulation I did 30 years ago (those who remember that time may recall the Marmottes library!), but it would take quite some time to implement this.

In order to create the rotation and rotation rates, I guess the best thing to do would simply to use the 4 vectors constructor of the rotation. The two first vectors would be the vectors in inertial frame given by your interface and the two other vectors would be the satellite vectors you want to align. This constructor is designed so the first vector of the first pair is perfectly transformed into the first vector of the second pair and the second vector of the first pair is only transformed in a way it defines a phase, i.e. the plane defined by the first pair is transformed into the plane defined by the second pair.

Hi @tens
Welcome to the community!
Your solution will be highly interesting as for now, to real implementation for a second axis constraint is on Orekit, while we have it in STK.
I will be happy to comment on your Merge Request, as I did something similar locally, but your approach seems more structured
Alberto