Simulating topocentric right ascension/declination measurements

Hi all,

I’m trying to simulate observations of a satellite from a ground station using the measurement generation package. I’d like to produce topocentric right ascension & declination values, as from a telescope. I tried using an AngularRaDecBuilder, but I don’t understand how to properly specify the frame. I (naively) started with specifying the topocentric frame of the ground station, but the values (perhaps unsurprisingly) do not match my validation case. How can I get topocentric right ascension and declination values here? Thanks in advance.

Sometimes, just the act of writing something down helps clear things up. I looked at the source for AngularRaDec, and I see that it is, in fact, computing topocentric values. Changing the reference frame to the inertial frame I am interested (EME2000, in this case) in gives me the results I was expecting.

Hi, I am pretty new with Orekit and Java. But I would like to do the same thing as you did: adding RA/Dec measurements to my code (which is pretty much a copy of orekit-tutorials-10.2\src\main\java\org\orekit\tutorials\estimation\common\AbstractOrbitDetermination.java). How do I call AngularRaDecBuilder? Do you have a sniplet of your code showing the syntax? Thanks for any advice you could share!

The constructor for AngularRaDecBuilder is documented. I can’t provide my code, but is there something specific you’re having trouble with?

Many thanks for your reply!

My main problem is that I am inexperienced in Java programming. I would like to add RA/Dec measurements from a telescope on Calar Alto (Spain) to the tutorial program AbstractOrbitDetermination. There I have the instance “stations” in the main program, that contains all the information about the GroundStation I want to use. It is defined via a Map:

final Map<String, StationData> stations = createStationsData(inputData, conventions, body);

My problem is to extract the information and to pass it on to a new variable that I can hand over to AngularRaDecBuilder.

I have tried this:
for (Entry<String, StationData> entry : stations.entrySet()) {
System.out.println("Key: " + entry.getKey() + " Value: " + entry.getValue());
if (entry.getKey().equals(“CAHA”)) {
final StationData CAHA = entry.getValue();
final GroundStation calarAlto = CAHA.getStation();
System.out.printf("Try this: ", calarAlto.getClass());
}
}

There is no error message but somehow the variable calarAlto is empty. (It just prints “Try this:” and nothing else. What am I doing wrong?

Hi @ruediger,

For this very specific point, you should maybe try System.out.println("Try this" + calarAlto.getClass()); instead.

Anyway, calarAlto.getClass() would return the class itself, i.e.GroundStation not the variable content.
Also GroundStation contains several objects (Earth frame, topocentric frame, station displacement model, several parameter drivers…) so you still would need to dig inside before printing something relevant.

I don’t understand what you try to achieve. If you want to add real measurements that you already have in a file, then you should simply convert the file to a format similar to the one supported by the tutorial (its just a column-oriented file, see W3B.aer as an example, and in your case the measurement type would be RA_DEC rather than AZ_EL, but you would need to create the parser for it). Creating the parser can be done by copying AzElParser and modifying it to create the proper type and add a case to call this new parser in the readMeasurements from the AbstractOrbitDetermination class).

If on the other hand you want to create the measurements by yourself for simulation purposes, then you would need an entirely different program that you should write, and this is not an easy task. The orbit determination tutorials consumes measurements, it does not create measurements. Unfortunately, they the online measurements generator we have set up in the OraaS site does not generate RA-DEC measurements, sorry for that.

So do you already have the measurements?

I already have the measurements. And I have already implemented the parser to digest RA and DEC. The orbit determination runs smoothly and returns credible results. And now I want to take the obtained solution, propagate it to the next night and predict where I have to point my telescope to reacquire the target. And for this I need to calculate Ra and Dec. Preferably in the same program, so at the end of AbstractOrbitDetermination. Isn’t that the best way to go?

Hi again @ruediger,

Here are some entry points for your problem:

I hope this will help you starting. Now feel free to ask any more help you need!
Note that there is also a tutorial here dedicated to measurement generation that can greatly help you.

Maxime

I understand now. You need a pointing program.
Ideally, it should be an independent program, run after orbit determination and using OD output. with a separate program, you could use any other reference orbit for pointing.

You can however modify the tutorial for this purpose, if you always want to do both OD on past measurements and pointing for next pass in row.

I would suggest the following:

Around line 453 of the tutorial, you should change the line:

            final Orbit estimated = estimator.estimate()[0].getInitialState().getOrbit();

into

          final Propagator estimatedPropagator = estimator.estimate()[0];
          final ORbit estimated = estimatedPropagator.getInitialState().getOrbit();
          final Generator generator = new Generator();
          final ObservableSatellite obsSat = generator.addPropagator(estimatedPropagator);
          final GroundStation cahaStation = stations.get("CAHA").getStation();
          final AngularRaDecBuilder raDecBuilder = new AngularRaDecBuilder(null,
                                                                             cahaStation,
                                                                             FramesFactory.getEME2000(),
                                                                             new double[] { 0.0, 0.0 },
                                                                             new double[] { 1.0, 1.0 },
                                                                             obsSat);
          final EventDetector above5Degrees = new ElevationDetector(cahaStation.getBaseFrame()).
                                              withConstantElevation(FastMath.toRadians(5.0));
          generator.addScheduler(new EventBasedScheduler<>(raDecBuilder,
                                                           new FixedStepSelector(10.0,
                                                                                 TimeScalesFactory.getUTC()),
                                                           estimatedPropagator,
                                                           above5Degrees,
                                                           SignSemantic.FEASIBLE_MEASUREMENT_WHEN_POSITIVE));
          SortedSet<ObservedMeasurement<?>> generated = generator.generate(myStartDate, myEndDate);

and then you should print the generatoed measurements in some file suitable for your telescope pointing program.

Here, I have arbitrarily used 10 seconds (aligned with UTC) for each generated measurement, and only when the satellite is 5 degrees above horizon as seen from the telescope site. You will need to adjust this to your needs.

Hope this helps

Thanks Luc. That’s exactly what I needed. It’s almost running now, but when I enter:

        final AbsoluteDate myStartDate = new AbsoluteDate("2010-11-02T09:50:40.0", TimeScalesFactory.getUTC());   
        final AbsoluteDate myEndDate   = new AbsoluteDate("2010-11-02T09:50:42.0", TimeScalesFactory.getUTC()); 
        SortedSet<ObservedMeasurement<?>> generated = generator.generate(myStartDate, myEndDate);
        System.out.println("size: " + generated.size());

It prints “size: 0”. I guess it means that the instance generated does not contain any measurements. I have changed the minimum elevation from +5 to -89 degrees, so it should produce measurements, even if the satellite is below the horizon, correct?
Or is there something wrong with the specification of the start and end date?

Sorry please ignore my previous message. My time window of 2 minutes was too small. Now I have increased it and I get the measurements. Just need to check, if they are correct …

Hi Luc, I have noticed that the first Ra/Dec measurement is not calculated at myStartDate but to some rounded value. I have this in my code:

        final AbsoluteDate myStartDate = new AbsoluteDate("2010-11-02T02:55:00.0", TimeScalesFactory.getUTC());   
        final AbsoluteDate myEndDate   = new AbsoluteDate("2010-11-02T03:15:00.0", TimeScalesFactory.getUTC());
        SortedSet<ObservedMeasurement<?>> generated = generator.generate(myStartDate, myEndDate);

        final ObservedMeasurement<?> radec = generated.first();
        System.out.println("Date of predicted measurement: " + radec.getDate());           
        final double ra1 = FastMath.toDegrees(radec.getObservedValue()[0]) + 360.0;

The printout reads:

Date of predicted measurement: 2010-11-02T03:00:00.000

which is 5 minutes after myStartDate. Do I have to set

