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:

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%
../_images/flight_comparator_9_1.png

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%
../_images/flight_comparator_10_4.png ../_images/flight_comparator_10_5.png ../_images/flight_comparator_10_6.png ../_images/flight_comparator_10_7.png ../_images/flight_comparator_10_8.png ../_images/flight_comparator_10_9.png ../_images/flight_comparator_10_10.png ../_images/flight_comparator_10_11.png ../_images/flight_comparator_10_12.png ../_images/flight_comparator_10_13.png

Trajectory Visualization#

Visualize 2D trajectory projections for spatial comparison:

# Plot trajectory in the XZ plane (side view)
comparator.trajectories_2d(plane="xz")
../_images/flight_comparator_11_0.png

See also

For detailed API documentation and additional methods, see rocketpy.simulation.FlightComparator in the API reference.