3-D Spacecraft Configuration Visualizer
plot_spacecraft_3d renders an interactive, rotatable 3-D model of a
spacecraft directly from its MissionConfig. The
figure is produced with Plotly and can be rotated, zoomed, and panned in
any browser or Jupyter notebook without running a full DITL simulation.
Features
Spacecraft bus — lit, solid-shaded box with configurable dimensions.
Telescope assembly — cylindrical baffle tube with aperture ring, mid-tube baffle rings, and secondary mirror housing. Sized automatically from
optics.aperture_mandoptics.tube_length_m.Solar panels — deep-blue solar cell faces on a silver frame. Uses
PanelGeometrywhen configured, otherwise places panels on the bus face whose outward normal best matches the panel normal vector. Panel area is estimated frommax_power.Radiators — white/MLI panels placed on the bus face matching
orientation.normal, sized bywidth_m×height_m.Star trackers — small prism bodies with a coloured aperture face, one per configured tracker. Each gets a distinct boresight-arrow colour.
Body-frame axes — +X / +Y / +Z triad with labelled arrows (red, green, blue).
Normal / boresight arrows — outward-normal arrows for solar panels and radiators; boresight arrows for the telescope and each star tracker.
Coordinate system
All geometry is expressed in the spacecraft body frame:
Axis |
Meaning |
|---|---|
+X |
Boresight / telescope pointing direction |
+Y |
Spacecraft “up” |
+Z |
Completes the right-handed system |
Quick start
from conops.config import MissionConfig
from conops.visualization import plot_spacecraft_3d
config = MissionConfig.from_json_file("examples/example_config.json")
fig = plot_spacecraft_3d(config)
fig.show()
No simulation run is needed — the visualizer reads geometry directly from the configuration.
Usage examples
Minimal default spacecraft
from conops.config import MissionConfig
from conops.visualization import plot_spacecraft_3d
# Default config gives a bus, one solar panel, one radiator, and one star tracker
fig = plot_spacecraft_3d(MissionConfig())
fig.show()
Custom Ritchey-Chrétien telescope
from conops.config import MissionConfig
from conops.config.instrument import Telescope, TelescopeConfig, TelescopeType, Payload
from conops.config.solar_panel import SolarPanel, SolarPanelSet, create_solar_panel_vector
from conops.visualization import plot_spacecraft_3d
config = MissionConfig(
payload=Payload(instruments=[
Telescope(
name="Primary",
boresight=(1.0, 0.0, 0.0),
optics=TelescopeConfig(
aperture_m=0.5,
focal_length_m=3.5,
tube_length_m=1.6,
telescope_type=TelescopeType.RITCHEY_CHRETIEN,
),
)
]),
solar_panel=SolarPanelSet(panels=[
SolarPanel(name="Panel +Y", normal=create_solar_panel_vector("sidemount"), max_power=1200.0),
SolarPanel(name="Panel -Y", normal=create_solar_panel_vector("sidemount", cant_z=180.0), max_power=1200.0),
]),
)
fig = plot_spacecraft_3d(config, title="RC Telescope — Dual Wing Config")
fig.show()
Overriding the bus box size
# bus_half_dims = (half_X, half_Y, half_Z) in metres
fig = plot_spacecraft_3d(config, bus_half_dims=(1.2, 0.65, 0.65))
fig.show()
Hiding normal vectors or axes
# Clean view without arrows
fig = plot_spacecraft_3d(config, show_normals=False, show_axes=False)
fig.show()
Embedding in a Jupyter notebook
# The figure is a standard go.Figure — display inline with:
fig = plot_spacecraft_3d(config)
fig # Jupyter evaluates this cell and renders the Plotly widget
Saving to HTML
fig = plot_spacecraft_3d(config)
fig.write_html("spacecraft_model.html")
Visual elements reference
Element |
Colour |
Source in config |
|---|---|---|
Spacecraft bus |
Silver-gray |
|
Telescope tube |
Dark gunmetal |
|
Aperture / baffle rings |
Gold |
|
Solar cell faces |
Deep blue |
|
Solar panel frames |
Silver |
Derived from panel geometry |
Radiators |
White / MLI |
|
Star tracker body |
Dark gray |
|
Star tracker aperture |
Per-tracker colour |
One of orange / hotpink / cyan / limegreen / gold / violet |
+X axis |
Red |
Hard-coded body frame |
+Y axis |
Limegreen |
Hard-coded body frame |
+Z axis |
Dodgerblue |
Hard-coded body frame |
Panel / radiator normals |
Yellow |
|
Telescope boresight |
Cyan |
|
Star tracker boresights |
Per-tracker colour |
|
Panel placement rules
When a PanelGeometry is attached to a solar
panel or radiator, its center_m, u, v, width_m, and
height_m fields are used directly.
When no PanelGeometry is set the visualizer falls back to automatic face
placement:
Dot-product the component normal against the six bus face normals.
Select the face with the largest dot product.
Place the component centre just outside that face (gap is component-specific; e.g. 20 mm for solar panels and 5 mm for radiators) and orient the panel spanning directions perpendicular to the face normal.
Solar panel size is estimated from max_power assuming 150 W/m² (solar
constant × typical conversion efficiency). Radiator size comes directly from
width_m and height_m.
API reference
See also
Mission Configuration — all geometric configuration fields in detail.
Visualization — overview of all COASTSim visualization utilities.
Sky Pointing Visualization — interactive sky-pointing globe.
conops.visualization.plot_sky_pointing_globe()— celestial-sphere globe driven by a completed DITL simulation.