How to Use MAVROS for Drone Control: Basic Guide
To use
mavros for drone control, first install and launch the mavros node to connect to your drone's autopilot. Then, publish commands to topics like /mavros/setpoint_position/local to control movement and subscribe to telemetry topics for feedback.Syntax
The basic syntax to use mavros involves launching the mavros node with connection parameters and then publishing or subscribing to ROS topics for control and telemetry.
roslaunch mavros px4.launch fcu_url:=udp://:14540@: Launches MAVROS connecting to the drone autopilot via UDP./mavros/setpoint_position/local: Topic to publish position commands./mavros/state: Topic to subscribe to drone state information./mavros/cmd/arming: Service to arm or disarm the drone./mavros/set_mode: Service to change flight modes.
bash
roslaunch mavros px4.launch fcu_url:=udp://:14540@ # Publish position commands to /mavros/setpoint_position/local # Subscribe to /mavros/state for drone status # Use /mavros/cmd/arming service to arm/disarm # Use /mavros/set_mode service to change flight mode
Example
This example shows how to arm the drone, set it to OFFBOARD mode, and send a position command to move it to a point 2 meters above the starting position.
python
import rospy from mavros_msgs.msg import State from mavros_msgs.srv import CommandBool, SetMode from geometry_msgs.msg import PoseStamped current_state = None def state_cb(msg): global current_state current_state = msg rospy.init_node('offboard_control') state_sub = rospy.Subscriber('mavros/state', State, state_cb) local_pos_pub = rospy.Publisher('mavros/setpoint_position/local', PoseStamped, queue_size=10) rospy.wait_for_service('mavros/cmd/arming') rospy.wait_for_service('mavros/set_mode') arm_service = rospy.ServiceProxy('mavros/cmd/arming', CommandBool) mode_service = rospy.ServiceProxy('mavros/set_mode', SetMode) pose = PoseStamped() pose.pose.position.x = 0 pose.pose.position.y = 0 pose.pose.position.z = 2 rate = rospy.Rate(20) # Wait for connection while not rospy.is_shutdown() and (current_state is None or not current_state.connected): rate.sleep() # Send a few setpoints before starting for i in range(100): local_pos_pub.publish(pose) rate.sleep() # Set mode to OFFBOARD mode_service(base_mode=0, custom_mode='OFFBOARD') # Arm the drone arm_service(True) while not rospy.is_shutdown(): local_pos_pub.publish(pose) rate.sleep()
Output
No direct output; drone moves to position (0,0,2) meters and stays there in OFFBOARD mode.
Common Pitfalls
- Not sending setpoints before switching to OFFBOARD mode: The autopilot requires a stream of setpoints before allowing OFFBOARD mode.
- Forgetting to arm the drone: Commands won't take effect if the drone is not armed.
- Incorrect connection URL: Ensure the
fcu_urlmatches your drone's communication method (UDP, serial, etc.). - Ignoring state feedback: Always check
/mavros/stateto confirm connection and mode changes.
python
## Wrong way: Switching to OFFBOARD mode without sending setpoints mode_service(base_mode=0, custom_mode='OFFBOARD') ## Right way: Send setpoints first for i in range(100): local_pos_pub.publish(pose) rate.sleep() mode_service(base_mode=0, custom_mode='OFFBOARD')
Quick Reference
| Command | Description |
|---|---|
| roslaunch mavros px4.launch fcu_url:=udp://:14540@ | Launch MAVROS and connect to drone autopilot |
| Publish to /mavros/setpoint_position/local | Send position commands to control drone movement |
| Subscribe to /mavros/state | Monitor drone connection and mode status |
| Call /mavros/cmd/arming service | Arm or disarm the drone |
| Call /mavros/set_mode service | Change the drone's flight mode (e.g., OFFBOARD, MANUAL) |
Key Takeaways
Always launch MAVROS with the correct connection URL to your drone autopilot.
Send a stream of setpoints before switching to OFFBOARD mode to enable external control.
Use the arming service to arm the drone before sending movement commands.
Monitor the drone state topic to confirm connection and mode changes.
Test commands in a safe environment to avoid unexpected drone behavior.