new FixedStepSelector(600.0,

to a much lower value? But then I will get too many data points, which I am not interested in. What do you suggest?

This is expected. The call to the constructor new FixedStepSelector(10.0, TimeScalesFactory.getUTC()) means that the generator will generate one point every 10.0 second (or some other step size if you changed it, I see you used 600.0 seconds), but it will choose the dates in order to be aligned at integer multiple of the steps with respect to UTC. If for example you used 600.0 s step, then measurements will only occur at dates like 03:00:00.000, 03:10:00.000, 03:20:00.000… If you do not want the dates to be aligned with some time scale, then you simply have to use null as the second argument to the constructor.

I was looking at the example AbstractGroundMeasurementBuilderTest.doTest#L53 you sited but it contains:
import org.orekit.estimation.Context;
import org.orekit.estimation.EstimationTestUtils;
import org.orekit.estimation.Force;
These are not in my current version (10.2) I noticed that Bryan Cazabonne is using the ‘develop’ branch.
Will these features be coming out in Orekit 10.3?
Thanks.

Thanks Luc for your sustained support!

My program is running now: I have observed 1977-093E during 5 nights from the telescope on Calar Alto. I have used the measurements of the first 4 nights for orbit determination (that means my time interval is just a bit longer than 3 days, note the orbital period is about 4 days). The residuals are quite good: max RA error: 0.012 deg and max DEC error: 0.021 deg, but the prediction for the fifth night was 3.7 deg off in right ascension, which means I would not have found it with the telescope. I guess the reason is that fitting an orbit over less than one orbital period will not give enough precision for my purposes. I will test this, by making observations over let’s say at least two orbits. Then my predictions for the next pass should work. In 4 days I will know …

The ultimate target is to predict the orbits of these strange “empty trash bag objects” (https://www.livescience.com/64631-empty-trash-bag-space-debris.html) which are often confused with asteroids. Obviously nobody has a proper database for them (I guess not even Bill Grey).

Finally, can I give something back to the Orekit community? I have created RaDecParser, RaLog and DeclinationLog which could be added to Orekit. Please let me know if this is of interest.

3.7 degrees error seem very large to me, even considering you have only 3/4 of an orbit. The object however does have a very high eccentricity and low perigee. What force model do you use for this?
Given its elongated orbit, and the fact it is a rocket body and therefore probably high surface/mass ratio, I would go to a sufficient degree/order for Earth gravity field (something like 12x12) and solar radiation pressure, and estimating the reflection coefficient, which is probably weird. Unfortunately for a tumbling debris, we cannot guess an attitude law, so we are almost forced to use isotropic model for the body which is certainly far from reality.

This will be even worse for the empty trash bag object: the effect of solar radiation pressure is
probably very high and… unpredictable for a foil-like object.

Contributions are always welcome for Orekit! If you want to contribute something, you can either make a pull request on our gitlab instance or create a feature request in our issue tracker and attache the files. Please take a look at section 3.3 in the appendix of the governance document. It is a form that one-time contributors can sign and send to us so we file it and have a legal proof that we are allowed to publish the contribution (for information, regular contributors sign a different form, from section 3.2, you can sign that too if you intend to do other contributions in the future). Beware that as these forms will have your name and signature, they should not be published in this forum but rather sent by mail directly to the core team. People usually send them to me, Luc.Maisonobe@csgroup.eu.

Thanks in advance for your contribution!

A contributing guide is also available :slightly_smiling_face:

Before submitting something to Orekit I should make sure that my code is working properly and indeed the 3.7 deg error in right ascension after less than 1 day propagation is by far too big as I also learned by using an online OD tool called Find_Orb. Maybe you have heard about it: https://www.projectpluto.com/find_orb.htm . Using this tool the predicted RA/DEC is matching within arc minutes. Now I try to debug my code to find the error.
When copying AzElParser and creating RaDecParser there were only two things to change:

  1. Add the frame:

     final Frame inertialFrame = FramesFactory.getEME2000();
     final StationData stationData = getStationData(fields[2], stations, line, lineNumber, fileName);
     final AngularRaDec raDec = new AngularRaDec(stationData.getStation(), inertialFrame,
                                              getDate(fields[0], line, lineNumber, fileName),
                                              new double[] {
                                                    FastMath.toRadians(Double.parseDouble(fields[3])),
                                                    FastMath.toRadians(Double.parseDouble(fields[4]))
                                              },
                                              stationData.getRaDecSigma(),
                                              weights.getRaDecBaseWeight(),
                                              satellite);
    

and 2) remove the refraction correction which is not implemented in AngularRaDec:

    if (stationData.getRefractionCorrection() != null) {
        azEl.addModifier(stationData.getRefractionCorrection());
    }

That’s all I did here. Have I overlooked something?

I don’t see anything obvious.
Is the 3.7 degree error constant or time-dependent? Is the declination error also big or much smaller than right ascension error?
Also as the orbit period is about 4 days, did the perigee occur between the 3 third observation days and the 4th prediction day?