# Region of Interest Observation in LEO Using Custom Sensor

Dear all,

I would like to use the Orekit Python Wrapper for an observation study of the aurora borealis from a LEO with a sensor of lets say 40° x 40° rectangular field of view. I started this study in pure Python but due to the lack of a proper geometry library I would like to change my working horse.

Since I have never worked with Orekit yet, I only have a rough road map of how to carry it out and therefore wanted to ask for a first general guidance to identify the important tools to use.

So far I could identify the following ingredients to my study:

1. Defining a region of interest (wherein the aurora would occur) by e.g. using a spherical circle of some radius with center at the magnetic North Pole projected onto the Earth’s surface (assuming its a sphere).

2. Defining the geometry of the sensor’s field of view: as it has a rectangular field of view I imagine it to look like a pyramid from space towards Earth.

3. Simulation of a LEO polar orbit using a certain set of keplerian elements.

4. For each time step of propagation check if the field of view intersects with the region of interest and calculate the intersection e.g. as a fraction of the region of interest itself.

5. Being able to access the results to visualise in Python.

I would probably start with Nadir pointing but ultimately change to a rotation across the ground track to increase the accessible region of interest.

Could you tell me if these plans are in the scope of Orekit and if so would you kindly point me into the right directions for starting point?

Thanks a lot!

Hi!

Welcome to the Orekit forum!
We are very sorry for this late answer.

Unfortunately, I’m not a Python expert… but I can try to give you some help.

Knowing the geodetic points defining the region, you can easily build an object that can be used to detect entry/exit of the region during an orbit propagation.

The first step is to build the list of `GeodeticPoint` that define the region. The more points you have, the more your region can be closed to a spherical region. Please note that initializing a `GeodeticPoint` object is very easy. It just requires the latitude, the longitude, and the altitude of the point on Earth. With Orekit, we usually forget that the latitude and longitude must be defined in radians.

Once the list of `GeodeticPoint` built (lets call it `pointList`), you can construct the zone using `EllipsoidTessellator.buildSimpleZone(tolerance, pointList)`. The value of `tolerance` is typically equal to 1.0e-10. The `buildSimpleZone` method will return a `SphericalPolygonsSet` that can be used in Orekit to initialize the `FootprintOverlapDetector` used to detect entry/exit of the zone. This class is an event detector that can be added to a propagator to detect entry/exit during an orbit propagation.

All the available geometries to define sensor’s field of view in Orekit are available in the `org.orekit.geometry.fov` package. As you want a rectangular field of view, I recommend you to use the `DoubleDihedraFieldOfView`. You can find some example on how initializing it in the test class of this class.

Let `fov` be the `DoubleDihedraFieldOfView` and `zone` be the `SphericalPolygonsSet` built from the list of `GeodeticPoint` and the `buildSimpleZone` method as presented previously. The `FootprintOverlapDetector` can be initialized like that:

``````ecef = FramesFactory.getITRF(IERSConventions.IERS_2010, true)
targetZoneDetector = FootprintOverlapDetector(fov,  earth, zone, 10000.0)
``````

Just note that using this detector, the propagation will stop when the region leaves the field of view. This behavior is due to the default handler of the detector which is `StopOnIncreasing`. You can easily override this configuration by calling the `.withHandler()` method of the event detector. Overrinding the default handler can be very useflul for your need. You can create you own handler (i.e., class) by implementing the `PythonEventHandler` interface of the Orekit Python Wrapper. It can help you to identify when the region enters or leaves the field of view. For instance by printing the epochs of saving some data to do plots at the end of the propagation.

``````targetZoneDetector = targetZoneDetector.withHandler(myWonderfulHandler)
``````

To define the initial orbit in Keplerian elements (lets call it `initialOrbit`), you have to use the KeplerianOrbit class. After defining the initial orbit, you can propagate it using an analytical (e.g., Eckstein-Hechler) or a numerical (i.e., NumericalPropagator) orbit propagator.

For instance, you can initialize the Eckstein-Hechler model like that:

``````provider   = GravityFieldFactory.getUnnormalizedProvider(6, 6)
propagator =  EcksteinHechlerPropagator(initialOrbit, Propagator.DEFAULT_MASS, provider)
``````

And, you can initialize a Numerical propagator like that:

``````integrationStep = 60
integrator      = ClassicalRungeKuttaIntegrator(integrationStep)
propagator      = NumericalPropagator(integrator)
initialState    = SpacecraftState(initialOrbit)
propagator.setInitialState(initialState)
gravityField = HolmesFeatherstoneAttractionModel(ecef, GravityFieldFactory.getNormalizedProvider(6, 6))
# Add the event detector for region entry/exit
``````

For the example with the numerical orbit propagator, I defined a nadir pointing law for the attitude mode. It is a classical attitude mode for Earth observation satellites. The attitude provider can also be added to the analytical orbit propagator using the same method.
Moreover, you can find also the force models that can be added to a numerical orbit propagator in the `org.orekit.forces` package.

After initializing the orbit propagator, the orbit propagation is performed by calling the `propagate(target)` method. Where `target` is the target epoch of the propagation.

When implementing you own handler for the `FootprintOverlapDetector`. The compiler will ask you to implement the `eventOccurred(state, detector, increasing)` method. This method is called each time the event is detected. For the `FootprintOverlapDetector` the `increasing` flag is equal to `false` when the region enters the Field Of View and `true` when the region leaves the Field Of View. The `state` parameter is the spacecraft state at the event detection epoch and the `detector` is the event detector related to the handler (i.e., `FootprintOverlapDetector` in this case). At detection epoch you can have the footprint of the field of view on ground by calling the `getFootprint` method of the `fov`. You can access the fov thanks to the `detector` parameter of the `eventOccurred` method. Indeed, `FootprintOverlapDetector` has a method `getFOV()`.

That is the limit of my Python skills

Finally, the following posts can also help you: Post1, Post 2, and Post 3
Please note that all the examples above were writtent directly in the forum, i.e., without any IDE or compiler. So they may contain typo.

Best regards,
Bryan

2 Likes

Dear Bryan,

thanks a lot for this very detailed response!
I will work through it and might come back for follow up discussion if my lack of knowledge on orekit strikes again

Cheers!