Overview and the most important commands in ROS2

Aus HSHL Mechatronik
Zur Navigation springen Zur Suche springen


Abb 1: Communication in ROS2 [1]


Absolute basics

  • Each robot-functionality is managed in one entity known as a ROS 2 Node, [here is a great illustration]. ROS2 takes care of the running Nodes: timing, communication,...
  • Communication between nodes is managed via interfaces, which are described using a specific ROS2-format [ROS2].
  1. Topics: a "Publisher" sends messages and one or many "Subsriber" gets them
  2. Service: a "Client" requests informations and a "Server" sends a response
  3. Action: ??
  • Organization in ROS2:
    • A package contains one or more programs (in C++ or Python). "Entry-Points" in their setup.py show ROS2 how to execute them.
    • Every "program" will start at least one Node. Each Node handles a specific robot function and ROS2 takes care of the running Nodes (timing, messaging,...)
    • A Launch-File launches a number of Nodes (from one or more packages)
  • In ROS2 we use multiple terminals
  • At the beginning of a terminal, use this so that the linux-terminal recognises all ROS2-commands

source /SomeWorkspace/install/setup.bash, e. g. source ~/ros2_ws/install/setup.bash

  • Run execubale files ros2 run <package_name> <executable_file>
  • ROS2-workspace: Folder for your ROS2-project, e. g. ros2_ws
  • Launch a launch-file ros2 launch <package_name> <launch_file>
  • Show all running nodes ros2 node list


Step-by-Step

  • Find out your ROS2-Version for the next command
  • Turn on the ROS2-environment via source /opt/ros/<ROS2-Version>/setup.bash
  • Set up your workspace source ~/ros2_ws/install/setup.bash
  • put this command in ~/.bashrc (~ means home-directory in Linux), so that it will be executed each time we start a terminal gedit ~/.bashrc

ROS-packages [ROS2-docs]

What is a package

Every program that we want to execute or create is organized in ROS2-packages. They are ether created in C/C++ or Python.

A Python-package consists of:

  1. package.xml - meta-information (maintainer, dependencies, etc.)
  2. setup.py - instructions how to compile the package
  3. setup.cfg - instructions how to install the package
  4. <package_name> - folder whith the name of your package. All our Python scripts etc. go here. Contains an empty __init__.py file at the beginning.

Show ROS2-packages

show all: ros2 pkg list

show only my "package_name": ros2 pkg list | grep <package_name>

Step-by-Step [go here for example-files]

  1. Go to the src-directory of your workspace-folder: cd/ros2_ws/src
  2. Create your package <package_name>: ros2 pkg create --build-type ament_python --license Apache-2.0 <package_name> --dependencies <package_dependency_1> <package_dependency_2>
  3. Create a launch-folder: create folder so that you get src/<package_name>/launch
  4. Modify setup.py: In order for ROS2 to find the .launch.py-files, we make sure the data_files in setup.py looks like
    # this is for finding
    import os
    from glob import glob
    #...
    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'))
        ],
    
  5. Create a program: Create MyFirstPythonROSProgram.py Example of a Python-File for ROS2 with Important Basic Principles
  6. Create a shortcut for the methods in a package: They are called executables/entry points/... Enter the name of the package in "entry_points" in the setup.py of your package
        entry_points={
            'console_scripts': [
                <name_of_executable> = <package_name>.<NewPythonScript>:<SomeMethod>,
                'for_example = somepackage.pythonscriptxy:main',
            ],
        },
    
  7. Build package: Execute this command in your workspace-folder (e. g. ros2_ws) to compile all packages colcon build or a specific one colcon build --packages-select <package_name>
  8. Refresh: After package-creation always do source ~/ros2_ws/install/setup.bash to let ROS2 recognize all updates
  9. Test: ros2 run <package_name> <name_of_executable>



