# Satellite footprint when beam pointed to specific ground station

I’d found this post and implemented it with NadirPointing

As expected it results in a circle below the spacecraft.

On a spacecraft with flat panels or mechanically steered dishes the beam can be pointed to a target ground station without changing satellite attitude.

How could I alter the code from the linked question such that the resulting location isn’t tied to satellite attitude but instead by a ground station target location?

Hi @JarrodSears welcome!

This can be achieved by twicking the fovToBody Transform that is passed as first argument to the getFootprint call.

As written in the post you refer too (and also in various test methods in PolygonalFieldOfViewTest), this transform is computed directly from satellite state (i.e. taking into account attitude between satellite frame and inertial frame), combined with body frame (i.e Earth orientation with respect to inertial frame). If you were using a polygonal field of view, I would have suggested to start from this and append the transform between satellite frame and sensor frame taking the steering mechanism behavior into account. However, since you have a circular field of view, there is a much simpler approach: compute the Line Of Sight vector from satellite to ground target in Earth frame and then compute the rotation that transform fov central vector (say Z axis for example) to this vector . This would be something along these lines:

Vector3D targetEarth = earth.transform(geodeticPoint); // this can be computed once as it does not depend on date
Vector3D losEarth    = target.subtract(spacecraftState.getPosition(earth.getBodyFrame()));
Transform fovToBody  = new Transform(date, new Rotation(Vector3D.Z, losEarth));

Dear Orekit community,
@luc and @JarrodSears

I wanted to ask a similar question, but since someone has just asked it, I would not open a new Topic. I’d like to determine the time when the ISS enters the field of view of a specified point on the ground.

I don’t fully understand the physics behind it yet, but I’m working on it.

Based on the answer, I created a code, but I get an error. @luc could you please take a look at it, I tried to do what you wrote. Unfortunately, I still don’t fully understand it, so I’m not sure if I succeeded

Here is my code

// ISS
TLE tle = new TLE(
"1 25544U 98067A   23208.30934329  .00015800  00000+0  28347-3 0  9998",
"2 25544  51.6413 129.7314 0000554  64.5675  79.5453 15.50079229408012",
TimeScalesFactory.getUTC()
);

Frame earthFrame = FramesFactory.getITRF(IERSConventions.IERS_2010, true);
BodyShape earth = new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS, Constants.WGS84_EARTH_FLATTENING, earthFrame);

// predict
final TLEPropagator propagator = TLEPropagator.selectExtrapolator(tle);
AbsoluteDate target = new AbsoluteDate(new Date(), TimeScalesFactory.getUTC());
SpacecraftState state = propagator.propagate(target);
Vector3D satPoint = state.getPVCoordinates().getPosition();
GeodeticPoint geoPoint = earth.transform(satPoint, state.getFrame(), state.getDate());
System.out.println(geoPoint);

//        Transform inertToBody = state.getFrame().getTransformTo(earthFrame, state.getDate());

//        Transform fovToBody = new Transform(state.getDate(),
//                state.toTransform().getInverse(),
//                inertToBody);

//create gps point on earth frame
final double altitude  = 0.;

GeodeticPoint gpsPoint = new GeodeticPoint(latitude, longitude, altitude);
Vector3D targetEarth = earth.transform(gpsPoint); // this can be computed once as it does not depend on date
Vector3D losEarth    = targetEarth.subtract(state.getPVCoordinates(earthFrame).getPosition());
Transform fovToBody  = new Transform(target, new Rotation(Vector3D.PLUS_K, losEarth));

CircularFieldOfView cfov =

List<List<GeodeticPoint>> footprint =
cfov.getFootprint(fovToBody, (OneAxisEllipsoid) earth, 0.1);

List<GeodeticPoint> list = footprint.get(0);
for (GeodeticPoint point : list) {
System.out.println("[" + FastMath.toDegrees(point.getLongitude()) + "," +
FastMath.toDegrees(point.getLatitude()) + "],");
}

and exception:
Exception in thread “main” org.orekit.errors.OrekitException: point is inside ellipsoid

Could you tell me which point is inside the ellipsoid and why?

I have one more question.
I tried to calculate the field of view based on the following article: Field of View Sat Event Detector Example
I started with Evan’s code and used TLE propagator to define the orbit. The values I got weren’t appropriate and I found this post.

I think that both solutions could be used to determine getting into the field of view. (Am I getting this right?)
How do the two implementations differ?

Rol

I think I made an error and you found it!
With what I suggested, fovToBody is a simple rotation, without a translation, so its origin is at the center of the Earth. This origin is used in the first few lines of getFootprint, as it was supposed to be centered on satellite. Obviously, the center of the Earth is within the Earth

So you have to create a Transform that is a composition of two lower level transforms: the rotation I already mentioned, and a translation that accounts for satellite position. The trick is to put them in the correct order and direction.

Beware also that a fov centered on a satellite and a field of view centered on a ground point are really different things.

Are there examples available in the documentation or elsewhere that show how this would be done?

Not really…

Try this:

Transform fovToBody  = new Transform(date,
new Transform(date, spacecraftState.getPosition(earth.getBodyFrame()).negate()),
new Transform(date, new Rotation(Vector3D.Z, losEarth));

I’m not sure I got it in the correct direction and composition order though.

Hi，guys！
I’ve checked this problem and verified it.

#get current Date
date = self.endState.getDate()
#Caculate the los in ECF frame
targetEarth = self.earth.transform(target_geodeticPoint)
los_sat2target_ecf   = targetEarth.subtract(self.endState.getPVCoordinates(self.earthFrame).getPosition())
#get the transform from J2000 to ECF
inertToBody = self.endState.getFrame().getTransformTo(self.earth.getBodyFrame(), date)
#get the transform from satellite body frame to ECF frame
satBody2ecf = Transform(date, self.endState.toTransform().getInverse(), inertToBody)
#transform the los into the satellite body frame
losPointing_body=satBody2ecf.getInverse().getRotation().applyTo(los_sat2target_ecf.normalize())

Then ,you can use this vector in for example getfootprint().