Get distance between two satellites

How I can get the distance between two satellites, I tried InterSatellitesRange class, but no luck.

I have more than one satellites get from TLE 2-line file and propgated.

Can anyone help with a piece of example code?

Thanks,
John

You can try something like this.

Beware, I just wrote it in a few minutes waiting for my plane at an airport, I didn’t test it. I wrote it assuming you have any number of satellites n (at least 2). If you have more than 2 spacecrafts, it should display the distances for all possible pairs.

   public void distancesEphemeris(List<TLE> tleList ,
                                                      AbsoluteDate startDate,
                                                      AbsoluteDate endDate,
                                                      double step,
                                                      PrintStream out) {
    final List<Propagator> propagatorsList = tleList.
                                             stream().
                                             map(tle -> TLEPropagator.selectExtrapolator(tle)).
                                             collect(Collectors.toList());
    PropagatorsParallelizer parallelizer =
                    new PropagatorsParallelizer(propagatorsList, new DistanceChecker(step, out));
    parallelizer.propagate(startDate, endDate);
}

private class DistanceChecker implements MultiSatStepHandler {

    private final double step;
    private final PrintStream out;
    private AbsoluteDate lastDate;

    DistanceChecker(double step, PrintStream out) {
        this.step     = step;
        this.out      = out;
    }

    public void init(final List<SpacecraftState> states0, final AbsoluteDate t) {
        printDistances(states0);
    }

    public void handleStep(List<OrekitStepInterpolator> interpolators, boolean isLast) {
        while (isInRange(lastDate.shiftedBy(step), interpolators.get(0))) {
            final AbsoluteDate next = lastDate.shiftedBy(step);
            List<SpacecraftState> states = interpolators.
                                           stream().
                                           map(i -> i.getInterpolatedState(next)).
                                           collect(Collectors.toList());
            printDistances(states);
        }
    }

    private boolean isInRange(AbsoluteDate date, OrekitStepInterpolator interpolator) {
        return interpolator.getPreviousState().getDate().compareTo(date) >= 0 &&
               interpolator.getCurrentState().getDate().compareTo(date) < 0;
    }

    private void printDistances(final List<SpacecraftState> states) {
        out.print(states.get(0).getDate());
        for (int i = 0; i < states.size() - 1; ++i) {
            for (int j = i + 1; j < states.size(); ++j) {
                out.print(" " +
                             Vector3D.distance(states.get(i).getPVCoordinates().getPosition(),
                                               states.get(j).getPVCoordinates().getPosition()));
            }
        }
        out.println();
        lastDate = states.get(0).getDate().shiftedBy(-step);
    }

}

The idea here is to use PropagatorsParallelizer to propagate all spacecrafts at once. One limitation of this class is that it does not handle fixed step handlers, but only a type of multi-sat handler that takes several step interpolators, so you have to compute the common date for comparing all states by yourself.

2 Likes

Hi luc,

Thanks for your quick reply, will try it and let you know.

Appreciate your help.
John

I will use slavemode for propagation, and use Vector3D to calculate the distance between any 2 satellites.
But one problem pops: how I know any 2 satellites are line of sign? Any easy way I can check this?

Thanks,
John

If you only want a rough check, you could consider Earth is spherical with a radius equal to Constants.WGS84_EARTH_EQUATORIAL_RADIUS. Then you can compute the apparent
angular radius of the Earth as seen from satellite 1 as:

double eta = FastMath.asin(Constants.WGS84_EARTH_EQUATORIAL_RADIU / pos1.getNorm());

On the other hand, the angular séparation between satellite 1 nadir direction and line of sight from satellite 1 to satellite 2 is:

double gamma = Vector3D.angle(pos1.negate(), pos2.subtract(pos1));

Satellite 2 is visible from satellite 1 if either gamma > eta (i.e. the satellite direction is away from Earth limb),
or if gamma < eta && Vector3D.distance(pos1, pos2) < pos1.getNorm() (i.e. if satellite 2 is in the direction of the Earth, but in front of it as seen from satellite 1. We assume here that at least pos2.getNorm() is always greater than Constants.WGS84_EARTH_EQUATORIAL_RADIUS).

If you want accurate computation, you should consider both the real shape of the Earth (using OneAxisEllipsoid.getIntersectionPoint() to compute the line of sight intersection with the ellipsoid, and
even consider atmospheric refraction in the case of just above limb cases.

You may want to apply safety margin on the computations too, which depending on your need may be
to consider satellites do see each other even if line of sight is slghtly below horizon, or it may be the opposite, considering satellites do not see each other even if line of sight skims slightly above horizon.

1 Like

Very appreciate your help, we are going to implement this now.

Thanks,
John