ROS2 Tutorial

Aus HSHL Mechatronik
Zur Navigation springen Zur Suche springen

ROS2 Tutorial

Introduction

The Robot Operating System (ROS) is a set of software libraries and tools for building robot applications. ROS2 has different packages for setting up programmes. Usually in ROS you can create packages in CPP and Python. Here we are focused in creating in packages in Python. A python package contain different files like package.xml - which contains the meta-information, setup.py - which contains the instruction set for the package to how to compile it, </package_name – which contains all the python scripts and this directory have always the same name as the package.

For creating a ROS package, it is necessary to operate in a specific workspace called ROS2 workspace. The directory on your hard drive where your ROS2 packages are stored and accessible by ROS2 is known as the ROS2 workspace. The ROS2 workspace directory is typically referred to as ros2_ws.

For create a package, you need to work specifically in ROS2^workspace. The directory on your hard drive where your ROS2 packages are stored and accessible by ROS2 is known as the ROS2 workspace. The ROS2 workspace directory is typically referred to as ros2_ws

First, source ROS2 in your terminal to use the ROS2 command-line tools

 source /opt/ros/foxy/setup.bash

Now, go to the ros2_ws

 cd ~/ros2_ws/

Inside this workspace, make a directory called src. This folder used to create all the packages needed. You must be in this directory each time you wish to create a package. ros2_ws/src. You are now prepared to design your own package at this point! Enter the next command into your terminal to do that:

 ros2 pkg create --build-type ament_python my_package --dependencies rclpy
 It is in the format
 ros2 pkg create --build-type ament_python <package_name> --dependencies <package_dependencies>

When you need to compile a package for it make to work. The command which can be used by ROS2 to compile is the following:

 colcon build 


This command, which must be executed in the ros2 ws directory for it to function, will compile your whole src directory.

Use various ROS package-related commands to verify that your package has been produced properly. For example, type the next:

 ros2 pkg list


 ros2 pkg list | grep my_package

Create a Python file named simple.py in the my_package directory which we created, which is inside the my_package package

so the location of the file will be:

 ros2_ws/src/my_package/my_package/simple.py

Now copy the following code given bellow:

 import rclpy
 # import the Node module from ROS2 Python library
 from rclpy.node import Node
 
 class MyNode(Node):
     def __init__(self):
         #call super() in the constructor to initialize the Node object
         # the parameter we pass is the node name
         super().__init__('Byakugan')
         # create a timer sending two parameters:
         # - the duration between two callbacks (0.2 seconds)
         # - the timer function (timer_callback)
         self.create_timer(0.2, self.timer_callback)
 
     def timer_callback(self):
         # print a ROS2 log on the terminal with a great message!
         self.get_logger().info("This is a test programm")
 
 def main(args=None):
     # initialize the ROS communication
     rclpy.init(args=args)
     # declare the node constructor
     node = MyNode()
     # keeps the node alive, waits for a request to kill the node (ctrl+c)
     rclpy.spin(node)
     # shutdown the ROS2 communication
     rclpy.shutdown()
 
 
 if __name__ == '__main__':
     main() #call the main function

Now we need to create the launch file to launch the program. For that follow the step belw:

Create a launch directory inside the package my_package

 cd ~/ros2_ws/src/my_package
 mkdir launch

Create a new launch file inside the launch directory.

 cd ~/ros2_ws/src/my_package/launch
 touch my_package_launch_file.launch.py
 chmod +x my_package_launch_file.launch.py

Now copy the code below in the launch file

 from launch import LaunchDescription
 from launch_ros.actions import Node
 
 def generate_launch_description():
     return LaunchDescription([
         Node(
             package='my_package',
             executable='simple_node',
             output='screen'),
     ])

Modify the setup.py file to the code given below in order to generate an executable from the Python file

 from setuptools import setup
 import os
 from glob import glob
 
 package_name = 'my_package'
 
 setup(
     name=package_name,
     version='0.0.0',
     packages=[package_name],
     data_files=[
         ('share/ament_index/resource_index/packages',
             ['resource/' + package_name]),
         ('share/' + package_name, ['package.xml']),
         (os.path.join('share', package_name), glob('launch/*.launch.py'))
     ],
     install_requires=['setuptools'],
     zip_safe=True,
     maintainer='ros-hshl',
     maintainer_email='ros-hshl@todo.todo',
     description='TODO: Package description',
     license='TODO: License declaration',
     tests_require=['pytest'],
     entry_points={
         'console_scripts': [
             'simple_node = my_package.simple:main'
         ],
     },
 )

Compile the package file as was previously explained

 cd ~/ros2_ws
 colcon build
 source ~/ros2_ws/install/setup.bash

then as a last steup, you need to launch the launch file by running the following:

 ros2 launch my_package my_package_launch_file.launch.py

ROS2 Nodes

Each node in ROS2 should be in charge of a specific module, such as one node for managing wheel motors, another for managing a laser rangefinder, etc. Different channels are available for each node's communication with other nodes

Abb.11 Communication between nodes


Source: here

In essence, ROS nodes are ROS programs. Use the ROS2 command to get a list of all the nodes active on a system:


> ros2 node list <


ROS client libraries enable communication between nodes created in different programming languages. Various ROS APIs require standard functionality, which is implemented by a core ROS client library (RCL). Writing client libraries for different languages is now simpler.

Basic Topic commands

There are different commands in ROS2 for various operations. The command ros2 topic list will prints a list which contains all the available Topics. The interface is divided into following groups.

Messages: This can be found as .msg files. The fields of a ROS communication are described in these straightforward text files. They can be utilized to create message source code. Services: which can be found as .srv files. A request and a response are the two pieces that make them up. Both are known as message deceleration.

Actions: Which Can be found as .action files. It contains three parts: a goal, a result, and feedback. All of these part contains a message declaration.

The .msg files and the msg/ directory of a ROS package are the two places where you can look for the descriptions and definitions for messages, respectively. The fields and constants sections make up the.msg files. The official ROS 2 documentation provide more details on this. You can read more about it here: ROS 2 documentation.

For publish a message to a topic, the ros2 topic pub command is used. The command structure is in the format as follows:


> ros2 topic pub <topic_name> <interface_name> <message> <


Topic Publisher: A topic is a place where knowledge can be read or written. A Publisher can now be described as a node that writes data into a Topic.

Custom Interface: Utilizing the interfaces that ROS2 already offers is always advised. Keep in mind that the ros2 interface list command can be used to view all ROS2 accessible interfaces. If none of them do, you can make a new one to suit your needs.

• Make a directory named msg inside your package

• Make a file called name_of_your_message.msg in this directory

• Change the CMakeLists.txt file

• Modifypackage.xml file

• Compile and source

• Use in your node

Service in ROS2

Services are a similar means of communication between nodes in ROS2 like topics. The publisher-subscriber model is used in Topics. And in services use a call-response type model. You can subscribe a node to a topic to receive specific information with ongoing updates, like you saw. However, a Service only offers data when specifically requested by a Client.

The structure of the command to call a Service (send a request) is as follows:


> ros2 service call <service_name> <service_type> <value> <


One example for this as follows:


> ros2 service type /moving <

Service Client

In order to create a service client, you need to create two nodes to request and respond to data through a service. Then you have to add their dependencies and executables to the package configuration files so that it is possible to build and run them. Which makes the service/client system works. Synchronous vs. Asynchronous Service Clients in ROS2

There are two types of calls a Service Client can make: Asychnronos calls and Sychnronous calls. You can use an asynchronous call using the call_async() method. An asynchronous client will instantly return future after sending a request to a service, which is a value that indicates whether the call and response have finished. The returned future can be requested for a response at any moment. An asynchronous client does not block anything when it sends a request. Then, for example, you could do a spin function and a feature check in the same thread. Asynchronous calls are completely secure and are advised for calling Services since they can be made from any location without interfering with other ROS2 activities. When sending a request, a synchronous client will pause the calling thread until the server has responded. After that, nothing else during the call can occur on that thread. The major issue is that you don't know how long it will take for the call thread to finish. This might result in a deadlock, which is the indefinite blocking of a group of concurrent system threads that are vying for communication.

Service Server

Keep in mind that you can use Services to make the nodes communicate. The node that sends a request to a service was designated as Client by the user. The Server node will be the node on the other side that responds to that request.


Custom Service Interface

To create a new Service type (srv), follow the steps below:

1. Create a directory named srv inside your package

2. Inside this directory, create a file z

3. Modify CMakeLists.txt file

4. Modify package.xml file

5. Compile and source

6. Use in code


Action in ROS2

Services and actions are pretty similar. When you use an Action, you are using a node's provided capability. Additionally, just like with services, actions are built on a client-server model. There are, however, two key distinctions between actions and services. First one is that, Actions are preemptable. This implies that you have the option to stop an Action in the middle of execution. And the other different is that actions always provides a feedback. This implies that the Server may provide feedback to the Client whilst the Action is being carried out.

Abb.11


Source: here

The Action Server must be present on the node that offers the Action feature. Other nodes are able to use that Action capabilities by calling the Action Server. An Action Client must be present in the node that calls the Action capability. A node can connect to the Action Server of another node via the Action Client. In summary, the workflow is as follows:

• A goal is sent from the Client to the Server. This will cause the Action to "start."

• While the Action is occurring, the server notifies the client with a feedback

• The Server responds to the Client after the Action is complete.

More information is given here: ROS2 Documentation


Calling an Action Server

Sending a goal to an action server constitutes calling it. It all operates by transmitting messages back and forth, just as Topics and Services. The message of a Topic is made up of a sole component, which is the information that the Topic provides. The request and the response are both included in a service's message. The aim, the outcome, and the feedback are the three components that make up an Action Server's message.

Creating Action Interface

• The first step is to make an Action directory in your custom_interface package.

• Create your <interface_name>.action Action Interface file.

The classes that will be utilized in the Action Server and/or Action Client will initially have names based on the name of the Action Interface file. According to ROS2 convention, the name must be in camel case. Remember that the Action Interface file has to contain three parts, each separated by three hyphens.


#goal
message_type goal_var_name
---
#result
message_type result_var_name
---
#feedback
message_type feedback_var_name

Move.action

int32 secs
---
string status
---
string feedback

then, make the necessary changes to CMakeLists.txt and package.xml files to add action interface compilation.

ROS2 Debugging Tools

RVIZ is one of the debugging tool used in ROS. You can view images, pointclouds, lasers, kinematic transformations, robot models, and other visualizations using RVIZ. The list is endless. You may even design your own markings. It's one of the factors contributing to ROS's popularity. Before RVIZ, it was difficult to decipher what the robot was viewing. RVIZ is a representation of what a simulation or actual robot is publishing in the topics.