Telemetry System
COASTSim’s telemetry system provides structured access to simulation data through typed data models. The telemetry system captures spacecraft state information during DITL simulations, making it easier to analyze, visualize, and export simulation results.
Overview
The telemetry system consists of three main components:
Housekeeping Records: Timestamped snapshots of spacecraft state at each simulation timestep
Payload Data Records: Records of data generation events during observations
Telemetry Container: A structured container that holds both housekeeping and payload data
This replaces the previous approach of storing telemetry as separate parallel arrays, providing better type safety, easier data access, and more structured analysis capabilities.
Housekeeping Data
Housekeeping records capture the complete spacecraft state at each simulation timestep.
from conops.ditl.telemetry import Housekeeping
# Example housekeeping record
hk = Housekeeping(
timestamp=datetime(2025, 1, 1, 12, 0, 0),
ra=45.0, # Right ascension in degrees
dec=-23.5, # Declination in degrees
roll=0.0, # Roll angle in degrees
acs_mode="SCIENCE", # ACS mode
panel_illumination=0.85, # Solar panel illumination (0-1)
power_usage=125.0, # Total power usage in W
power_bus=45.0, # Spacecraft bus power in W
power_payload=80.0, # Payload power in W
battery_level=0.75, # Battery state of charge (0-1)
charge_state=1, # Charging state (0=discharging, 1=charging)
battery_alert=0, # Battery alert level (0/1/2)
obsid=1001, # Current observation ID
recorder_volume_gb=25.3, # Data volume in recorder (Gb)
recorder_fill_fraction=0.2, # Recorder fill level (0-1)
recorder_alert=0, # Recorder alert level (0/1/2)
sun_angle_deg=75.3, # Angular distance to Sun in degrees
earth_angle_deg=62.1, # Angular distance to Earth in degrees
moon_angle_deg=118.5, # Angular distance to Moon in degrees
in_constraint=None, # Name of violated constraint, or None
)
Housekeeping Fields
- Attitude and Pointing
timestamp: UTC timestamp of the recordra: Right ascension in degreesdec: Declination in degreesroll: Roll angle in degreesroll_offset_deg: Signed offset from the solar-optimal roll in degrees (range [-180, 180)); meaningful only during SCIENCE mode.quat_w: Attitude quaternion scalar component (w)quat_x: Attitude quaternion vector component (x)quat_y: Attitude quaternion vector component (y)quat_z: Attitude quaternion vector component (z)
- ACS State
acs_mode: Current ACS mode (SCIENCE, SLEWING, SAFE, SAA, etc.)
- Power System
panel_illumination: Solar panel illumination fraction (0-1)power_usage: Total spacecraft power consumption in Wpower_bus: Spacecraft bus power consumption in Wpower_payload: Payload power consumption in Wbattery_level: Battery state of charge (0-1)charge_state: Battery charging state (0=discharging, 1=charging)battery_alert: Battery alert level (0=normal, 1=warning, 2=critical)
- Data Management
obsid: Current observation IDrecorder_volume_gb: Current data volume in recorder (Gb)recorder_fill_fraction: Recorder fill fraction (0-1)recorder_alert: Recorder alert level (0=normal, 1=warning, 2=critical)
- Constraint Geometry
sun_angle_deg: Angular distance from current pointing to Sun in degreesearth_angle_deg: Angular distance from current pointing to Earth in degreesmoon_angle_deg: Angular distance from current pointing to Moon in degreesin_constraint: Name of the constraint currently being violated (e.g."Sun","Earth Limb","Moon","Panel","Anti-Sun","ST Hard","ST Soft"), orNonewhen no constraint is active.for_solid_angle_sr: Instantaneous field-of-regard solid angle in steradians. This value is optional and isNoneunless FOR calculation is enabled.in_eclipse: Whether spacecraft is in eclipse
- Star Tracker and Radiator State
star_tracker_hard_violations: Number of star trackers in hard keep-out zonesstar_tracker_soft_violations: Whether any star tracker is in a soft-degradation zonestar_tracker_functional_count: Number of star trackers currently counted as functionalradiator_hard_violations: Number of radiators violating hard keep-out constraintsradiator_sun_exposure: Area-weighted Sun exposure for all configured radiators (0-1)radiator_earth_exposure: Area-weighted Earth exposure for all configured radiators (0-1)radiator_heat_dissipation_w: Total first-order net radiator heat flow (W); positive rejects heat, negative absorbs net external radiative load
Radiator metrics are continuous performance signals, not binary “working/failing” states. Pointing can reduce heat rejection or even drive temporary net heat absorption without implying hardware failure.
Payload Data
Payload data records capture data generation events during observations.
from conops.ditl.telemetry import PayloadData
from datetime import datetime
# Example payload data record
pd = PayloadData(
timestamp=datetime(2025, 1, 1, 12, 15, 0),
data_size_gb=2.5 # Size of data generated in Gb
)
Telemetry Container
The Telemetry class provides a structured container for
both housekeeping and payload data records.
from conops.ditl.telemetry import Telemetry, HousekeepingList, Housekeeping, PayloadData
# Create telemetry container
telemetry = Telemetry(
housekeeping=HousekeepingList([hk1, hk2, hk3]), # List of housekeeping records
data=[pd1, pd2] # List of payload data records
)
Accessing Telemetry Data
The telemetry container provides convenient access to data fields:
# Access housekeeping data
timestamps = telemetry.housekeeping.timestamp
ra_values = telemetry.housekeeping.ra
dec_values = telemetry.housekeeping.dec
acs_modes = telemetry.housekeeping.acs_mode
battery_levels = telemetry.housekeeping.battery_level
# Angular distances and constraint geometry
sun_angles = telemetry.housekeeping.sun_angle_deg
earth_angles = telemetry.housekeeping.earth_angle_deg
moon_angles = telemetry.housekeeping.moon_angle_deg
constraints = telemetry.housekeeping.in_constraint # list of str|None
# Star tracker health
hard_violations = telemetry.housekeeping.star_tracker_hard_violations
functional_count = telemetry.housekeeping.star_tracker_functional_count
# Access payload data
data_timestamps = [pd.timestamp for pd in telemetry.data]
data_sizes = [pd.data_size_gb for pd in telemetry.data]
Field Extraction Utilities
The Housekeeping class provides utility methods for
extracting fields from multiple records:
from conops.ditl.telemetry import Housekeeping
# Extract single field from multiple records
timestamps = Housekeeping.extract_field(housekeeping_records, 'timestamp')
battery_levels = Housekeeping.extract_field(housekeeping_records, 'battery_level')
# Extract multiple fields at once
fields = Housekeeping.extract_fields(housekeeping_records, ['ra', 'dec', 'acs_mode'])
Integration with DITL
During DITL simulation, telemetry data is automatically recorded and stored in the
ditl.telemetry attribute.
from conops.ditl import QueueDITL
from conops import MissionConfig
config = MissionConfig()
# FOR calculation is disabled by default.
# Enable it only when this telemetry is needed.
ditl = QueueDITL(config=config, calculate_field_of_regard=True)
ditl.calc() # Run simulation
# Access telemetry data
telemetry = ditl.telemetry
housekeeping = telemetry.housekeeping
payload_data = telemetry.data
# Analyze results
print(f"Simulation covered {len(housekeeping)} timesteps")
print(f"Generated {len(payload_data)} data records")
print(f"Average battery level: {sum(housekeeping.battery_level) / len(housekeeping):.2f}")
Visualization with Telemetry
All COASTSim visualization functions now work with the structured telemetry system:
from conops.visualization import plot_ditl_telemetry, plot_data_management_telemetry
# Plot basic telemetry timeline
fig, axes = plot_ditl_telemetry(ditl)
# Plot data management telemetry
fig2, axes2 = plot_data_management_telemetry(ditl)
Exporting Telemetry Data
Telemetry data can be easily exported for external analysis:
import pandas as pd
# Convert housekeeping to DataFrame
hk_df = pd.DataFrame({
'timestamp': housekeeping.timestamp,
'ra': housekeeping.ra,
'dec': housekeeping.dec,
'acs_mode': housekeeping.acs_mode,
'battery_level': housekeeping.battery_level,
'recorder_fill_fraction': housekeeping.recorder_fill_fraction
})
# Convert payload data to DataFrame
pd_df = pd.DataFrame({
'timestamp': [pd.timestamp for pd in payload_data],
'data_size_gb': [pd.data_size_gb for pd in payload_data]
})
# Export to CSV
hk_df.to_csv('housekeeping.csv', index=False)
pd_df.to_csv('payload_data.csv', index=False)
Migration from Legacy Arrays
If you have existing code that accesses telemetry as parallel arrays (ditl.ra, ditl.dec, etc.),
you can migrate to the new telemetry system:
# Legacy access (still works)
ra_values = ditl.ra
dec_values = ditl.dec
battery_levels = ditl.batterylevel
# New structured access
ra_values = ditl.telemetry.housekeeping.ra
dec_values = ditl.telemetry.housekeeping.dec
battery_levels = ditl.telemetry.housekeeping.battery_level
The legacy array access is maintained for backward compatibility, but the new telemetry system provides better type safety and more structured data access.