How to Use ROS2 with Drone: Simple Guide for Beginners
To use
ROS2 with a drone, install ROS2 on your control computer and the drone's onboard computer, then create ROS2 nodes to communicate commands and telemetry. Use ros2 topics and services to send flight commands and receive sensor data, enabling autonomous or remote control.Syntax
Using ROS2 with a drone involves creating ROS2 nodes that publish and subscribe to topics for commands and telemetry. You use rclpy (Python) or rclcpp (C++) libraries to write these nodes.
- Node: A program that communicates in ROS2.
- Publisher: Sends messages (e.g., flight commands).
- Subscriber: Receives messages (e.g., sensor data).
- Topic: Named channel for messages.
python
import rclpy from rclpy.node import Node from std_msgs.msg import String class DroneCommandPublisher(Node): def __init__(self): super().__init__('drone_command_publisher') self.publisher_ = self.create_publisher(String, 'drone/command', 10) timer_period = 1 # seconds self.timer = self.create_timer(timer_period, self.timer_callback) def timer_callback(self): msg = String() msg.data = 'takeoff' self.publisher_.publish(msg) self.get_logger().info('Publishing: "%s"' % msg.data) def main(args=None): rclpy.init(args=args) drone_command_publisher = DroneCommandPublisher() rclpy.spin(drone_command_publisher) drone_command_publisher.destroy_node() rclpy.shutdown()
Example
This example shows a simple ROS2 Python node that publishes a "takeoff" command to the drone every second. The drone should have a subscriber node listening to the drone/command topic to act on these commands.
python
import rclpy from rclpy.node import Node from std_msgs.msg import String class DroneCommandPublisher(Node): def __init__(self): super().__init__('drone_command_publisher') self.publisher_ = self.create_publisher(String, 'drone/command', 10) timer_period = 1 # seconds self.timer = self.create_timer(timer_period, self.timer_callback) def timer_callback(self): msg = String() msg.data = 'takeoff' self.publisher_.publish(msg) self.get_logger().info('Publishing: "%s"' % msg.data) def main(args=None): rclpy.init(args=args) drone_command_publisher = DroneCommandPublisher() rclpy.spin(drone_command_publisher) drone_command_publisher.destroy_node() rclpy.shutdown() if __name__ == '__main__': main()
Output
[INFO] [drone_command_publisher]: Publishing: "takeoff"
[INFO] [drone_command_publisher]: Publishing: "takeoff"
[INFO] [drone_command_publisher]: Publishing: "takeoff"
... (repeats every second)
Common Pitfalls
Common mistakes when using ROS2 with drones include:
- Not matching topic names exactly between publisher and subscriber.
- Forgetting to initialize ROS2 with
rclpy.init()before creating nodes. - Not spinning the node with
rclpy.spin(), which stops callbacks from running. - Ignoring network setup if drone and control computer are on different machines.
- Using incompatible message types between nodes.
Always test communication with simple messages before adding complex flight logic.
python
## Wrong: Missing rclpy.spin() stops callbacks import rclpy from rclpy.node import Node from std_msgs.msg import String class Publisher(Node): def __init__(self): super().__init__('publisher') self.pub = self.create_publisher(String, 'topic', 10) self.timer = self.create_timer(1, self.timer_callback) def timer_callback(self): msg = String() msg.data = 'hello' self.pub.publish(msg) self.get_logger().info('Published: %s' % msg.data) rclpy.init() node = Publisher() # Missing rclpy.spin(node) here means timer_callback never runs rclpy.shutdown() ## Right: Add spin to keep node alive rclpy.init() node = Publisher() rclpy.spin(node) rclpy.shutdown()
Quick Reference
Here is a quick cheat sheet for using ROS2 with drones:
| Concept | Description | Example |
|---|---|---|
| Node | A program that sends or receives messages | DroneCommandPublisher |
| Publisher | Sends messages on a topic | create_publisher(String, 'drone/command', 10) |
| Subscriber | Receives messages from a topic | create_subscription(String, 'drone/command', callback, 10) |
| Topic | Named channel for messages | 'drone/command' |
| Message | Data sent between nodes | std_msgs.msg.String |
| Spin | Keeps node running to process callbacks | rclpy.spin(node) |
| Init/Shutdown | Start and stop ROS2 client library | rclpy.init(), rclpy.shutdown() |
Key Takeaways
Install ROS2 on both drone and control computer to enable communication.
Use ROS2 nodes with publishers and subscribers to send commands and receive data.
Always initialize ROS2 and spin nodes to keep communication active.
Match topic names and message types exactly between nodes.
Test with simple messages before adding complex drone control logic.