Solar system visibility check

Is it possible solar system visibility check with ground station ?
I’d like to get visible time with range.
Please let me know how to get it.

Thanks.

Hi @gardin68

Welcome to the Orekit forum! :slight_smile:

I’m not sure I understand your question. What do you mean by “solar system”?

Do you want to access time range of local night or day?

Best regards,
Bryan

Thanks your reply.
Solar system means ce·les·tial propagator.
I want to know jupiter, mars, earth, … orbits.

Thanks

That’s an interesting problem. I never tried to do it.

The ElevationDetector class is design for satellite visibilities with respect to a ground station. In other words, it is not adapted to your problem. The GroundAtNightDetector could be an interesting work around to try. Its implementation is very close to ElevationDetector. It computes the elevation of the Sun with respect to a ground station to highlight if the station is at day or night. The Sun object used to initialize the detector is represented by a PVCoordinatesProvider. However, all the celestial bodies in Orekit are PVCoordinatesProvider instances. This is the work around.

The g function of the GroundAtNightDetector is positive when ground is at night (i.e.,end of the visibility window) and negative when ground is at day (i.e., start of the visibility window).

Please find below an example :

public class CelestialBodiesVisibility {

    public static void main(String[] args)  {

        // configure Orekit
        final File home       = new File(System.getProperty("user.home"));
        final File orekitData = new File(home, "orekit-data");
        final DataProvidersManager manager = DataContext.getDefault().getDataProvidersManager();
        manager.addProvider(new DirectoryCrawler(orekitData));

        // Earth
        final OneAxisEllipsoid earth = new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
                                                            Constants.WGS84_EARTH_FLATTENING,
                                                            FramesFactory.getITRF(IERSConventions.IERS_2010, true));

        // Initial date
        final AbsoluteDate t0 = new AbsoluteDate(2004, 01, 01, 23, 30, 00.000,
                                                 TimeScalesFactory.getUTC());

        // Location
        final double latitude = 43.6;
        final double longitude = 1.4;
        final double altitude = 0.0;
        final GeodeticPoint location = new GeodeticPoint(FastMath.toRadians(latitude), FastMath.toRadians(longitude), altitude);
        final TopocentricFrame topo  = new TopocentricFrame(earth, location, "topo");

        // Gravitation coefficient
        final double mu =  3.986004415e+14;

        // Inertial frame
        final Frame inertialFrame = FramesFactory.getEME2000();

        // Initial orbit (not really used in that case but mandatory)
        final double a = 24396159; // semi major axis in meters
        final double e = 0.72831215; // eccentricity
        final double i = FastMath.toRadians(7); // inclination
        final double omega = FastMath.toRadians(180); // perigee argument
        final double raan = FastMath.toRadians(261); // right ascention of ascending node
        final double lM = 0; // mean anomaly
        final Orbit initialOrbit = new KeplerianOrbit(a, e, i, omega, raan, lM, PositionAngle.MEAN,
                                                      inertialFrame, t0, mu);

        // Orbit propagator
        final KeplerianPropagator propagator = new KeplerianPropagator(initialOrbit);

        // Celestial body
        final PVCoordinatesProvider sun = CelestialBodyFactory.getSun();
        //final PVCoordinatesProvider mars = CelestialBodyFactory.getMars();
        //final PVCoordinatesProvider jupiter = CelestialBodyFactory.getJupiter();

        // Initialize detector
        final GroundAtNightDetector detector = new GroundAtNightDetector(topo, sun, FastMath.toRadians(3.0),
                                                                         new EarthITU453AtmosphereRefraction(altitude));
        propagator.addEventDetector(detector.withHandler(new MyHandler()));

        // Propagation
        propagator.propagate(t0.shiftedBy(Constants.JULIAN_YEAR));

    }

    /** Handler to print start and end of celestial body visibility. */
    private static class MyHandler implements EventHandler<GroundAtNightDetector> {

        private double duration;
        private AbsoluteDate start;
        private AbsoluteDate end;

        /** {@inheritDoc} */
        @Override
        public Action eventOccurred(final SpacecraftState s,
                                    final GroundAtNightDetector detector,
                                    final boolean increasing) {

            // Check sign of g function
            if (increasing) {

                // End
                end = s.getDate();

                // Duration
                duration = end.durationFrom(start);

                // Night -> End of visibility
                System.out.println("End of visibility: " + end.toString());
                System.out.println("Visibility duration (s): " + duration);

            } else {

                // Start
                start = s.getDate();

                // Day -> Start of visibility
                System.out.println("================================================");
                System.out.println("Start of visibility: " + start.toString());

            }

            return Action.CONTINUE;
        }
 

    }
}

A more rigorous solution would be to implement your own detector by extending AbstractDetector class. This detector could be a mix between ElevationDetector and GroundAtNightDetector.

Best regards,
Bryan

Another option could be to create a Propagator that delegates to a PVCP. That would let you use the existing detectors and step handler treating the celestial body as the satellite. E.g.

class PvcpPropagator extends AbstractAnalyticalPropagator {
  PVCoordinatesProvider pvcp;
  Frame frame;

  protected Orbit propagateOrbit(AbsoluteDate date) {
    return new CartesianOrbit(pvcp.getPVCoordinates(date, frame), frame, date);
  }
}
1 Like