nominal_roll#

m4opt.dynamics.nominal_roll(observer_location, target_coord, obstime)[source] [edit on github]#

Determine the nominal roll angle for a space telescope.

Many space telescopes have a gross physical configuration that consists of a telescope boresight along the +X axis, solar panels that are on the +Y axis (which may be free to rotate around that axis to track the sun), and a +Z axis that points away from the sun shield toward the “dark” or “cool” side of the spacecraft. See below for an example from Chandra.

Chandra X-ray Observatory spacecraft coordinate system

Spacecraft coordinate system typical of most space telescopes. Reproduced with permission from SAO/CXC (see original).#

In space telescopes with this general physical plan, it is common to prefer or require that the roll of the telescope about the boresight places the +Y axis perpendicular to the direction of the sun, so that the solar array can be oriented for optimal power. This is called the nominal roll angle.

(It is assumed that when roll=0, the +Z axis points to celestial north.)

This function determines the nominal roll angle for a spacecraft at a given location, observing a given target at a given time.

Parameters:
  • observer_location (EarthLocation) – Location of the spacecraft.

  • target_coord (SkyCoord) – Orientation of the boresight of the telescope.

  • obstime (Time) – The time of the observation.

Returns:

The nominal roll angle for the observation.

Return type:

Annotated[Quantity, PhysicalType(‘angle’)]

Examples

(Source code)

../_images/m4opt-dynamics-nominal_roll-1.svg

Nominal roll angle over one year for a selection of ecliptic latitudes#

(Source code)

../_images/m4opt-dynamics-nominal_roll-2.svg

Maximum rate of change of nominal roll angle as a function of ecliptic latitude#

You can compute the nominal roll angle for a particular observation:

>>> from astropy.coordinates import GCRS, EarthLocation, SkyCoord
>>> from astropy.time import Time
>>> from astropy import units as u
>>> from m4opt.dynamics import nominal_roll
>>> observer_location = EarthLocation.from_geocentric(
...     6000 * u.km, 8000 * u.km, -3000 * u.km)
>>> obstime = Time("2024-12-25 12:00:00")
>>> target_coord = SkyCoord.from_name("NGC 4993")
>>> roll = nominal_roll(observer_location, target_coord, obstime)
>>> roll
<Quantity -72.56082178 deg>

You can create an appropriately rolled coordinate frame in the spacecraft coordinates by using the skyoffset_frame() method:

>>> obsgeoloc, obsgeovel = observer_location.get_gcrs_posvel(obstime)
>>> spacecraft_frame = target_coord.transform_to(
...     GCRS(obstime=obstime, obsgeoloc=obsgeoloc, obsgeovel=obsgeovel)
... ).skyoffset_frame(roll)