Session 1: Introduction to ROS2
Learning Goals
In this session, you will gain a practical introduction to ROS2 by learning about nodes, publishers, and subscribers through a fun example. By the end of this tutorial, you will understand how to set up and use these fundamental ROS2 components, navigate the ROS file system, create a ROS workspace, and use the command line to inspect topics and messages.
Nodes: Fundamental entities in ROS2 that perform computation and communicate with each other.
Publishers: Nodes that send data to topics.
Subscribers: Nodes that receive data from topics.
Services: Provide a way for nodes to request and provide data on demand (synchronous communication).
Note: Actions are not covered in this workshop.
Here are some basic commands to help you use the terminal:
Basic Terminal Commands:
Open a terminal: Press Ctrl + Alt + T - This opens a new window where you can type commands.
Open a new tab: Press Ctrl + Shift + T - This adds a new tab to the terminal window.
Stop a running command: Press Ctrl + C - This stops whatever command is running.
Working with Folders and Files:
Go to a folder: Type cd <folder name> - This takes you to a different folder.
Create a new folder: Type mkdir <folder name> - This makes a new folder.
Delete a file: Type rm <file name> - This erases a file forever, so be careful!
Copy a file: Type cp <file name> <new place> - This makes a copy of a file.
Delete a folder and everything in it: Type rm -rf <folder name> - This removes a folder and all its files.
Copy a folder and everything in it: Type cp -r <folder name> <new place> - This makes a copy of a folder and all its files.
Move or rename a file: Type mv <file name> <new place or new name> - This moves a file to a new spot or changes its name.
Opening Your Workspace
To open and work with your ROS2 workspace, use the command:
Open your workspace in Visual Studio Code: ‘code ~/ros2_ws’
This command opens the ~/ros2_ws directory in Visual Studio Code, in which you can easily see and edit your files. It’s a helpful way to manage your workspace without needing to use all the terminal commands.
Workspace Setup
Your ROS2 workspace is already set up for you. It is named ‘ros2_ws’ and includes: - A package named ‘my_package’ - A node named ‘my_node’
Building Your Package
To build your ROS2 package, use the command:
Build with Colcon:
cd ~/ros2_ws && colcon build --symlink-install
This command compiles your code and prepares everything to run.
ROS2 Node Communication
The following diagram visualizes how nodes interact through topics and services in ROS2:
Node: Imagine a node as a character in a game. Each node can do different things, like listening, talking, or asking for help.
Topic: Think of a topic as a chat room where characters (nodes) can talk to each other. Some nodes send messages (like “The car is moving!”), and others listen to those messages.
Publisher: This is the node that talks in the chat room. It shares messages for others to hear.
Subscriber: This is the node that listens to the chat room. It hears the messages that the publisher is sharing.
Service: Sometimes, one node might need help from another, like asking for directions. The service is like a special request that a node makes to another.
Service Client: This is the node that asks for help or makes the request.
Service Server: This is the node that receives the request and responds with the help needed.
So, the nodes can either chat with each other through topics or ask for special help through services!
Chatter Example
In this example, you’ll create a simple “chatter” application that demonstrates how nodes, publishers, subscribers, and services work together in ROS2.
Create a ROS2 Package: A package called ‘my_package’ is already created for you. It contains a node named ‘my_node’. It is created using the command:
cd ~/ros2_ws/src && ros2 pkg create my_package --build-type ament_python --node-name my_node
Write a Publisher Node: Implement a Python node that publishes messages to a topic:
code ~/ros2_ws In Visual Studio Code, open the 'my_node' file in the 'my_package' package. Replace the contents with the following Python code::
import rclpy
from std_msgs.msg import String
from time import sleep
def main(args=None):
rclpy.init(args=args)
node = rclpy.create_node('my_node')
publisher = node.create_publisher(String, 'chatter', 1)
msg = String()
msg.data = 'Hello, ROS2!'
while rclpy.ok():
node.get_logger().info('Publishing: "%s"' % msg.data)
publisher.publish(msg)
rclpy.spin_once(node)
sleep(1)
node.destroy_node()
rclpy.shutdown()
if __name__ == '__main__':
main()
Note: This code publishes a message ‘Hello, ROS2!’ to the ‘chatter’ topic every second.
But, this code will not work until you build the package. *
Build the Package: Compile the package using the command:
cd ~/ros2_ws && colcon build --symlink-install
Let ROS2 Discover Your Node: Source the ROS2 workspace to let ROS2 discover your node:
source ~/ros2_ws/install/setup.bash
The python node can be run using the following command in Terminal:
ros2 run my_package my_node
Inspect the Node: Check if the node is running using the command:
ros2 node list
Inspect the Topic: Check the topic being published to using the command:
ros2 topic list
Inspect the Message: Check the message being published using the command:
ros2 topic echo /chatter
Node using Python class: You can also create a node using a Python class. Here’s an example:
import rclpy
from std_msgs.msg import String
from rclpy.node import Node
class MyNode(Node):
def __init__(self):
super().__init__('my_node')
self.publisher_ = self.create_publisher(String, 'chatter', 1)
timer_period = 1
self.timer = self.create_timer(timer_period, self.timer_callback)
def timer_callback(self):
msg = String()
msg.data = 'Hello, ROS2!'
self.get_logger().info('Publishing: "%s"' % msg.data)
self.publisher_.publish(msg)
def main(args=None):
rclpy.init(args=args)
node = MyNode()
rclpy.spin(node)
rclpy.shutdown()
if __name__ == '__main__':
main()
Explanation
Create a Node:
class MyNode(Node): def __init__(self): super().__init__('my_node')
The code creates a class called
MyNodethat sets up a ROS2 node namedmy_node.Create a Publisher:
self.publisher_ = self.create_publisher(String, 'chatter', 1)
Inside the constructor, a publisher is created to send messages of type
Stringto thechattertopic. This allows other nodes to receive messages sent to this topic.Set up a Timer:
timer_period = 1 self.timer = self.create_timer(timer_period, self.timer_callback)
A timer is set up to call the
timer_callbackfunction every second (1 second). This helps in periodically sending messages.Define the Timer Callback:
def timer_callback(self): msg = String() msg.data = 'Hello, ROS2!' self.get_logger().info('Publishing: "%s"' % msg.data) self.publisher_.publish(msg)
The
timer_callbackfunction creates a message with the text'Hello, ROS2!', logs it, and publishes it to thechattertopic.Main Function:
def main(args=None): rclpy.init(args=args) node = MyNode() rclpy.spin(node) rclpy.shutdown()
The
mainfunction initializes ROS2, creates an instance ofMyNode, starts spinning (to keep the node active and responsive), and shuts down ROS2 when done.
Note: It is important to understand the difference between the two methods of creating a node. Python class method is more object-oriented and allows for better organization of code.
Challenge Activity:
The instructor will subscribe to a topic called ‘/text’ with ROS domain ID ‘123’ using:
export ROS_DOMAIN_ID=123
Students need to race to publish a string message to this topic.
Make sure to use different ROS domain IDs to avoid interfering with each other’s ROS2 nodes in upcoming sessions.
For detailed instructions, refer to these tutorials: