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:

ROS2 Node Communication Diagram
  • 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.

  1. 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
    
  2. 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. *

  1. Build the Package: Compile the package using the command:

    cd ~/ros2_ws && colcon build --symlink-install
    
  2. Let ROS2 Discover Your Node: Source the ROS2 workspace to let ROS2 discover your node:

    source ~/ros2_ws/install/setup.bash
    
  3. The python node can be run using the following command in Terminal:

    ros2 run my_package my_node
    
  4. Inspect the Node: Check if the node is running using the command:

    ros2 node list
    
  5. Inspect the Topic: Check the topic being published to using the command:

    ros2 topic list
    
  6. Inspect the Message: Check the message being published using the command:

    ros2 topic echo /chatter
    
  7. 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

  1. Create a Node:

    class MyNode(Node):
        def __init__(self):
            super().__init__('my_node')
    

    The code creates a class called MyNode that sets up a ROS2 node named my_node.

  2. Create a Publisher:

    self.publisher_ = self.create_publisher(String, 'chatter', 1)
    

    Inside the constructor, a publisher is created to send messages of type String to the chatter topic. This allows other nodes to receive messages sent to this topic.

  3. 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_callback function every second (1 second). This helps in periodically sending messages.

  4. 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_callback function creates a message with the text 'Hello, ROS2!', logs it, and publishes it to the chatter topic.

  5. Main Function:

    def main(args=None):
        rclpy.init(args=args)
        node = MyNode()
        rclpy.spin(node)
        rclpy.shutdown()
    

    The main function initializes ROS2, creates an instance of MyNode, 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: