Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Note: This repository contains only one module of a larger rocket project developed by the student group RocKIT at the Karlsruhe Institute of Technology (KIT). The overall project focuses on the development of a small vertical takeoff and landing (VTVL) rocket powered by an ethanol–nitrous oxide (N₂O) propulsion system.

Dropper State Estimator

The estimator is based on the PX4 estimator, which is a robust professional estimator. The implementation has the following features:

  • Sensor fusion for 3IMUs, 2Mag, 2GPS and 3Lidars
  • Multi EKF Selector for robustness (multi IMUs)
  • Two levels of output fidelity:
    • Output predictor — runs at IMU sample rate. On each new IMU sample, it cheaply integrates the last corrected state forward (no full EKF math), giving the low-latency, high-rate estimate the controller needs for stability.
    • Full EKF correction — runs at a lower rate, applying the complete Kalman filter (prediction + measurement correction) to produce the corrected delayed state that the output predictor integrates from.

Architecture

Folder Organization

The DropperOS/src/GNC/Estimators/EKF/EKFcore folder is a faithful copy of the PX4 estimator.

Then, the DropperOS/src/GNC/Estimators/EKF folder is our OS-specific wrapper. The main actions of this folder are:

  • Conversion from DropperOS data structs to EKFcore structs that the estimator needs
  • Parameter override with our Dropper rocket specifics
  • Multi EKF selector for robustness (makes use of our multi-IMUs). This logic is also drawn from PX4.

Call Diagram

This is a basic overall explanation of the estimator. More details can be found at PX4 EKF Tuning Guide.

flowchart TB
    subgraph SensorTasks["Sensor tasks (FreeRTOS)"]
        IMU["IMUTask @ IMU_HZ (200 Hz)"]
        GPS["GPSTask"]
        MAG["MagTask"]
        LIDAR["LidarTask"]
    end
    subgraph Wrapper["StateEstimatorWrapper"]
        STAGE["Stage sensor data\n(imuDirty, gpsDirty, ...)"]
        EST["estimateState()"]
    end
    subgraph DropperLayer["Dropper EKF layer  (./EKF)"]
        EE["EkfEstimator"]
        CONV["SensorConversion\n(convertIMU, convertGPS, ...)"]
        SEL["EkfInstanceSelector\n(3 instances, pick best)"]
        OUT["convertOutput()\n→ StateEstimationData"]
    end
    subgraph EKFcore["PX4 EKF copy (./EKF/EKFcore)"]
        SET["Ekf::setIMUData()"]
        OP["OutputPredictor\ncalculateOutputStates()"]
        DS["ImuDownSampler\n→ IMU ring buffer"]
        UPD["Ekf::update()\npredict + fuse"]
    end
    subgraph Consumers["Consumers"]
        CTRL["ControlTask @ CONTROL_HZ (100 Hz)\n(reads getStateEstimation)"]
        TEL["Telemetry / FSM / ..."]
    end
    IMU --> STAGE
    GPS --> STAGE
    MAG --> STAGE
    LIDAR --> STAGE
    SETask["StateEstimationTask @ STATE_ESTIMATION_HZ (200 Hz)"] --> EST
    EST --> EE
    EE --> CONV
    CONV --> SET
    SET --> OP
    SET --> DS
    DS --> UPD
    UPD --> SEL
    SEL --> OUT
    OUT --> EST
    EST --> CTRL
    EST --> TEL
Loading

Note: this diagram represents the target architecture and is still a work in progress — several pieces are already implemented, but the design isn't fully locked down yet.

The flow reads roughly as follows:

sensor data (IMU, GPS, magnetometer, LIDAR) is staged by StateEstimatorWrapper, which calls estimateState(). Sensor conversion translates the data from DropperOS structs into the structs expected by EKFcore. From there, setIMUData() immediately calls the OutputPredictor (calculateOutputStates()), producing the fast prediction at the same rate as the IMU. The full Ekf::update() — which does the complete Kalman prediction and sensor fusion — is triggered separately, via a downsampler mechanism (in estimator_interface.cpp) that accumulates a certain number of IMU samples before running the whole Kalman update. How many samples get accumulated before that happens is configurable via a parameter, and is something we'll need to tune. Once a result is produced, it's converted back into the DropperOS output struct via convertOutput(), making it available to consumers such as the control task or telemetry.

Interface

The input/output interface is designed to match the OS data struct contract. It is documented in detail in another file.

Please see Dropper/Avionics/DropperOS/docs/markdown_docs/estimator/interface.md The filter parameters are also documented there.

Build

Build and test the EKFcore:

# From the EKF directory
cd Dropper/Avionics/DropperOS/src/GNC/Estimators/EKF

# First-time setup (only if build/ doesn't exist)
mkdir -p build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release

# Build
cmake --build . -j$(nproc)

# Run all tests
ctest --output-on-failure -j$(nproc)

Simulink Specifics

The implementation in DropperOS/src/GNC/Estimators/EKF can be tested on Simulink.

Find the ready-to-use Simulink Subsystem here: DropperModel/models/Dropper_Subsystem_StateEstimation.slx

And a minimal testbench for the estimator here: DropperModel/tests/EstimatorGroundTruthData/test/dropper_excitation_testbench.slx

For this, we compile our C++ estimator with the MATLAB MEX compiler. Then we can use an S-function block in Simulink. See the files in DropperModel/scripts/estimator to do the compilation:

  • build_sfun.m — does the build
  • sfun_dropper_ekf.cpp — the minimal Simulink interface which makes API calls to our estimator

Build

To build, simply:

# Set env var for non-interactive batch mode
export DROPPER_OS_PATH="/path/to/Dropper/Avionics/DropperOS"

# Run MATLAB batch compile
matlab -batch "cd('DropperModel/scripts/estimator'); build_sfun"

The output file is platform dependent:

  • DropperModel/sfun_dropper_ekf.mexa64 will run on Linux.
  • Compile again from a Windows machine to get the proper Windows format: .mexw64

Work in Progress

The following items are still open and need to be addressed:

  • Fully understand all of the parameters in Dropper/Avionics/DropperOS/src/GNC/Estimators/EKF/EkfConfig.cpp and define them correctly.
  • Update OS data structs of sensors and the estimator output.
  • Update the sensor model to be rich enough to simulate the estimator. An example can be found in:
  openExample("px4/RunPX4SITLWithQuadcopterPlantExample")
  • The in ./EKF files which does the orchestration between the ./EKF/EKFcore and the DropperOS is not completely define.
  • Decide: normal LIDAR measurement models in the Kalman filter (as already implemented in the Kalman filter) or triangulation dynamics for the measurement model to help predict height and quaternion.
  • Test and validation, first in Simulink and then on the Teensy — both are missing.

About

Extended Kalman Filter Estimator for a Vertical Take Off and Landing Rocket based on PX4

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages