Overview
This document describes the implementation of:
- Robust DDP Controller (C++ port from Python engine simulation)
- Enhanced EKF Navigation with magnetometer support
- IMU Calibration System (accelerometer, gyroscope, magnetometer)
Robust DDP Controller
Location
Features
- Thrust regulation via pressure control
- Safety filtering for constraint satisfaction
- Warm start for efficient optimization
- Robustness bounds for uncertainty handling
Usage
meas.P_reg = ...;
nav.vz = vertical_velocity;
auto [actuation, diagnostics] = controller.
step(meas,
nav, cmd);
apply_solenoid_duty(actuation.duty_F, actuation.duty_O);
}
static std::atomic< bool > running
Robust Hybrid Optimal Controller.
bool initialize(const Config &config)
std::pair< ActuationCommand, Diagnostics > step(const Measurement &meas, const NavState &nav, const Command &cmd)
Execute one control step.
static const idle_config_t config
State Vector
- P_copv: COPV pressure
- P_reg: Regulator pressure
- P_u_fuel: Fuel upstream pressure
- P_u_ox: Oxidizer upstream pressure
- P_d_fuel: Fuel downstream pressure
- P_d_ox: Oxidizer downstream pressure
- V_u_F: Fuel ullage volume
- V_u_O: Oxidizer ullage volume
- Additional states (3)
Control Output
- duty_F: Fuel solenoid duty cycle [0-1]
- duty_O: Oxidizer solenoid duty cycle [0-1]
Enhanced EKF Navigation
Location
Enhancements
- Magnetometer integration for heading estimation
- Calibrated IMU measurements
- Magnetic declination correction
- Heading estimation from magnetometer + gyro fusion
Usage
config.use_magnetometer =
true;
config.magnetic_declination = 0.1;
config.magnetometer_noise = 0.01;
auto imu_calib = std::make_shared<IMUCalibrationSystem>();
IMUMeasurement imu_meas;
imu_meas.magnetometer = Eigen::Vector3d(...);
imu_meas.timestamp = now();
auto calibrated_mag = imu_calib->calibrateIMU(accel_raw, gyro_raw, mag_raw);
Enhanced EKF Navigation with Magnetometer Support.
bool initialize(const EnhancedConfig &config, const NavigationState &initial_state)
Initialize with enhanced configuration.
bool processMagnetometerMeasurement(const IMUMeasurement &measurement, const calibration::IMUCalibration::CalibratedReading &calibrated)
Process magnetometer measurement with calibration.
void setIMUCalibration(std::shared_ptr< calibration::IMUCalibrationSystem > calib_system)
Set IMU calibration system.
double getHeading() const
Get heading estimate (from magnetometer + gyro fusion).
Output smoothing for calibrated PT pressure, per sensor uid (ESP32 and LabJack T7 alike).
Enhanced configuration with magnetometer parameters.
IMU Calibration System
Python Calibration Workflow
Calibration is performed using Python scripts (similar to PT calibration), and the resulting parameters are loaded into the C++ runtime system for real-time sensor correction.
For the Python calibration workflow and per-sensor procedures, see ../tools/calibration/README_IMU.md.
C++ Runtime Application
Usage
C++ Runtime Application:
std::vector<IMUCalibration::RawReading> accel_readings;
std::vector<IMUCalibration::RawReading> gyro_readings;
std::vector<IMUCalibration::RawReading> mag_readings;
for (int i = 0; i < 6; ++i) {
reading.
value = get_accel_reading();
accel_readings.push_back(reading);
}
for (int i = 0; i < 100; ++i) {
reading.
value = get_gyro_reading();
gyro_readings.push_back(reading);
}
Eigen::Vector3d reference_field(1.0, 0.0, 0.0);
for (int i = 0; i < 12; ++i) {
reading.
value = get_mag_reading();
mag_readings.push_back(reading);
}
accel_readings,
gyro_readings,
mag_readings,
reference_field
);
Eigen::Vector3d accel_calibrated =
calibrated.accelerometer.value;
Eigen::Vector3d gyro_calibrated =
calibrated.gyroscope.value;
Eigen::Vector3d mag_calibrated =
calibrated.magnetometer.value;
Complete IMU Calibration System.
bool calibrateAll(const std::vector< IMUCalibration::RawReading > &accel_readings, const std::vector< IMUCalibration::RawReading > &gyro_readings, const std::vector< IMUCalibration::RawReading > &mag_readings, const Eigen::Vector3d &reference_magnetic_field)
Calibrate all sensors.
CalibratedIMU calibrateIMU(const IMUCalibration::RawReading &accel, const IMUCalibration::RawReading &gyro, const IMUCalibration::RawReading &mag) const
std::chrono::steady_clock::time_point timestamp
Integration with SITL
All components integrate with SITL:
- Robust DDP Controller: Receives measurements from SITL, outputs actuation
- Enhanced EKF: Processes simulated sensor data, estimates navigation state
- IMU Calibration: Calibrates simulated IMU sensors before EKF processing
References
- Engine Simulation Controller: engine_sim/docs/control/
- DDP Solver: engine_sim/docs/control/DDP_SOLVER.md
- EKF Navigation: diablo_server/lib/include/nav/EKFNavigation.hpp