Source code for opengnc.classical_control.bdot

"""
B-Dot controller for spacecraft magnetic detumbling.
"""


import numpy as np


[docs] class BDot: r""" B-Dot controller for magnetic detumbling. Control Law: $\mathbf{m} = -K_{gain} \dot{\mathbf{B}}$ Parameters ---------- gain : float Feedback gain $K$ ($Am^2 s / T$). """ def __init__(self, gain: float) -> None: """Initialize the B-Dot controller.""" self.gain = gain
[docs] def calculate_control(self, b_dot: np.ndarray | list[float]) -> np.ndarray: r""" Calculate the required magnetic dipole moment from the B-field rate. Parameters ---------- b_dot : np.ndarray or list The time derivative of the magnetic field vector ($\dot{B}$) in the Body frame (3,). Units: [T/s]. Returns ------- np.ndarray Magnetic dipole moment vector $m$ in Body frame (3,). Units: $[A \cdot m^2]$. """ # Standard law: m = -K * B_dot return -self.gain * np.asarray(b_dot, dtype=float)
[docs] def calculate_control_discrete( self, b_field_curr: np.ndarray | list[float], b_field_prev: np.ndarray | list[float], dt: float, ) -> np.ndarray: r""" Calculate B-Dot control using discrete finite differences. Useful when only B-field measurements are available instead of explicit rates. Parameters ---------- b_field_curr : np.ndarray or list Current magnetic field vector measurement (Body frame). Units: [T]. b_field_prev : np.ndarray or list Previous magnetic field vector measurement (Body frame). Units: [T]. dt : float Time step between measurements (s). Returns ------- np.ndarray Magnetic dipole moment vector $m$ in Body frame (3,). """ if dt <= 0: return np.zeros(3) # Estimate B_dot via backward difference b_dot_est = (np.asarray(b_field_curr) - np.asarray(b_field_prev)) / dt return self.calculate_control(b_dot_est)