roverdevkit / data /analytical /SCHEMA.md
jjreif's picture
Deploy roverdevkit @ 2676a67
b3d14e3
|
Raw
History Blame Contribute Delete
13.3 kB

Analytical Dataset Column Schema

Produced by roverdevkit.surrogate.dataset.build_dataset from LHSSamples generated by roverdevkit.surrogate.sampling.generate_samples. Each row is one (design, scenario, soil) triple evaluated by roverdevkit.mission.evaluator.evaluate_verbose, flattened into a single Parquet row.

  • Schema version: v9 (see dataset.SCHEMA_VERSION). Scientific payload is an explicit mission requirement, carried by the scenario-side inputs scenario_payload_mass_kg and scenario_payload_power_w. Payload mass enters the total vehicle mass as a line item outside the AIAA S-120A dry-mass growth margin (m_total = m_dry + m_margin + m_payload); payload power adds to the continuous ops-time electrical load (alongside avionics) and to the hot-case thermal dissipation. Both are sampled uniform and family-agnostic (payload_mass_kg in [0, 30], payload_power_w in [0, 30]) so the entire webapp Mission-Inputs slider range is in-distribution. Payload lives on MissionScenario (a requirement set by the mission), not on DesignVector (a variable the designer trades); the design vector is 11-D. A per-call override on evaluate / /evaluate / /predict lets callers substitute a specific payload.
  • Fidelity level (this file): analytical β€” the Bekker-Wong terramechanics path solved inside traverse_sim.run_traverse.
  • Canonical filename: lhs_v9.parquet β€” the current training set, 40k rows at 10k Γ— 4 scenario families. Pilot (lhs_pilot.parquet) and challenge (challenge_v1.parquet) files are generated on demand from scripts/build_dataset.py; only the canonical training set is treated as a tracked artifact.

Dataset-level metadata is written to the Parquet file's schema footer; use read_parquet_metadata(path) to recover it (seed, sampler version, scenario families, val/test fractions, UTC build timestamp, evaluator version, free-form notes).

Column groups

Prefix conventions:

  • design_* β€” inputs from the 11-D DesignVector.
  • scenario_* β€” inputs from the MissionScenario, plus the sampler's jittered Bekker soil parameters (scenario_soil_*).
  • stat_* β€” aggregate statistics (mean / p95 / max / final) reduced from the per-step TraverseLog time series.
  • Unprefixed columns with physical units (e.g. range_km) β€” targets from MissionMetrics.
  • Otherwise β€” dataset metadata.

Dataset metadata (5 columns)

Column dtype Description
sample_index int64 Monotonic row id from the sampler. Stable across re-runs with the same seed.
split category train / val / test, assigned at sample time with a deterministic RNG independent of row ordering.
stratum_id int 0 = 4-wheel, 1 = 6-wheel. Matches design_n_wheels.
fidelity category analytical for this file β€” the Bekker-Wong terramechanics path. No separate fidelity tier is shipped.
status category ok if evaluator succeeded, else the exception class name (e.g. ValueError). Numeric target columns are NaN on non-ok rows; boolean targets are False.

Design vector (11 columns)

All design_* columns mirror the DesignVector pydantic schema.

Column dtype Range Description
design_wheel_radius_m float64 [0.05, 0.20] Wheel radius R
design_wheel_width_m float64 [0.03, 0.20] Wheel width W
design_grouser_height_m float64 [0.0, 0.020] Grouser height
design_grouser_count int64 [0, 24] Number of grousers per wheel
design_n_wheels int64 {4, 6} Wheel count (kept in sync with architecture)
design_mobility_architecture category rigid_4wheel, rocker_bogie_6wheel Primary mobility-architecture trade in the evaluator/optimizer. Not yet present in the shipped lhs_v9.parquet surrogate training set; the surrogate still keys off design_n_wheels until the dataset is rebuilt.
design_chassis_mass_kg float64 [0.5, 50.0] Dry chassis mass (structural chassis only)
design_wheelbase_m float64 [0.3, 1.2] Wheelbase
design_solar_area_m2 float64 [0.1, 1.5] Solar array area
design_battery_capacity_wh float64 [5.0, 500.0] Usable battery energy
design_avionics_power_w float64 [5.0, 40.0] Continuous avionics draw
design_peak_wheel_torque_nm float64 [0.05, 20.0] Per-wheel hub torque capacity. Cruise speed is derived inside the evaluator from torque + slip + power balance (see roverdevkit/drivetrain/motor.py::cruise_speed). LHS is log-uniform around a per-row anchor rather than uniform on these bounds β€” see roverdevkit/surrogate/sampling.py::_peak_wheel_torque_anchor_for_row.

Scenario inputs (18 columns)

Family-fixed columns (scenario_family, scenario_terrain_class, scenario_soil_simulant, scenario_sun_geometry, scenario_traverse_distance_m) take one of four canonical values per family. The remaining columns are jittered per sample.

Column dtype Notes
scenario_family category One of equatorial_mare_traverse, polar_prospecting, highland_slope_capability, crater_rim_survey. Use for per-scenario accuracy breakdown.
scenario_name category Mirrors scenario_family in this dataset (validation-only scenarios live elsewhere).
scenario_latitude_deg float64 Family-specific range; see sampling.FAMILIES.
scenario_traverse_distance_m float64 Family-fixed, non-binding β€” deliberately above the energy-/duty-limited reach so range_km stays a continuous signal instead of saturating at a distance cap.
scenario_terrain_class category mare_nominal, mare_loose, highland_dense, polar_regolith.
scenario_soil_simulant category Family nominal; the actual Bekker numbers used by the evaluator are the scenario_soil_* columns below.
scenario_mission_duration_earth_days float64 Family-specific range.
scenario_max_slope_deg float64 Family-specific range.
scenario_operational_duty_cycle float64 Drive duty cycle the rover would actually run on the ground β€” sets Ξ΄_eff = clamp(Ξ΄_ops, 0, 0.6) in the traverse loop. Sampled per row uniform on [0, 0.6] independently of family, so the surrogate keys off it as a true continuous input. The per-family default is kept on ScenarioFamily for canonical YAML / UI initial slider position.
scenario_sun_geometry category continuous / diurnal / polar_intermittent.
scenario_soil_n float64 Bekker sinkage exponent, jitter bounds [0.8, 1.2].
scenario_soil_k_c float64 Cohesive modulus, [0.5, 2.0] kN/m^(n+1).
scenario_soil_k_phi float64 Frictional modulus, [400, 1200] kN/m^(n+2).
scenario_soil_cohesion_kpa float64 Soil cohesion, [0.1, 1.0] kPa.
scenario_soil_friction_angle_deg float64 Internal friction angle, [30, 50]Β°.
scenario_soil_shear_modulus_k_m float64 Janosi-Hanamoto K, [0.010, 0.025] m.
scenario_payload_mass_kg float64 Scientific-payload mass (mission requirement). Per-row LHS feature uniform on [0, 30] independently of family. Added to total vehicle mass as a line item outside the dry-mass growth margin; the per-scenario default is kept on the YAML / ScenarioFamily for canonical webapp slider position.
scenario_payload_power_w float64 Scientific-payload continuous ops-time power (mission requirement). Per-row LHS feature uniform on [0, 30]. Added to the continuous electrical load (alongside avionics) in the traverse budget and to the hot-case thermal dissipation.
scenario_required_obstacle_height_m float64 Minimum traversable obstacle/step height (m). Defaults to 0 on the canonical smooth-regolith scenarios. Evaluator-only today: obstacle metrics (obstacle_capability_m, obstacle_margin_m) are computed from mobility_architecture and wheel radius; the surrogate does not yet predict them.

Mission-metric targets (8 columns)

Mirror MissionMetrics fields. range_km and energy_margin_raw_pct are the primary regression targets (no saturation); *_pct and the boolean flag are secondary reporting/classification targets. thermal_survival is not in this group: the evaluator still computes it as a diagnostic, but the mass model treats RHU power and MLI quality as free, so it reduces to a near-trivial gate with no real design trade-off and the surrogate does not consume or predict it.