Topics

  • Print all available topics ros2 topic list
  • Search for specific topic ros2 topic list | grep <topic_name>
  • Get information about a topic ros2 topic info <topic_name>
    • Get more details including the Quality of Service (QoS) ros2 topic info <topic_name> -v
    • "Type" is the interface. Show it via ros2 interface show <Type>
    • This gets us a list of "fields" which are the data fields / variables a topic transmits.
  • Listen to a topic (stop with Cntrl+C) ros2 topic echo <topic_name>
  • Listen to a topic once ros2 topic echo <topic_name> --once
  • Listen to a field of a topic ros2 topic echo <topic_name> --field <field_name>
  • Show camera data in an extra window ros2 run rqt_image_view rqt_image_view <topic_name>/.../image
  • Publish a message to a topic ros2 topic pub <topic_name> <interface_name> <message>
  • Example
    • Publish a message ros2 topic pub --once /SomeMessageName std_msgs/msg/String "data: 'Hello World'"
    • This topic should show here ros2 topic list
    • Get more information ros2 topic info /SomeMessageName . This way we get the Type=interface std_msgs/msg/String
    • Getting morge info about the interface ros2 interface show std_msgs/msg/String . This gets us at the end all variables, here it's only one string data
    • So in a Python-Skript we have to use
      # Import the String-Definition
      from std_msgs.msg import String
      
      # Subscriber to SomeMessageName
              self.our_new_subscriber = self.create_subscription(
                  String,
                  '/SomeMessageName',
                  self.our_new_subscriber_callback,
                  QoSProfile(depth=10, reliability=ReliabilityPolicy.RELIABLE)
              )
      
      # Our Callback-Method accessing the String via "msg.data"
      def our_new_subscriber_callback(self, msg):
              self.get_logger().info("[our_new_subscriber_callback] ...")
              self.get_logger().info(msg.data)
      



Interfaces

  • show all ros2 interface list
  • a interface has to be created in a CMake-package (there is no way in a Python-package yet)

Step-by-Step

  1. Create package ros2 pkg create --build-type ament_cmake --license Apache-2.0 <InterfaceCPackage>
  2. Create a msg-directory inside the tutorial_interfaces-folder and a msg-file
    cd ~/ros2_ws/src/<InterfaceCPackage>
    mkdir msg
    touch msg/<SomeInterface>.msg
    
  3. Modify the msg-file:
    geometry_msgs/Point center # This custom message uses a message from another message package (geometry_msgs/Point in this case).
    float64 radius # Some new variable
    
  4. Add some stuff to the CMakeLists.txt file:
    find_package(geometry_msgs REQUIRED)
    find_package(rosidl_default_generators REQUIRED)
    
    rosidl_generate_interfaces(${PROJECT_NAME}
      "msg/Num.msg"
      "msg/Sphere.msg"
      "srv/AddThreeInts.srv"
      DEPENDENCIES geometry_msgs # Add packages that above messages depend on, in this case geometry_msgs for Sphere.msg
    )
    
  5. Add some stuff to the packages.xml file:
    <depend>geometry_msgs</depend>
    <buildtool_depend>rosidl_default_generators</buildtool_depend>
    <exec_depend>rosidl_default_runtime</exec_depend>
    <member_of_group>rosidl_interface_packages</member_of_group>
    
  6. Compile in the workspace-folder: colcon build --packages-select custom_interfaces
  7. Source (to let ros2 know all changes) source install/setup.bash



Coordinate Systems

coordinate system = coordinate/reference frame = transform = transformation frame (TF)

xyz = red green blue = RGB

View coordinate systems

Show a graph in a pdf-document to analyze the coordinate frame structure of a project:

ros2 run tf2_tools view_frames

Get the same graph, but in a window which you can refresh and see changes in real-time:

ros2 run rqt_tf_tree rqt_tf_tree

Show the link between 2 coordinate systems

ros2 run tf2_ros tf2_echo reference_frame get_frame

View coordinate systems via RViz2

  • open RViz rviz2
  • set the fixed frame via Global Options/Fixed Frame
  • add the frame view via Add/TF
  • Add/Image and set up "Description Topic" and "Quality of Service QoS" [in which quality the signal is to be received]
  • Add/RobotModel and set up "Description Topic"
  • and save the rviz2-config!

Create a coordinate system "NewSystem"

ros2 run tf2_ros static_transform_publisher --x 0 --y 4.0 --z 0 --roll 0 --pitch 0 --yaw 0 --frame-id SomeParentSystem--child-frame-id NewSystem