Skip to main content
Ctrl+K

M⁴OPT

  • Installation
  • User Guide
  • Design
  • Developer Documentation
  • GitHub
  • Installation
  • User Guide
  • Design
  • Developer Documentation
  • GitHub

Section Navigation

  • Field of Regard Constraints (m4opt.constraints)
  • Spacecraft Dynamics (m4opt.dynamics)
  • Fields of View (m4opt.fov)
  • Synthetic Photometry (m4opt.synphot)
  • Observer Locations (m4opt.observer)
  • Sky Grid Tessellation (m4opt.skygrid)
  • Mixed Integer Linear Programs (m4opt.milp)
  • Mission Profiles (m4opt.missions)
    • uvex_downlink_orientation
    • Mission
    • rubin
    • ultrasat
    • uvex
    • ztf
  • Utilities (m4opt.utils)
  • Command Line Interface
  • User Guide
  • Mission Profiles (m4opt.missions)
  • uvex_downlink_orientation

uvex_downlink_orientation#

m4opt.missions.uvex_downlink_orientation(time)[source] [edit on github]#

Get the target coordinates and roll for a UVEX downlink.

For UVEX, calculate the telescope boresight target coordinate and the roll angle of the satellite for a ground contact. This is the orientation that points the high gain antenna toward the Earth while maintaining pointing constraints.

Parameters:

time (Time) – Time of the downlink.

Returns:

Target coordinate and roll angle.

Return type:

tuple[SkyCoord, Angle]

Notes

UVEX’s high gain antenna is at a 45° angle to the spacecraft axes, and points toward the cool side and opposite the telescope boresight. In terms of the unit vector of the axes of the spacecraft coordinate system shown in the illustration for the nominal_roll() method, the direction \(\hat{\mathbf{a}}\) of the antenna is:

\[\hat{\mathbf{a}} = -\frac{\sqrt{2}}{2} \hat{\mathbf{x}} + \frac{\sqrt{2}}{2} \hat{\mathbf{z}}.\]

For a ground contact, the following conditions should be met, as shown in the diagram below:

  • Solar array drive axis is perpendicular to the direction of the Sun and the Earth

  • Earth is 135° from the telescope boresight

  • Sun is ≥45° from the telescope boresight

The example below shows that all of these constraints are met for downlinks at any time over the course of a year.

(Source code)

../_images/m4opt-missions-uvex_downlink_orientation-1.svg

Orientation of the UVEX spacecraft for a downlink.#

import numpy as np
from astropy import units as u
from astropy.coordinates import (
    SkyCoord,
    CartesianRepresentation,
    get_body,
)
from astropy.time import Time
from m4opt.missions import uvex as mission, uvex_downlink_orientation
from matplotlib import pyplot as plt

time = Time("2025-01-01") + np.linspace(0, 1, 1000) * u.year
target, roll = uvex_downlink_orientation(time)

observer_location = mission.observer_location(time)
sun = get_body("sun", time, observer_location)
earth = get_body("earth", time, observer_location)
spacecraft_frame = target.skyoffset_frame(roll)
antenna = SkyCoord(
    CartesianRepresentation(-1 / np.sqrt(2), 0, 1 / np.sqrt(2)), frame=spacecraft_frame
)
solar_array = SkyCoord(CartesianRepresentation(0, 1, 0), frame=spacecraft_frame)

fig = plt.figure()
ax = fig.add_subplot()
ax.yaxis.set_major_locator(plt.MultipleLocator(45))
ax.yaxis.set_major_formatter(plt.FormatStrFormatter("%g°"))
dt = time.datetime
ax.plot(dt, target.separation(earth), label=r"Target $\leftrightarrow$ Earth")
ax.plot(dt, target.separation(sun), label=r"Target $\leftrightarrow$ Sun")
ax.plot(dt, solar_array.separation(sun), label=r"Solar axis $\leftrightarrow$ Sun")
ax.plot(dt, antenna.separation(earth), label=r"Target $\leftrightarrow$ antenna")
ax.legend(title="Separation", loc="center right", bbox_to_anchor=(0.975, 0.25))

(Source code)

../_images/m4opt-missions-uvex_downlink_orientation-2.svg

Satisfaction of downlink constraints as a function of time.#

previous

Mission Profiles (m4opt.missions)

next

Mission

On this page
  • uvex_downlink_orientation()
Edit on GitHub
Show Source

© Copyright 2026, M4OPT Developers.

Created using Sphinx 9.1.0.

Built with the PyData Sphinx Theme 0.18.0.