Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/PX4/PX4-Autopilot/llms.txt

Use this file to discover all available pages before exploring further.

A PX4 module is a self-contained software component that runs as an independent task or a work queue item. Each module has a defined responsibility — a single module estimates attitude, another manages mission execution, another handles MAVLink communication — and modules interact exclusively through uORB topics. This strict separation makes it possible to start, stop, replace, or debug any module independently without affecting the rest of the system.

Module execution model

Modules run in one of two execution contexts:
  • Independent task — has its own stack and OS scheduling priority. Can sleep, block on I/O, and perform long-running computation. Visible in top output.
  • Work queue task — shares a stack with other items on the same work queue. Must not block or sleep; scheduled by time interval or uORB topic update callback. Consumes less RAM and produces fewer context switches. Not visible in top; use work_queue status instead.
Most flight-critical modules (e.g., ekf2, mc_att_control) run as independent tasks with elevated priority. Lower-frequency management tasks often run on work queues.

Core module reference

ModuleCategoryRole
commanderSystemVehicle state machine, arming/disarming, failsafe logic, mode management, calibration
navigatorControllerAutonomous mission execution, holds, return-to-launch, geofence enforcement
mc_pos_controlControllerMulticopter position and velocity control; outputs attitude and thrust setpoints
mc_att_controlControllerMulticopter attitude and rate control; outputs actuator torque commands
fw_pos_controlControllerFixed-wing position, altitude, and airspeed control
vtol_att_controlControllerVTOL transition logic and attitude control blending
ekf2EstimatorExtended Kalman Filter fusing IMU, GPS, baro, mag, optical flow; produces state estimates
sensorsSystemAggregates and calibrates sensor data; publishes sensor_combined
mavlinkCommunicationMAVLink telemetry, commands, parameters, and missions over UDP/serial
uxrce_dds_clientCommunicationBridges uORB topics to ROS 2 via Micro XRCE-DDS
loggerSystemHigh-rate ULog data recorder to SD card
land_detectorSystemDetects landed state; gates arming and triggers failsafes
control_allocatorControllerMaps body force/torque demands to individual actuator commands (mixing)
battery_statusSystemMonitors battery voltage/current and publishes state-of-charge estimates

Starting and stopping modules

You control modules from the NuttX shell (via serial or MAVLink shell) or from the SITL pxh> prompt.
# Start a module (with optional arguments)
ekf2 start
mavlink start -d /dev/ttyS1 -b 57600

# Stop a module
ekf2 stop

# Check if a module is running and print its status
commander status
sensors status

# List all running tasks and their CPU/stack usage
top

# List all active work queue items
work_queue status

# Inspect uORB topic rates in real time
uorb top
In SITL, the pxh> shell is available directly in the terminal. On hardware, access the NSH shell through a serial debug adapter or the MAVLink shell built into QGroundControl (Analyze Tools → MAVLink Console).
Modules that run on a work queue (rather than as independent tasks) do not appear in top. Look for entries like wq:lp_default in top output, then run work_queue status to see which modules are scheduled on it.

The commander module

commander is the vehicle’s central state machine. It arbitrates:
  • Arming and disarming — checks all health and arming conditions before permitting arm.
  • Flight mode transitions — translates RC switch positions, MAVLink commands, and offboard requests into navigation states.
  • Failsafe logic — monitors link loss, battery level, geofence violations, and sensor failures, then triggers the appropriate failsafe action.
  • Calibration routines — manages accelerometer, gyroscope, magnetometer, barometer, RC, and ESC calibration sequences.
The commander module directory (src/modules/commander/) contains separate compilation units for each major responsibility:
Commander.cpp / Commander.hpp     — Main state machine loop
ModeManagement.cpp                — External and internal mode arbitration
Safety.cpp                        — Safety switch and kill switch handling
HomePosition.cpp                  — Home position management
failsafe/                         — Failsafe state machine
HealthAndArmingChecks/            — Modular pre-arm check framework
Arming/                           — Arming/disarming sequencing

The module.yaml descriptor

Every module that exposes parameters or has configurable behavior provides a module.yaml file alongside its source code. The build system reads these files to auto-generate parameter documentation and the module’s command-line help text. A minimal module.yaml looks like this:
module_name: MyModule

parameters:
  - group: MyModule
    definitions:
      MYM_ENABLE:
        description:
          short: Enable my module feature
          long: |
            When set to 1, the module activates the experimental
            feature. Set to 0 to disable.
        type: boolean
        default: 0

      MYM_GAIN:
        description:
          short: Control gain for my module
          long: Proportional gain applied to the error signal.
        type: float
        unit: ''
        min: 0.0
        max: 10.0
        decimal: 2
        increment: 0.1
        default: 1.0

Supported parameter types

TypeDescription
boolean0 or 1
int3232-bit signed integer
float32-bit float
enumInteger with named values
bitmaskInteger interpreted as bit flags

Enum and bitmask parameters

COM_FLTMODE1:
  description:
    short: Mode slot 1
    long: |
      If the main switch channel is in this range the
      selected flight mode will be applied.
  type: enum
  values:
    -1: Unassigned
    0: Manual
    1: Altitude
    2: Position
    3: Mission
    4: Hold
    5: Return
  default: -1

Writing a new module

1

Create the module directory

Add a new directory under src/modules/ (or src/drivers/ for a hardware driver). Your directory needs at minimum:
src/modules/my_module/
├── CMakeLists.txt
├── module.yaml
├── MyModule.cpp
└── MyModule.hpp
2

Define the CMakeLists.txt

Register your module with the PX4 build system and declare its source files and uORB dependencies:
px4_add_module(
  MODULE modules__my_module
  MAIN my_module
  COMPILE_FLAGS
    -O2
  SRCS
    MyModule.cpp
  DEPENDS
    px4_work_queue
)
3

Implement the module class

Subclass ModuleBase and ModuleParams. Override task_spawn, run, and print_status:
#include <px4_platform_common/module.h>
#include <px4_platform_common/module_params.h>
#include <uORB/Subscription.hpp>
#include <uORB/topics/vehicle_local_position.h>

class MyModule : public ModuleBase<MyModule>, public ModuleParams
{
public:
    MyModule() : ModuleParams(nullptr) {}

    static int task_spawn(int argc, char *argv[]);
    static int custom_command(int argc, char *argv[]);
    static int print_usage(const char *reason = nullptr);

    void run() override;

private:
    uORB::Subscription _local_pos_sub{ORB_ID(vehicle_local_position)};
};
4

Add to a board configuration

Add modules/my_module to the relevant boards/<vendor>/<board>/default.px4board configuration file so the module is included in the firmware build for your target.
Modules that run on a work queue must never call sleep(), usleep(), or any blocking I/O function. Blocking inside a work queue item stalls all other items on the same queue. If your module needs to sleep or block, run it as an independent task instead.

Build docs developers (and LLMs) love