Determining if FOV Sensor can view sun, and calculate angle from center

I am attempting to solve an issue with the placement of a star tracker. I would like to use Orekit to determine what is the angle between the sun’s incident vector onto the satellite and the FOV’s center vector of the star tracker. This is to ensure that the sun’s incident vector onto the satellite does not enter the direct FOV of the star tracker for too long, which may result in oversaturation of the lenses.

I have the star tracker currently angled at 30 degrees off the horizontal plane, so I have defined the FOV as such

cameraDirection = Vector3D(1.0, 0.0, 0.6)
camerafov = CircularFieldOfView(cameraDirection, math.radians(30), 0.0)

Following that, I propagate an initialOrbit forward in time, and try to calculate the angle between the vectors as such

sun = CelestialBodyFactory.getSun()
sun = PVCoordinatesProvider.cast_(sun) 

while (extrapDate.compareTo(finalDate) <= 0.0):  

    #pv = propagator.getPVCoordinates(extrapDate, inertialFrame)
    pv_state = propagator.propagate(extrapDate)

    pos_sun = sun.getPVCoordinates(extrapDate, inertialFrame).getPosition()

    FOV_angle = Vector3D.angle(pos_sun, camerafov.getCenter())
    fov_list.append(FOV_angle)

    date.append(absolutedate_to_datetime(extrapDate))
    print(extrapDate, end="\r")
    extrapDate = extrapDate.shiftedBy(24*3600.0)

I am currently wondering if this is the correct way to do this, as the sun vector’s angle is currently defined to the inertialFrame that is defined as Earth itself instead of the satellite. How can I correctly calculate the angle of the FieldofView? I have seen some API documentation that the spacecraft frame is currently deprecated, but the FieldofView’s center vector is defined on the spacecraft frame. Should I transform the center vector of the FOV to the inertialFrame?

I do not want to use the FieldofViewDetector, as it does not provide me the angles necessary to plot a graph over time. Thank you to anyone who is reading this.

What was deprecated was the SpacecraftFrame class that extended Frame, but the concept of a spacecraft frame still makes sense, it is just not backed by a custom Frame specialization.

You should convert the camerafov.getCenter() vector from spacecraft frame to inertial frame. You can do this by calling:

pv_state.toStaticTransform().getInverse().transformVector(camerafov.getCenter())

Also note that instead of performing a time loop by yourself, you could just register one step handler to the propagator and propagate just once from start to end. This is much more efficient that performing a lot of one step propagations.

1 Like

Hi Luc, thanks for the help.

I will look further into the registering of the step handler to the propagator, I was using the propagation example given in the GitLab repository as a starting point. Thanks for the tip.

I have a further question for the spacecraft frame, I am not entirely sure how the X, Y, Z frame is defined, and have only been able to see some information that the spacecraft is modeled as a unit sphere. I was planning on changing the camera FOV to figure it out but was wondering if you have any links or images to help me determine how is it orientated?

Thanks a lot again for your help.

The spacecraft frame is defined by the AttitudeProvider that is registered to the propagator. If you don’t set up any attitude provider, a default one is used, often simply aligned with some inertial frame. This is however generally not what you want and is mainly suited as a failsafe when attitude is irrelevant. In your case, attitude is paramount, so you probably must register an explicit attitude provider, there are many available in Orekit or you could implement a dedicated one by yourself if needed.