Flight Comparator#
The rocketpy.simulation.FlightComparator class enables users to compare
a RocketPy Flight simulation against external data sources, providing error
metrics and visualization tools for validation and analysis.
See also
For comparing multiple RocketPy simulations together, see the Compare Flights guide.
Overview#
This class is designed to compare a RocketPy Flight simulation against external data sources, such as:
Real flight data - Avionics logs, altimeter CSVs, GPS tracking data
Other simulators - OpenRocket, RASAero, or custom simulation tools
Theoretical models - Analytical solutions or manual calculations
Unlike rocketpy.plots.compare.CompareFlights (which compares multiple
RocketPy simulations), FlightComparator specifically handles the challenge
of aligning different time steps and calculating error metrics (RMSE, MAE, etc.)
between a “Reference” simulation and “External” data.
Key Features#
Automatic time-step alignment between different data sources
Error metric calculations (RMSE, MAE, etc.)
Side-by-side visualization of flight variables
Support for multiple external data sources
Direct comparison with other RocketPy Flight objects
Creating a Reference Simulation#
First, import the necessary classes and modules:
Importing Classes#
import numpy as np
from rocketpy import Environment, Rocket, SolidMotor, Flight
from rocketpy.simulation import FlightComparator, FlightDataImporter
Setting Up the Environment#
First, let’s create the standard RocketPy simulation that will serve as our reference model. This follows the same pattern as in First Simulation with RocketPy.
# Create Environment (Spaceport America, NM)
env = Environment(
date=(2022, 10, 1, 12),
latitude=32.990254,
longitude=-106.974998,
elevation=1400,
)
env.set_atmospheric_model(type="standard_atmosphere")
Setting Up the Motor#
# Create a Cesaroni M1670 Solid Motor
Pro75M1670 = SolidMotor(
thrust_source="../data/motors/cesaroni/Cesaroni_M1670.eng",
burn_time=3.9,
grain_number=5,
grain_density=1815,
grain_outer_radius=33 / 1000,
grain_initial_inner_radius=15 / 1000,
grain_initial_height=120 / 1000,
grain_separation=5 / 1000,
nozzle_radius=33 / 1000,
throat_radius=11 / 1000,
interpolation_method="linear",
coordinate_system_orientation="nozzle_to_combustion_chamber",
dry_mass=1.815,
dry_inertia=(0.125, 0.125, 0.002),
grains_center_of_mass_position=0.33,
center_of_dry_mass_position=0.317,
nozzle_position=0,
)
Setting Up the Rocket#
# Create Calisto rocket
calisto = Rocket(
radius=127 / 2000,
mass=19.197 - 2.956,
inertia=(6.321, 6.321, 0.034),
power_off_drag="../data/rockets/calisto/powerOffDragCurve.csv",
power_on_drag="../data/rockets/calisto/powerOnDragCurve.csv",
center_of_mass_without_motor=0,
coordinate_system_orientation="tail_to_nose",
)
# Add rail buttons
calisto.set_rail_buttons(0.0818, -0.618, 45)
# Add motor to rocket
calisto.add_motor(Pro75M1670, position=-1.255)
# Add aerodynamic surfaces
nosecone = calisto.add_nose(
length=0.55829,
kind="vonKarman",
position=0.71971,
)
fin_set = calisto.add_trapezoidal_fins(
n=4,
root_chord=0.120,
tip_chord=0.040,
span=0.100,
position=-1.04956,
cant_angle=0.5,
airfoil=("../data/airfoils/NACA0012-radians.txt", "radians"),
)
tail = calisto.add_tail(
top_radius=0.0635,
bottom_radius=0.0435,
length=0.060,
position=-1.194656,
)
Running the Simulation#
# Create and run flight simulation
flight = Flight(
rocket=calisto,
environment=env,
rail_length=5.2,
inclination=85,
heading=0,
)
Creating the FlightComparator#
# Initialize FlightComparator with reference flight
comparator = FlightComparator(flight)
Adding Comparison Data#
Comparing with Another Flight#
You can compare against another RocketPy rocketpy.Flight object directly:
# Create a second simulation with slightly different parameters
flight2 = Flight(
rocket=calisto,
environment=env,
rail_length=5.0, # Slightly shorter rail
inclination=85,
heading=0,
)
# Add the second flight to comparator
comparator.add_data("Alternative Sim", flight2)
Added data source 'Alternative Sim' with variables: ['z', 'vz', 'x', 'y', 'speed', 'vx', 'vy', 'ax', 'ay', 'az', 'acceleration', 'altitude']
Comparing with External Data#
The primary data format expected by FlightComparator.add_data is a dictionary
where keys are variable names (e.g., "z", "vz", "altitude") and values
are either:
A RocketPy
rocketpy.Functionobject, orA tuple of
(time_array, data_array)
Let’s create some synthetic external data to demonstrate the comparison process:
# Generate synthetic external data with realistic noise
time_external = np.linspace(0, flight.t_final, 80) # Different time steps
external_altitude = flight.z(time_external) + np.random.normal(0, 3, 80) # Add 3 m noise
external_velocity = flight.vz(time_external) + np.random.normal(0, 0.5, 80) # Add 0.5 m/s noise
# Add external data to comparator
comparator.add_data(
"External Simulator",
{
"altitude": (time_external, external_altitude),
"vz": (time_external, external_velocity),
}
)
Added data source 'External Simulator' with variables: ['altitude', 'vz']
Tip
External data does not need to have the same time steps as the reference
simulation. The FlightComparator automatically handles interpolation
and alignment for comparison.
Analyzing Comparison Results#
Summary Report#
Generate a comprehensive summary of the comparison:
# Display comparison summary with key flight events
comparator.summary()
============================================================
FLIGHT COMPARISON SUMMARY
============================================================
RocketPy Simulation:
- Apogee: 4366.55 m at t=24.91 s
- Max velocity: 259.32 m/s
- Impact velocity: -200.54 m/s
- Flight duration: 51.08 s
External Data Sources: ['Alternative Sim', 'External Simulator']
Metric RocketPy Alternative Sim Alternative Sim Error Alternative Sim Error (%) External Simulator External Simulator Error External Simulator Error (%)
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Apogee Altitude (m) 4366.55 4366.41 -0.14 -0.00 4369.87 3.32 0.08
Apogee Time (s) 24.91 24.90 -0.01 -0.06 24.59 -0.32 -1.29
Max Velocity (m/s) 259.32 259.31 -0.02 -0.01 255.91 * -3.41 -1.32
Impact Velocity (m/s) -200.54 0.00 200.54 -100.00 200.98 * 401.52 -200.22
Note: Values marked with * are approximations (e.g., speed from vz only)
============================================================
Comparing Specific Variables#
You can compare individual flight variables:
# Compare altitude data across all sources
comparator.compare("altitude")
--------------------
COMPARISON REPORT: altitude
--------------------
Source: Alternative Sim
- MAE: 1399.8489
- RMSE: 1399.8489
- Max Deviation: 1400.0002
- Relative Error: 73.26%
Source: External Simulator
- MAE: 1400.5406
- RMSE: 1400.5434
- Max Deviation: 1409.0321
- Relative Error: 73.30%
The comparison plot shows the reference simulation alongside all external data sources, making it easy to identify discrepancies and validate the simulation.
Comparing All Variables#
To get a complete overview, compare all available variables at once:
# Generate plots for all common variables
comparator.all()
Generating comparison plots for: z, vz, ax, ay, az, altitude, speed, vx, vy, acceleration
--------------------
COMPARISON REPORT: z
--------------------
Source: Alternative Sim
- MAE: 0.1511
- RMSE: 0.1776
- Max Deviation: 0.3029
- Relative Error: 0.01%
--------------------
COMPARISON REPORT: vz
--------------------
Source: Alternative Sim
- MAE: 0.2065
- RMSE: 6.3416
- Max Deviation: 200.5397
- Relative Error: 5.46%
Source: External Simulator
- MAE: 0.4264
- RMSE: 0.6820
- Max Deviation: 5.7529
- Relative Error: 0.59%
--------------------
COMPARISON REPORT: ax
--------------------
Source: Alternative Sim
- MAE: 0.0004
- RMSE: 0.0010
- Max Deviation: 0.0208
- Relative Error: 5.27%
--------------------
COMPARISON REPORT: ay
--------------------
Source: Alternative Sim
- MAE: 0.0037
- RMSE: 0.0352
- Max Deviation: 1.0262
- Relative Error: 3.94%
--------------------
COMPARISON REPORT: az
--------------------
Source: Alternative Sim
- MAE: 0.0046
- RMSE: 0.1235
- Max Deviation: 3.9046
- Relative Error: 0.88%
--------------------
COMPARISON REPORT: altitude
--------------------
Source: Alternative Sim
- MAE: 1399.8489
- RMSE: 1399.8489
- Max Deviation: 1400.0002
- Relative Error: 73.26%
Source: External Simulator
- MAE: 1400.5406
- RMSE: 1400.5434
- Max Deviation: 1409.0321
- Relative Error: 73.30%
--------------------
COMPARISON REPORT: speed
--------------------
Source: Alternative Sim
- MAE: 0.2099
- RMSE: 6.3568
- Max Deviation: 201.0185
- Relative Error: 5.33%
--------------------
COMPARISON REPORT: vx
--------------------
Source: Alternative Sim
- MAE: 0.0005
- RMSE: 0.0036
- Max Deviation: 0.1143
- Relative Error: 2.03%
--------------------
COMPARISON REPORT: vy
--------------------
Source: Alternative Sim
- MAE: 0.0422
- RMSE: 0.4394
- Max Deviation: 13.8646
- Relative Error: 2.21%
--------------------
COMPARISON REPORT: acceleration
--------------------
Source: Alternative Sim
- MAE: 0.0045
- RMSE: 0.1242
- Max Deviation: 3.9259
- Relative Error: 0.88%
Trajectory Visualization#
Visualize 2D trajectory projections for spatial comparison:
# Plot trajectory in the XZ plane (side view)
comparator.trajectories_2d(plane="xz")
See also
For detailed API documentation and additional methods, see
rocketpy.simulation.FlightComparator in the API reference.