Skip to content

iotrustlab/buggy_drone

Repository files navigation

Buggy Drone: A Modular Drone Simulation, SCRBE Pipeline, and Fuzzing Suite

Contents

Overview and scope

This project implements:

  • A modular drone simulation with PyBullet dynamics, mission execution, telemetry logging, and Matplotlib-based visualization.
  • A structure- and component-preserving reduced pipeline (SCRBE) for fast, static-state analyses of emergency deployment logic.
  • An STL-guided, Hypothesis-powered fuzzer that explores battery/altitude and controller parameters to falsify a safety property.

The systems are intentionally instrumented for message logging and trace capture to enable reproducible experiments and visual analysis.

Repository layout

  • core/: Drone internals
    • messaging.py: topic-based in-process message bus with CSV logging
    • physics_engine.py: PyBullet wrapper
    • drone.py: integrates physics, controllers, and state publication
    • controllers/: flight, mission, parachute, emergency, sensors, actuators
    • sensors/: battery, GPS, IMU models
    • actuators/: parachute actuator
  • simulation/: Orchestration, logging, and interactive visualizer
    • simulator.py, flight_logger.py, visualizer.py
  • scrbe/: Reduced pipeline (static state), CLI, and docs
    • src/pipeline.py, run_simulation.py, config/scrbe_config.json
  • scrbe_fuzzer/: Fuzzer, harness, oracle, metrics, and visualization suite
    • run_fuzz.py, results/, visualize/**
  • config/: Simulation configs (drone, battery, gps, imu, physics, simulation)
  • missions/: Example mission JSONs
  • data/: Default full-simulation flight log (CSV)
  • tests/: Unit/integration tests

System architecture

The simulation system composes the simulator, the drone and its controllers/sensors/actuators, a message broker, and output components (logger and visualizer).

flowchart LR
  %% Styling
  classDef simulator fill:#d4f1f9,stroke:#05728f,stroke-width:1px,color:#05728f,rounded
  classDef logger fill:#d5e8d4,stroke:#82b366,stroke-width:1px,color:#3d602e,rounded
  classDef controller fill:#fff2cc,stroke:#d6b656,stroke-width:1px,color:#7d5f15,rounded
  classDef sensor fill:#e1d5e7,stroke:#9673a6,stroke-width:1px,color:#5e3973,rounded
  classDef actuator fill:#ffcccc,stroke:#cc6666,stroke-width:1px,color:#994c4c,rounded
  classDef drone fill:#f8cecc,stroke:#b85450,stroke-width:1px,color:#8a2b23,rounded
  classDef broker fill:#dae8fc,stroke:#6c8ebf,stroke-width:1px,color:#314b73,rounded
    
  %% Main components
  Simulator[Simulator]:::simulator
    
  subgraph OutputComponents["Output Components"]
    FlightLogger[Flight Logger]:::logger
    Visualizer[Visualizer]:::logger
  end
    
  subgraph DroneSystem["Drone System"]
    Drone[Drone]:::drone
        
    subgraph Controllers["Controllers"]
      MissionController[Mission Controller]:::controller
      FlightController[Flight Controller]:::controller
      SensorController[Sensor Controller]:::controller
      ActuatorController[Actuator Controller]:::controller
      ParachuteController[Parachute Controller]:::controller
      EmergencyController[Emergency Controller]:::controller
    end
        
    subgraph Sensors["Sensors"]
      GPS[GPS]:::sensor
      IMU[IMU]:::sensor
      Battery[Battery]:::sensor
    end
        
    subgraph Actuators["Actuators"]
      ParachuteActuator[Parachute Actuator]:::actuator
    end
        
    MessageBroker[Message Broker]:::broker
  end
    
  %% Connections
  Simulator --> Drone
  Simulator --> FlightLogger
  Simulator --> Visualizer
    
  Drone --> MissionController
  Drone --> FlightController
  Drone --> SensorController
  Drone --> ActuatorController
  Drone --> ParachuteController
  Drone --> EmergencyController
    
  SensorController --> GPS
  SensorController --> IMU
  SensorController --> Battery
    
  ParachuteController --> ParachuteActuator
    
  %% All components connect to message broker
  MessageBroker <--> Drone
  MessageBroker <--> MissionController
  MessageBroker <--> FlightController
  MessageBroker <--> SensorController
  MessageBroker <--> ActuatorController
  MessageBroker <--> ParachuteController
  MessageBroker <--> EmergencyController
  MessageBroker <--> FlightLogger
    
  %% Add description
  style OutputComponents fill:none,stroke:none
  style DroneSystem fill:none,stroke:none
  style Controllers fill:none,stroke:none
  style Sensors fill:none,stroke:none
  style Actuators fill:none,stroke:none
Loading

Code pointers:

Quick start (env, install, run)

The commands below assume macOS/Linux with zsh; adapt to your shell as needed.

# 1) Create and activate a virtual environment
python3 -m venv .venv
source .venv/bin/activate

# 2) Install base requirements (simulation + visualizer)
pip install -r requirements.txt

# 3) (Optional, for fuzzing) Install fuzzer extras
pip install -r scrbe_fuzzer/requirements.txt

Full simulation workflow

Run a mission end-to-end (physics + controllers + logging + interactive viz):

source .venv/bin/activate
python run_simulation.py --mission missions/sample_mission.json

Artifacts:

  • Flight log: data/flight_log.csv
  • Interactive plots open automatically at the end.

Visualize an existing log without re-running physics:

source .venv/bin/activate
python run_simulation.py --visualize-only --log-file data/flight_log.csv

SCRBE static pipeline

Run a reduced, static-state analysis at a fixed battery and altitude:

source .venv/bin/activate
python run_scrbe_simulation.py --battery 10.0 --altitude 70.0 --log

Outputs (example):

  • Message bus log: log/scrbe_run_YYYYMMDD_HHMMSS/message_bus.csv
  • Flight trace: scrbe/flight_record/scrbe_run_YYYYMMDD_HHMMSS.csv

The CLI validates inputs and config schema (scrbe/config/scrbe_config.json).

See also: scrbe/README.md and scrbe/docs/message_logging.md.

Fuzzer and visual analytics

The fuzzer explores battery/altitude and (optionally) controller parameters to falsify an STL safety property.

Run a bounded session and generate figures:

source .venv/bin/activate
python scrbe_fuzzer/run_fuzz.py --runs 20 --visual

Results go to a timestamped directory, e.g. scrbe_fuzzer/results/session_20251029_124816/:

  • violations.csv: tabular summary of runs
  • violations/: per-run JSONs for violations
  • summary.json: counts and rates
  • visual/: publication-ready figures (PNG/SVG)

Re-generate visuals for an existing session:

source .venv/bin/activate
python -m scrbe_fuzzer.visualize --input scrbe_fuzzer/results/session_20250421_002920/violations.csv

Example figure (state vs limits) from a real session:

State vs Limits

See also: scrbe_fuzzer/README.md and scrbe_fuzzer/visualize/README.md.

Data products and locations

  • Full simulation
    • data/flight_log.csv (wide CSV: state, targets, battery, modes)
  • SCRBE
    • log/<log_id>/message_bus.csv (origin, topic, payload)
    • scrbe/flight_record/<log_id>.csv (battery, altitude, mode, deployed flags)
  • Fuzzer
    • scrbe_fuzzer/results/session_*/violations.csv
    • scrbe_fuzzer/results/session_*/violations/*.json
    • scrbe_fuzzer/results/session_*/visual/*.png|*.svg

Tests and quality checks

source .venv/bin/activate
pytest -q

Key tests include sensors/physics/controller behavior and the intentional emergency-controller constraint.

Intentional bug: emergency deployment gated by altitude

There are two parachute deployment paths in this repository:

  1. Manual deploy via mission command
  • Trigger: mission action DEPLOY_PARACHUTE (or publishing to parachute/deploy).
  • Flow: MissionController → ParachuteController → ParachuteActuator.
  • Behavior: The actuator’s deploy() currently deploys at any altitude and does not enforce min_deploy_altitude/max_deploy_altitude (keys exist in config but aren’t checked in core/actuators/parachute_actuator.py).
  1. Emergency deploy on low battery (intentional flaw)
  • Trigger: Battery status becomes LOW at or below the configured threshold.
  • Flow: EmergencyController monitors battery and altitude; if LOW, it is supposed to deploy.
  • Intentional bug: The EmergencyController requires altitude ≥ min_deploy_altitude before publishing a deploy command, withholding deployment at low altitudes even in an emergency. See core/controllers/emergency_controller.py.

Property under test and expected violations

  • Intended safety property (used by the SCRBE checker and fuzzer): “If battery is low while airborne, deploy the parachute within Δ.”
  • Because of the intentional gating, runs where the battery becomes LOW below min_deploy_altitude will violate this property. The visualization suite highlights this region.

References and code pointers

Creating missions

Missions are JSON arrays of steps. Each step includes an action and, when relevant, a waypoint as [x, y, z] in meters.

Example:

[
  {"action": "TAKE_OFF", "waypoint": [0, 0, 10]},
  {"action": "GOTO",     "waypoint": [10, 0, 10]},
  {"action": "GOTO",     "waypoint": [10, 10, 10]},
  {"action": "LAND"}
]

Supported actions:

  • TAKE_OFF: ascend to the specified waypoint altitude (x/y used as target as well)
  • GOTO: move to the specified waypoint [x, y, z]
  • LAND: land at the current x/y position (z will be set to 0 internally)
  • DEPLOY_PARACHUTE: request parachute deployment at the current position

Notes:

  • Unknown actions are logged and skipped. See core/controllers/mission_controller.py for exact behavior.

For emergency deployment behavior, see Intentional bug: emergency deployment gated by altitude.

See also:

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages