0
0
Pcb-designHow-ToIntermediate · 4 min read

How to Control Drone Using PX4 Offboard Mode

To control a drone using PX4 offboard mode, you send position, velocity, or attitude setpoints from an external computer or companion computer to the flight controller via MAVLink. You must first enable offboard mode, then continuously stream commands at a steady rate to maintain control.
📐

Syntax

In PX4 offboard mode, you typically send commands using MAVLink messages such as SET_POSITION_TARGET_LOCAL_NED or SET_ATTITUDE_TARGET. The main steps are:

  • Enable offboard mode: Switch the drone's flight mode to offboard.
  • Send setpoints: Continuously send position, velocity, or attitude targets.
  • Maintain rate: Commands must be sent at about 10 Hz or faster to keep control.
c
mavlink_message_t msg;

// Example: Set position target in local NED frame
mavlink_set_position_target_local_ned_t sp;
sp.time_boot_ms = current_time_ms();
sp.coordinate_frame = MAV_FRAME_LOCAL_NED;
sp.type_mask = POSITION_TARGET_TYPEMASK_VX_IGNORE | POSITION_TARGET_TYPEMASK_VY_IGNORE | POSITION_TARGET_TYPEMASK_VZ_IGNORE;
sp.x = 0; // desired x position in meters
sp.y = 0; // desired y position in meters
sp.z = -5; // desired altitude (negative down)

mavlink_msg_set_position_target_local_ned_encode(system_id, component_id, &msg, &sp);
send_mavlink_message(&msg);
💻

Example

This example shows how to control a PX4 drone in offboard mode using Python and the pymavlink library. It connects to the drone, switches to offboard mode, and sends position setpoints to hover at 5 meters altitude.

python
from pymavlink import mavutil
import time

# Connect to the drone
master = mavutil.mavlink_connection('udp:127.0.0.1:14540')
master.wait_heartbeat()
print('Heartbeat from system (system %u component %u)' % (master.target_system, master.target_component))

# Function to send position setpoint

def send_position_setpoint(x, y, z):
    master.mav.set_position_target_local_ned_send(
        int(time.time() * 1000),
        master.target_system,
        master.target_component,
        mavutil.mavlink.MAV_FRAME_LOCAL_NED,
        0b0000111111000111,  # ignore velocity, acceleration, yaw
        x, y, z,  # position
        0, 0, 0,  # velocity
        0, 0, 0,  # acceleration
        0, 0)     # yaw, yaw_rate

# Set mode to OFFBOARD
master.set_mode_offboard()

# Arm the drone
master.arducopter_arm()

# Send setpoints at 10 Hz for 10 seconds
start = time.time()
while time.time() - start < 10:
    send_position_setpoint(0, 0, -5)  # hover 5 meters above ground
    time.sleep(0.1)

# Disarm after
master.arducopter_disarm()
Output
Heartbeat from system (system 1 component 1) Mode set to OFFBOARD Armed Sending position setpoints... Disarmed
⚠️

Common Pitfalls

  • Not sending setpoints fast enough: PX4 requires continuous setpoints at ~10 Hz; otherwise, it exits offboard mode.
  • Forgetting to arm the drone: Offboard mode requires the drone to be armed to move.
  • Incorrect coordinate frames: Use the correct MAV_FRAME (usually LOCAL_NED) for position commands.
  • Not switching to offboard mode: You must explicitly set the flight mode to offboard before sending commands.
c
/* Wrong: Sending one setpoint and stopping */
send_position_setpoint(0, 0, -5);
// No further commands sent, drone will exit offboard mode

/* Right: Continuously sending setpoints */
while (true) {
  send_position_setpoint(0, 0, -5);
  sleep(100); // 10 Hz
}
📊

Quick Reference

  • Enable offboard mode: Set flight mode to OFFBOARD.
  • Arm drone: Arm before sending commands.
  • Send setpoints: Use SET_POSITION_TARGET_LOCAL_NED or similar MAVLink messages.
  • Maintain rate: Send commands at 10 Hz or faster.
  • Coordinate frame: Use LOCAL_NED for position control.

Key Takeaways

Enable offboard mode and arm the drone before sending commands.
Continuously send position or velocity setpoints at 10 Hz to maintain control.
Use the correct MAVLink messages and coordinate frames (usually LOCAL_NED).
Failing to send setpoints regularly causes PX4 to exit offboard mode.
Test commands in simulation before flying a real drone for safety.