GeodeticPoint - getIntersectionPoint returning null value

Hi Community,

I’m trying to find the Visibility of a Star - Canopus using Eclipse Detector.

At certain point while running the code I’m getting NullPointerException. below I share you the piece of code to try and let me know why the error is generated. from the OneAxisEllipsoid class it says that it will return null if → intersection point at altitude zero or null if the line does not intersect the surface. But the Intersection point is computed when the event is detected with eclipse detector.( here it just doesnot makes sense to me). maybe if I’m wrong. Also if you have any other solution to compute the Intersection point and visibility would be much appreciable.

I have cut short the code to focus on only one part. I hope this helps. please let me know if you need more details.

Waiting for your response.


{ // main function
Frame eme = FramesFactory.getEME2000();

OneAxisEllipsoid tangentPLow = new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
                    Constants.WGS84_EARTH_FLATTENING,
                    FramesFactory.getITRF(IERSConventions.IERS_2010, true));

TLE tle = new TLE("1 39159U 13021A   21117.10971189 -.00000003  00000-0  16958-4 0  9999",
                    "2 39159  98.4135 167.6604 0003439 213.4832 146.6130 14.22999585414117",TimeScalesFactory.getUTC());

TLEPropagator probav = TLEPropagator.selectExtrapolator(tle);
// Dates for visibility check
AbsoluteDate startDate = new AbsoluteDate(2021, 4, 27, 0, 0, 00.000, TimeScalesFactory.getUTC());
AbsoluteDate endDate = new AbsoluteDate(2021, 4, 28, 0, 0, 00.000, TimeScalesFactory.getUTC());

Stars fStars = new Stars();
PVCoordinatesProvider Capella = fStars.Star("Capella");

// Eclipse detector

EclipseDetector capellalow = new EclipseDetector(Capella, 0, tangentPLow)
                    .withHandler((SpacecraftState s, EclipseDetector detector, boolean increasing) -> {
                        if (increasing) {
                            Vector3D PlanAppPos = Capella.getPVCoordinates(s.getDate(), eme).getPosition();
                            Vector3D sd = s.getPVCoordinates(eme).getPosition();
                            GeodeticPoint gp = tangentPLow.transform(sd, eme, s.getDate());
                            double slt = FastMath.toDegrees(gp.getLatitude());
                            double sln = FastMath.toDegrees(gp.getLongitude());
                            Line los = new Line(sd,PlanAppPos, 1e-10);
                            GeodeticPoint gp1 = tangentPLow.getIntersectionPoint(los, sd, eme, s.getDate());
                            double tlt = FastMath.toDegrees(gp1.getLatitude()); // The Error Occurs here as the gp1 is null
                            double tln = FastMath.toDegrees(gp1.getLongitude());
                            double alt = tanPoints[0];
                            System.out.format(Locale.US,
                                    "Visibility of Capella Begins at       :%s, SLat: %3.3f, SLon: %3.3f, TPLat: %3.3f, TPLon: %3.3f, TAlt: %3.2f %n",
                                            s.getDate(),slt,sln,tlt,tln,alt);
                        }
                        return Action.CONTINUE;
                    });

System.out.print("\n");
probav.addEventDetector(capellalow);
probav.propagate(startDate, endDate);

}

static class Stars{
        public PVCoordinatesProvider Star(String star){

            // Star Cartesian coordinates taken from https://www.astronexus.com/hyg HYG 3.0 Database.
            PVCoordinatesProvider st;
            PVCoordinates pv;
            Frame frame = FramesFactory.getEME2000();
            if(star == "Capella" | star =="capella"){
                pv = new PVCoordinates(new Vector3D(1.712633*Constants.IAU_2012_ASTRONOMICAL_UNIT, 8.954439*Constants.IAU_2012_ASTRONOMICAL_UNIT,
                9.440007*Constants.IAU_2012_ASTRONOMICAL_UNIT),new Vector3D(1.92E-06, 3.559E-05, -2.54E-06));
                AbsoluteDate date = AbsoluteDate.J2000_EPOCH;
                st = new CartesianOrbit(pv, frame, date, Constants.WGS84_EARTH_MU);
            }else{
                st = null;
                System.out.println("Please Enter Stars from the catalogue- Polaris, Capella, Canopus, Procyon, Altair. If"
                +" you need to add a new star in the statements above use the Hyg DataBase for Star Position Data");
            }

            return st;
        }
    }

Here is the error produced:

Exception in thread "main" java.lang.NullPointerException
        at org.orekit.tutorials.propagation.PlanetAngPos.lambda$16(PlanetAngPos.java:499)

To add some investigations on this issue.

  1. Looks like ellipsoid is the problem here. when I set the flattening to Zero the code just works fine. and this doesn’t solve the problem here.

  2. (I tried to change the Ellipsoid with the IERS conventions model as below to be consistent with defined parameters). And issue seems to be solved for that Star.

neAxisEllipsoid tangentPLow = new OneAxisEllipsoid(Constants.IERS2010_EARTH_EQUATORIAL_RADIUS,
                    Constants.IERS2010_EARTH_FLATTENING,
                    FramesFactory.getITRF(IERSConventions.IERS_2010, false)); 
  1. but when I try this for a different star or celestial bodies (Let’s say Mars/ Jupiter the issue remains the same). I think that the eclipse detector is detecting the Star/ Planet but the Line
Line los = new Line(sd,PlanAppPos, 1e-10);

that is created between the spacecraft current state and the celestial body position either doesn’t intercept the tip of the surface or goes through the surface of the ellipsoid triggering a null value.

Does the eclipse detector suppose to work in this way or am I understanding incorrectly?

Hi @asuthoshcr , sorry for the late answer

I ran your example code. It seems to me that the culprit comes from numerical noise when subtracting two positions that are really far from each other.
You already put Capella much closer to Earth than it really is (about 2 billion kilometers instead of 42.9 light years) but it is still too large to get an accurate result when we subtract the position of a satellite that is at about 820km altitude.

Here, I think we should have a dedicated detector that really considers a direction at infinity and not a point target. It is probably not really difficult to set up starting from EclipseDetector, but clearly EclipseDetector cannot deal with this use case.

Could you open a feature request on the forge for a StartVisibilityDetector?

Thanks @luc , I have raised a Feature Request in the forge * #1035 .

Hi @luc ,

This is something I don’t understand. if we do the same operations for celestial bodies some of the bodies like Mars,Saturn, Venus throw the same error. can you further investigate the same from your side and let me know, what is causing the error during the set begins/ends phase? below I provide you with the sample code for visualization.

PVCoordinatesProvider venus = CelestialBodyFactory.getVenus();
double venusrad = 6051800; // Venus Radius in meters (6051.8km)
EclipseDetector venuslow = new EclipseDetector(venus, venusrad, tangentPLow)
                    .withHandler((SpacecraftState s, EclipseDetector detector, boolean increasing) -> {
                        Vector3D PlanAppPos = venus.getPVCoordinates(s.getDate(), eme).getPosition();
                        Vector3D sd = s.getPVCoordinates().getPosition();
                        Line los = new Line(sd,PlanAppPos, 1e-10);
                        GeodeticPoint gp1 = tangentPLow.getIntersectionPoint(los, sd, eme, s.getDate());
                        double tlt,tln;
                        if(gp1==null){tlt =0;tln =0;}else{
                        tlt = FastMath.toDegrees(gp1.getLatitude());
                        tln = FastMath.toDegrees(gp1.getLongitude());}
                        System.out.println("Venus"+","+(increasing ? "Rise Begins" : "Set Ends")+","+s.getDate()+","+tlt+","+tln);
                        return Action.CONTINUE;
                    });

EclipseDetector venushigh = new EclipseDetector(venus, venusrad, tangentPHigh)
                    .withHandler((SpacecraftState s, EclipseDetector detector, boolean increasing) -> {
                        Vector3D PlanAppPos = venus.getPVCoordinates(s.getDate(), eme).getPosition();
                        Vector3D sd = s.getPVCoordinates().getPosition();
                        Line los = new Line(sd,PlanAppPos, 1e-10);
                        GeodeticPoint gp1 = tangentPHigh.getIntersectionPoint(los, sd, eme, s.getDate());
                        double tlt,tln;
                        if(gp1==null){tlt =0;tln =0;}else{
                        tlt = FastMath.toDegrees(gp1.getLatitude());
                        tln = FastMath.toDegrees(gp1.getLongitude());}
                        System.out.println("Venus"+","+(increasing ? "Rise Ends" : "Set Begins")+","+s.getDate()+","+tlt+","+tln);
                        return Action.CONTINUE;
                    });

probav.addEventDetector(venuslow);
probav.addEventDetector(venushigh);

When you run the code you can see that the Set Begins/ Set Ends Event will produce “0” as output.
I also have added results for comparison from NASA SPICE based computation in last two columns where I expect the zeros to the value similar to the one generated in SPICE.

Sample Output:

Planet Event Date-Time TP_Lat TP_Lon Expected TP_Lat_from_SPICE Expected TP_Lon_From_SPICE
Venus Rise Begins 2021-04-27T02:40:59.26680214475475Z 19.12011 -111.16218 19.12011 -111.16218
Venus Rise Ends 2021-04-27T02:41:30.29372461745479Z 21.09386 -111.73092 21.09386 -111.73092
Venus Set Begins 2021-04-27T03:56:00.0278744172002Z 0 0 -73.969081 134.266582
Venus Set Ends 2021-04-27T03:56:26.50098703235145Z 0 0 -73.767724 139.354426
Venus Rise Begins 2021-04-27T04:22:18.09527629728225Z 19.12011 -111.16218 19.12011 -111.16218
Venus Rise Ends 2021-04-27T04:22:44.61911142141932Z 21.09386 -111.73092 21.09386 -111.73092
Venus Set Begins 2021-04-27T05:37:14.33769187805322Z 0 0 -73.945329 108.815176
Venus Set Ends 2021-04-27T05:37:40.80818845617651Z 0 0 -73.747886 113.898165

I have used the same TLE as provided in the initial comment of this thread.
any help on the error understanding would be much helpful.

I solved the issue on the above thread myself.

To add it to the community. I made a mistake while setting the logic.
i.e. I have set the Propagator with TLE and the default frame from TLE Propagator is TEME frame.
Now in the Eclipse detector while extracting the spacecraft current state PV Coordinates I didn’t consider the frame of reference and I used the same coordinates to create a line for getting the intersection point which resulted to null value for most of the cases. And now I solved it by extracting the spacecraft state in correct frame and using it for further computations to create a Line and getting the intersection point.

For Stars:
I reduced the distance of star by placing it near to earth, in that way the problem of numerical noise is eliminated to some extent (but not completely.) I fine tuned the coordinates after events detection by reducing it more to few thousand kilometers to create a Line with S/C and further find the intersection without any problem.

Still having a separate Star Visibility Detector will be a good feature to OREKIT for working with deep space missions. Waiting for the feature to be release soon.

1 Like