Column dtype Notes
range_km float64 Energy-feasible mission range. run_traverse applies an in-traverse throttle that drops effective duty when the battery floors and load exceeds solar.
energy_margin_pct float64 Clipped 0-100, SOC-based reporting metric.
energy_margin_raw_pct float64 Unclipped mission-integrated (E_in - E_out)/E_out Γ— 100; primary surrogate target.
slope_capability_deg float64 Max climbable slope on this soil.
total_mass_kg float64 Mass-model output.
peak_motor_torque_nm float64 Observed peak wheel torque during traverse.
sinkage_max_m float64 Observed peak sinkage during traverse.
stalled bool Single feasibility classifier target (1 = infeasible). Captures whether the rover failed the slip-balance solve at any traverse step (Brent solver could not find a slip that satisfied force balance under the available drawbar pull and torque envelope).

Evaluator-only architecture metrics (present on live /evaluate and optimizer outputs, not in the shipped lhs_v9.parquet targets):

Column dtype Notes
obstacle_capability_m float64 Estimated max traversable obstacle height from architecture proxy ($h_{\mathrm{obs}} = k_{\mathrm{arch}} R$).
obstacle_margin_m float64 Capability minus scenario_required_obstacle_height_m.
obstacle_requirement_met bool Whether obstacle_margin_m \ge 0.
architecture_mass_kg float64 Rocker-bogie suspension/linkage mass charged in the bottom-up mass model.

Traverse-log aggregate statistics (β‰₯24 columns)

Reduced from the per-step TraverseLog time series. Used to measure where the surrogate needs to be accurate (peak-load versus steady-state regimes) and as auxiliary diagnostics for the baselines.

Numeric aggregates (mean / p95 / max over the whole traverse, absolute value for signed quantities like slip and torque):

  • stat_power_in_{mean,p95,max}_w β€” solar input power.
  • stat_power_out_{mean,p95,max}_w β€” total electrical draw (mobility + avionics).
  • stat_mobility_power_{mean,p95,max}_w β€” mobility subsystem draw alone.
  • stat_slip_{mean,p95,max} β€” wheel slip magnitude in [0, ~0.95].
  • stat_sinkage_{mean,p95}_m β€” peak is already sinkage_max_m above.
  • stat_wheel_torque_{mean,p95}_nm β€” peak is already peak_motor_torque_nm above.
  • stat_sun_elevation_{mean,max}_deg β€” degrees above horizon.
  • stat_soc_final / stat_soc_min β€” end-of-mission and deepest SOC.

Boolean end-of-run flags:

  • stat_rover_stalled β€” Brent slip solve failed at some step.
  • stat_battery_floored β€” SOC hit the 15% DoD floor during the run.
  • stat_reached_distance β€” the rover reached the scenario's (non-binding) distance budget.

Categorical:

  • stat_terminated_reason β€” a free-form short string from the sim layer (e.g. "mission_duration", "evaluator_error"). Use as a post-hoc diagnostic; not suitable as a model input.

Layer-1 registry sanity scope

roverdevkit.surrogate.baselines.predict_for_registry_rovers produces a registry_sanity.csv artifact with one row per (rover, algorithm, target) tuple plus an is_primary boolean. The split is enforced by the LAYER1_PRIMARY_TARGETS / LAYER1_DIAGNOSTIC_TARGETS constants in roverdevkit/surrogate/baselines.py:

  • Primary (is_primary=True): total_mass_kg, slope_capability_deg, stalled. Design-axis metrics where the LHS bounds put every flown / design-target rover inside the surrogate's training support. Treated as the main registry sanity set.
  • Diagnostic (is_primary=False): range_km, energy_margin_raw_pct. Both are scenario-OOD for the registry: Pragyan β‰ˆ 100 m, Yutu-2 β‰ˆ 25 m / lunar day, MoonRanger and Rashid-1 β‰ˆ 1 km published mission distances against LHS family budgets of 20–80 km (intentionally non-binding so range_km stays a continuous training signal). The relative error for these targets is dominated by the absolute-scale mismatch and reflects scenario-OOD rather than a surrogate-calibration failure. Reported for transparency only.

Slope MAPE on Pragyan and MoonRanger runs elevated relative to mass: published rover slope-capability specs come from real-rover-specific design choices the analytical Bekker-Wong kernel's feature space cannot fully resolve.

Column count sanity

Metadata (5) + design (11) + scenario (18) + metrics (8) + stats (β‰₯24) = β‰₯66 columns at SCHEMA_VERSION = v9. Future versions appending, removing, or re-binding columns β€” or changing the LHS support so a surrogate trained on one version would be OOD on the next β€” must bump SCHEMA_VERSION so downstream code can detect a mismatch.