Getting Access to Event Handler Data

LookAngleGenerator.java (14.5 KB)

I am trying to get the rise/set times out of the EventHandler using the EventLogger but am obviously am not doing something in the correct way. I want to grab these times in order to generate the look angles for use in an OD routine. Any assistance will be appreciated.

Hi Stephen,

Here are some remarks I can make on your code:

In the section

        // Add event to be detected
        numProp.addEventDetector(sta1Vis);
        numProp.addEventDetector(sta2Vis);
        numProp.addEventDetector(sta3Vis);
        numProp.addEventDetector(sta4Vis);

        numProp.addEventDetector(logger.monitorDetector(sta1Vis));
        numProp.addEventDetector(logger.monitorDetector(sta2Vis));
        numProp.addEventDetector(logger.monitorDetector(sta3Vis));
        numProp.addEventDetector(logger.monitorDetector(sta4Vis));

The first four lines should be removed as the detectors should be added only wrapped in the logger, not directly. When the detectors are added both directly and wrapped, they are triggered twice.

In the section

        List<EventsLogger.LoggedEvent> allEvents = logger.getLoggedEvents();    
        SpacecraftState finalState = numProp.propagate(new AbsoluteDate(initialDate, 12000.0));

The two statements should be interchanged so the events are collected from the logger after the propagation has been performed. With lines in their current order, the events list is empty because nothing has been computed yet.

In the section

        for (extrapDateP = initialDate; extrapDateP.compareTo(finalDateP) <= 0; extrapDateP = extrapDateP.shiftedBy(stepT)) {
                SpacecraftState extrapState = numProp.propagate(extrapDateP);
                ...
        }

It would be better to use a first a single propagation from initialDate to finalDateP using ephemeris generation mode, and then a second propagation using the generated ephemeris in master mode with an OrekitFixedStepHandler with a step size set to stepT. The current loop that uses several one minute propagations in the numerical propagator reset the generated ephemeris each time a propagation is run. This implies that at the end of the loop, the generated ephemeris only covers the last one minute time span corresponding to the last iteration of the loop.

Luc,
Thank you very much for your helpful comments. Making the changes you suggested I get the following when I run the code:
System.out.println(" allEvents " + allEvents.size() );
System.out.println(" allEvents " + allEvents.get(0) );

allEvents 15
allEvents org.orekit.propagation.events.EventsLogger$LoggedEvent@6a2bcfcb

How do I convert the last line into rise/set times to use for computing my azimuth, elevation and range values?
(I appreciate your patience as I am an astrodynamicist who is working to learn Java.)
When I try:
String str1 = allEvents.get(0).toString();
System.out.println(" str1 " + str1);
I get the same representation:
str1 org.orekit.propagation.events.EventsLogger$LoggedEvent@6a2bcfcb

Thanks for the comments on the propagation. I now understand why the visibility were triggering again during my propagation loop.

The allEvents.get(0) will return a EventsLogger.LoggedEvent object which is a small container holding three properties:

  • the detector that was triggered
  • the Spacecraft state at the event occurrence
  • the increasing boolean describing the event slope direction

If I understand your needs, you want to compute the azimuth/elevation at event occurrence (which can be used to check elevation is zero since there is no refraction model used here). Here is how you get them:

  for (EventsLogger.LoggedEvent logged : allEvents) {
    ElevationDetector detector = (ElevationDetector) logged.getEventDetector();
    TopocentricFrame station = detector.getTopocentricFrame();
    SpacecraftState state = logged.getState();
    double azimuth = station.getAzimuth(state.getPVCoordinates().getPosition(),
                                        state.getFrame(),
                                        state.getDate());
    double elevation = station.getElevation(state.getPVCoordinates().getPosition(),
                                        state.getFrame(),
                                        state.getDate());
    System.out.println(station.getName() + " " +
                       (logged.isIncreasing() ? "raising" : "setting") + " " +
                       state.getDate() + " " +
                       FastMath.toDegrees(azimuth) + " " +
                       FastMath.toDegrees(elevation));
  }

Note that if you want to improve accuracy, you can set up a refraction model in the elevation detector and in the print loop above fix the geometric elevation by adding the following line just before the print:

   elevation += refractionModel.getRefraction(trueElevation);

Thanks again for you help. That is exactly what I am looking for.

Hi!
I am working on the Detector and find this post.It’s helpful,but I got some problems.
I use BooleanDetector to record events that comply with multiple conditions.
BooleanDetector detector = BooleanDetector.andCombine(ed, BooleanDetector.notCombine(fd)).withMaxCheck(10).withThreshold(1.0e-3).withHandler(handler);
The method does not work due to detector type problem.Any suggestions?

The reason the detector cannot be cast to an ElevationDetector is that it is a BooleanDetector that contains both your initial ElevationDetector and a NegateDetector, which itself contains another detector.

The boolean detector has a getDetectors method that allows you to dig deeper in the tree. ou can use that to retrieve the initial elevation detector.

Thanks,I now know why it doesn’t work.
I’ll see what I can do,thanks again!

I have one more question.Could you help me out? I’m using EventsLogger to collect access data,the code are as follows:

	 List<EventsLogger.LoggedEvent> allEvents = logger.getLoggedEvents();    

		 for (EventsLogger.LoggedEvent logged : allEvents) {
			 BooleanDetector detector_temp = (BooleanDetector) logged.getEventDetector();
//			    TopocentricFrame station = detector_temp.getTopocentricFrame();
			    SpacecraftState state = logged.getState();
//			    double azimuth = station.getAzimuth(state.getPVCoordinates().getPosition(),
//			                                        state.getFrame(),
//			                                        state.getDate());
//			    double elevation = station.getElevation(state.getPVCoordinates().getPosition(),
//			                                        state.getFrame(),
//			                                        state.getDate());
//			    System.out.println(station.getName() + " " +
//			                       (logged.isIncreasing() ? "raising" : "setting") + " " +
//			                       state.getDate() + " " +
//			                       FastMath.toDegrees(azimuth) + " " +
//			                       FastMath.toDegrees(elevation));
			    System.out.println( "station ID:"+String.valueOf(staID)+" satID :"+String.valueOf(sat.getSatID()) + " "+
	                       (logged.isIncreasing() ? "entering" : "leaving") + " " +
	                       state.getDate() + " " );
			  }

The access time results are not complete when the satellite was accessible at the very beginning of the computation period.The begin time of the first time-window is missing.I’m not sure if I have to deal with it myself or there is another way.
image

If you start the propagation after the first event, there is no way to know when it happened. You may try to add another propagation in reverse for example.

Yes,that’s exactly what happened.The propagation time lasts from 2021/01/01 20:00:00[UTC] to 2021/01/03 20:00:00[UTC]. According to the result,the satellite was already accessible at 2021/01/01 20:00:00[UTC].So it’s a little akward when you are using EventLogger to get formatted access time-window results in the scenario time like STK.

AbsoluteDate startDate=new AbsoluteDate(2021, 01, 01, 20, 00, 00.000, TimeScalesFactory.getUTC());|

AbsoluteDate endDate = new AbsoluteDate(2021, 01, 03, 20, 00, 00.000, TimeScalesFactory.getUTC());|

The same situation would happen at the end of the propagation time.

Another possibility is to update your propagation start time before launching the propagation.
You could for example use a simple loop and evaluate the sign of the event detector g function at t0 - kΔt for k = 0, 1, 2… until you find a k that ensures the satellite is not visible. Then you would use propagate(t0 - kΔt, t1), i.e. use the propagate method with two dates instead of just propagate(t1). The two-dates version first propagate from initial time to the first date with neither step handlers nor events handlers, and then perform a propagation between the two provided dates with step handlers and events handlers.
You could also to the same for the final date.

1 Like

That sounds a good approach,I will try that later!It seems I have a long way to go to write a complete access function.
I’ve been checking the results and find another question about the propagator.In my access computaion,I have encapsulate the propagator into a satellite class.Then I conduct two successive access computations for the same satellite.The second access results seems strange to me.Have you ever seen this?
first access computaion for station202 to sat101

second access computaion for station201 to sat101.This time the propagator seems to propagate twice,once backward and once forward.

Propagators that are based on integration (i.e. NumericlPropagator and DSSTPropagator) have a specific feature that differ from other propagators : they may reset the initial state to final state at the end of propagation. This allows for example to propagate from t0 to t1, then from t1 to t2, then from t2 to t3.
This feature is activated by default. If your first propagation ended at t1 and you restart a propagation from t0 to t1, it must “rewind” first.
What looks strange to me is that if you used propagate(t0, t1), the event should have been disabled during the rewind part, so it may be a bug. You can anyway disable this feature by calling propagator.setResetAtEnd(false) before performing the first propagation.

1 Like

I solved the problem by using propagate(t0, t0.shiftedBy(0)) before each propagation.I tried your method,it’s also useful and more elegent.Thanks a lot!