ADCS.controller.plan_and_track_exact module

class ADCS.controller.plan_and_track_exact.Plan_and_Track_Exact(est_sat, planner_settings)[source]

Bases: PlanAndTrackBase

Plan-and-Track Exact controller using ALTRO planning with open-loop execution.

This controller plans an optimal attitude-control trajectory using the C++ ALTRO planner and then executes the planned control sequence open-loop (no feedback tracking). It is primarily intended for:

  • Validating feasibility and quality of planned trajectories.

  • Testing planner settings and cost weights in isolation from tracking.

  • Characterizing actuator usage and constraint satisfaction.

Relationship to other components

This class derives from PlanAndTrackBase, which provides:

  • Planner construction via _init_planner().

  • Environment propagation via _propagate_environment().

  • Common trajectory-optimization logic via _calculate_trajectory_common().

Mathematical description

The planner returns a discrete-time nominal trajectory

\[\{\mathbf{x}_k\}_{k=0}^{N-1}, \quad \{\mathbf{u}_k\}_{k=0}^{N-2},\]

sampled at times \(t_k\). The exact controller applies the nominal input directly:

\[\mathbf{u}(t_k) = \mathbf{u}_k,\]

without using the TVLQR feedback gains \(K_k\). Any model mismatch, disturbances, or estimation errors therefore appear as open-loop tracking error, making this variant useful for assessing the robustness margin of the planned trajectory.

Quaternion mode

During initialization, this controller sets the planner to use the full quaternion representation (exact 4-parameter attitude):

  • quat_to_3vec_mode = 2

The tracking formulation is configured as standard TVLQR on the C++ side (even though this class does not apply feedback), since the planner may still compute linearizations and gain-related data as part of its output.

param est_sat:

Estimated satellite model with actuators and sensors.

type est_sat:

EstimatedSatellite

param planner_settings:

ALTRO trajectory planner configuration bundle.

type planner_settings:

PlannerSettings

return:

None.

rtype:

None

calculate_trajectory(t_start, duration, x_0, os_0, goals, verbose=False)[source]

Plan an optimal trajectory using ALTRO and package it as a Trajectory object.

This method calls the common planning pipeline in _calculate_trajectory_common() to obtain the planner outputs, and then wraps them into a Trajectory instance.

Outputs

The returned trajectory contains:

  • lqr_times: time grid for the nominal plan and tracking data.

  • Xset: nominal state sequence.

  • Uset: nominal control sequence (reordered into Python actuator order).

  • Kset: TVLQR gains (reordered into Python actuator order), included for completeness even though this controller does not apply them.

  • Sset: auxiliary tracking/planner data returned by the C++ backend.

Mathematical interpretation

Let the planner’s nominal sequences be \(\mathbf{x}_k\) and \(\mathbf{u}_k\) at times \(t_k\). The resulting trajectory object represents the piecewise sampling of these sequences and provides time-indexed access to the nominal control via get_control_at().

param t_start:

Planning start time in J2000 centuries.

type t_start:

float

param duration:

Planning horizon length in seconds.

type duration:

float

param x_0:

Initial state vector used to seed the optimizer.

type x_0:

numpy.ndarray

param os_0:

Initial orbital state used to seed environment propagation.

type os_0:

Orbital_State

param goals:

Goal list used to compute inertial reference vectors along the horizon.

type goals:

GoalList

param verbose:

If true, enable planner verbosity and print vector diagnostics.

type verbose:

bool

return:

Planned trajectory container with times, states, controls, gains, and auxiliary data.

rtype:

Trajectory

Parameters:
Return type:

Trajectory

find_u(x_hat, sens, est_sat, os_hat, goal=None)[source]

Return the planned open-loop control input at the current time.

This method selects the control value from the active trajectory at the current orbital time and returns it directly. No feedback is applied.

Time selection

The current time is read from the estimated orbital state as os_hat.J2000 (J2000 centuries). Let this be \(t\). If the active trajectory is valid at \(t\), the controller returns:

\[\]

mathbf{u}(t) = mathbf{u}_{mathrm{traj}}(t),

where \(\mathbf{u}_{\mathrm{traj}}(t)\) is obtained via get_control_at().

Validity conditions

The method raises a runtime error if:

  • No active trajectory has been installed via set_active_trajectory().

  • The trajectory time window does not contain the current time, as tested by is_valid_time().

Parameter usage

The arguments x_hat, sens, est_sat, goal_vector_eci, and w_ref are accepted to match the Controller interface but are not used for control computation in the open-loop variant.

param x_hat:

Estimated state vector. Not used in open-loop execution.

type x_hat:

numpy.typing.NDArray[numpy.float64]

param sens:

Sensor measurement vector. Not used in open-loop execution.

type sens:

numpy.typing.NDArray[numpy.float64]

param est_sat:

Estimated satellite model. Not used in open-loop execution.

type est_sat:

EstimatedSatellite

param os_hat:

Estimated orbital state providing the current time.

type os_hat:

Orbital_State

param goal_vector_eci:

Goal vector in ECI frame. Not used in open-loop execution.

type goal_vector_eci:

typing.Optional[numpy.typing.NDArray[numpy.float64]]

param w_ref:

Reference angular velocity. Not used in open-loop execution.

type w_ref:

typing.Optional[numpy.typing.NDArray[numpy.float64]]

return:

Control vector from the active trajectory at the current time.

rtype:

numpy.typing.NDArray[numpy.float64]

Parameters:
Return type:

ndarray[tuple[int, …], dtype[float64]]

Parameters: