[Gazebo in 5 mins] 010 – How to launch RViz using a configuration file

[Gazebo in 5 mins] 010 – How to launch RViz using a configuration file

In this post, you’ll learn how to launch RViz using a configuration file. You will learn how to close and open RViz as many times you need without having to configure or customize it all over again.

Step 1: Fire up a system with ROS installation

“Hey, do you mean I have to install ROS first?” Absolutely not! Just log in to The Construct to get access to virtual machines pre-installed with ROS.

Once logged in, click here to copy the ROS project (rosject) we’ll use for this post. Once copied, click the Run button to open the rosject.

You might also want to try this on a local PC if you have ROS installed. However, please note that we don’t support local PCs and you will have to fix any errors you run into on your own. The rest of the instruction assumes that you are working on The Construct; please adapt them to your local PC and ROS installation.

PS: we are using ROS Kinetic. You should be able to replicate the same on any ROS 1 distro, with minor changes.

Step 2: Run RViz without loading a configuration file

Open the Code Editor and create a new file rviz_plain.launch in the location shown in the image below:

Here is the content of the file:

<?xml version="1.0"?>
<launch>

    <param name="robot_description" command="$(find xacro)/xacro --inorder '$(find my_robot_description)/urdf/robot.urdf'" />    

    <!-- send fake joint values -->
    <node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher">
        <param name="use_gui" value="True"/>
    </node>
    
    <!-- Combine joint values -->
    <node name="robot_state_publisher" pkg="robot_state_publisher" type="state_publisher"/>
    
    <!-- Show in Rviz   -->
    <node name="rviz" pkg="rviz" type="rviz" />

</launch>

Next, launch the rviz_plain.launch file. Open a Web Shell and type the command that follows.

roslaunch my_robot_description rviz_plain.launch

Now you should see the rviz window, with no display added. We would need to add the display one by one and then configure them. But this is not necessary, since we have a configuration file saved already. Let’s load it next.

Step 3: Run RViz in a launch file and pass the configuration

Stop the current program in the web shell using Ctrl + C and run the following command instead.

roslaunch my_robot_description rviz.launch

Now you should see a different rviz screen, generated from the configuration!

Can you spot some differences in the two launch files? Here is the rviz.launch file.

<?xml version="1.0"?>
<launch>

    <param name="robot_description" command="$(find xacro)/xacro --inorder '$(find my_robot_description)/urdf/robot.urdf'" />    

    <!-- send fake joint values -->
    <node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher">
        <param name="use_gui" value="True"/>
    </node>
    
    <!-- Combine joint values -->
    <node name="robot_state_publisher" pkg="robot_state_publisher" type="state_publisher"/>
    
    <!-- Show in Rviz   -->
    <node name="rviz" pkg="rviz" type="rviz" args="-d $(find my_robot_description)/rviz/robotmodel.rviz" />

</launch>

Step 4: Check your learning + Extra Tip

Do you now understand how to launch rviz using a configuration file? If not, please go over the post again, more carefully this time.

You can create a configuration file by using the File -> Save Config As... command on the rviz window. Use File -> Save Config to update the current config.

Step 5 (optional): watch the video

Feedback

Did you like this video? Whatever the case, please leave a comment in the comments section below, so we can interact and learn from each other.

If you want to learn about other ROS topics, please let us know on the comments area, and we will do a video about it.

Thank you!

How to Publish and Subscribe to a topic from a launch file

How to Publish and Subscribe to a topic from a launch file

In this post, you will learn how to publish and subscribe to a topic from a launch file. This post is a response to this question posted on Gazebo Answers.

Step 1: Fire up a system with ROS installation

“Hey, do you mean I have to install ROS first?” Absolutely not! Just log in to The Construct to get access to virtual machines pre-installed with ROS.

Once logged in, click on My Rosjects, then Create a New Rosject, supply the information as shown in the image below, and click Create. Then RUN the rosject.

Create a new Rosject

You might also want to try this on a local PC if you have ROS installed. However, please note that we don’t support local PCs and you will have to fix any errors you run into on your own. The rest of the instruction assumes that you are working on The Construct; please adapt them to your local PC and ROS installation.

PS: we are using ROS Noetic. You should be able to replicate the same on any ROS 1 distro.

Step 2: Create a package to demonstrate how to publish and subscribe to a topic from a launch file

Open Code Editor
Open a web shell

Open a web shell and run the following commands to create the package.

cd catkin_ws/src
source /opt/ros/noetic/setup.bash
catkin_create_pkg test_rostopic

Next, we create the launch directory and the launch files.

cd test_rostopic
mkdir launch
cd launch
touch test_pub.launch
touch test_echo.launch

Nice done! Now head over to the Code Editor to make changes to the launch files. Check the image below for how to open the Code Editor.

Open the Code Editor

Locate the launch folder in the code editor: catkin_ws > src > test_rostopic > launch and open the two launch files.

Paste the following lines into the test_pub.launch file. This is equivalent to rostopic pub /test_topic std_msgs/String "data: 'Hello there!'"

<launch>
    <arg name="topic_name" default="/test_topic" />
    <arg name="message" default="Hello there!" />
    <node pkg="rostopic" type="rostopic" name="rostopic_pub_node" output="screen" args="pub $(arg topic_name) std_msgs/String 'data: $(arg message)'" />
</launch>

Next, your test_echo.launch should be made up of the following lines. This is equivalent to rostopic echo /test_topic.

<launch>
    <arg name="topic_name" default="/test_topic" />
    <node pkg="rostopic" type="rostopic" name="rostopic_echo_node" output="screen" args="echo $(arg topic_name)" />
</launch>

Fantastic! Now, let’s compile the package.

cd ~/catkin_ws
catkin_make
source devel/setup.bash

Success! We’ll test it in the next step.

PS: if your code did not compile correctly, please go over the instructions and ensure you have created the files in the exact locations specified.

Step 3: Test the package to demonstrate how to publish and subscribe to a topic from a launch file

Start the test_pub.launch file in the current terminal.

roslaunch test_rostopic test_pub.launch

When done, open another terminal and run the test_echo.launch file.

roslaunch test_rostopic test_echo.launch

Now you should see something similar to the following on the terminal where test_echo.launch is running:

process[rostopic_echo_node-1]: started with pid [xxxx]
data: "Hello there!"
---

Sweet! So we are able to publish with one launch file and echo what we publish in another launch file. And…we are done here, congrats!

Take home: try combining both into a single launch file. After trying, check the solution in this gist.

Step 4: Check your learning

Do you understand how to publish and subscribe to a topic from a launch file? If you don’t know it yet, please go over the post again, more carefully this time.

(Extra) Step 5: Watch the video to understand how to publish and subscribe to a topic from a launch file

Here you go:

Feedback

Did you like this post? Do you have any questions about how to publish and subscribe to a topic from a launch file? Please leave a comment in the comments section below, so we can interact and learn from each other.

If you want to learn about other ROS topics, please let us know in the comments area and we will do a video or post about it.

How to write a ROS publisher and subscriber with a custom message

How to write a ROS publisher and subscriber with a custom message

In this post, you will learn how to write a ROS publisher and subscriber with a custom message, by following the Writing a Publisher and Subscriber with a Custom Message (Python) tutorial. This post is a response to this question posted on Gazebo Answers.

Step 1: Fire up a system with ROS installation

“Hey, do you mean I have to install ROS first?” Absolutely not! Just log in to The Construct to get access to virtual machines pre-installed with ROS.

Once logged in, click on My Rosjects, then Create a New Rosject, supply the information as shown in the image below, and click Create. Then RUN the rosject.

Create a new Rosject

You might also want to try this on a local PC if you have ROS installed. However, please note that we don’t support local PCs and you will have to fix any errors you run into on your own. The rest of the instruction assumes that you are working on The Construct; please adapt them to your local PC and ROS installation.

PS:

  • We are using ROS Kinetic here because that’s what the user on ROS Answers used.
  • We could put the publisher and the subscriber in a single package, but we’ll create two packages as the user did.
  • We could put the custom message in any of the two packages, but we’ll put it in the subscriber, just like the user.

Step 2: Create the first package that contains the subscriber and the custom message

Open Code Editor
Open a web shell

Create the package and custom message

Open a web shell and run the following commands to create the package. When creating a custom message, you need extra dependencies message_generation and message_runtime, in addition to the main ROS API, rospy (for Python) in this case, and the types needed for the message, in this case std_msgs.

cd catkin_ws/src
source /opt/ros/kinetic/setup.bash
catkin_create_pkg quadrotor_receive rospy std_msgs message_generation message_runtime

Next, we create the message file, Person.msg. Run the following command in the same terminal you just used.

cd quadrotor_receive
mkdir msg
cd msg
touch Person.msg

Nice done! Now head over to the Code Editor to make changes to the Person.msg file. Check the image below for how to open the Code Editor.

Open the Code Editor

Locate the file in the code editor: catkin_ws > src > quadrotor_receive > msg > Person.msg and paste in the following code.

string name
int32 age

Edit package files

Replace CMakeLists.txt with the one below (where the following changes have been made).

  • Removed message_runtime from the find_package function.
  • Uncommented the add_message_files function, and added Person.msg below FILES.
  • Uncommented the generate_messages function, and left it intact.
  • Uncommented the line CATKIN_DEPENDS in the catkin_package function.
  • Removed all commented lines to keep the file short and sweet.
cmake_minimum_required(VERSION 3.0.2)
project(quadrotor_receive)

## Find catkin macros and libraries
## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz)
## is used, also find other catkin packages
find_package(catkin REQUIRED COMPONENTS
  message_runtime
  rospy
  std_msgs
)

## Generate messages in the 'msg' folder
add_message_files(
  FILES
  Person.msg
  # Message2.msg
)

## Generate added messages and services with any dependencies listed here
generate_messages(
  DEPENDENCIES
  std_msgs
)

###################################
## catkin specific configuration ##
###################################
## The catkin_package macro generates cmake config files for your package
## Declare things to be passed to dependent projects
## INCLUDE_DIRS: uncomment this if your package contains header files
## LIBRARIES: libraries you create in this project that dependent projects also need
## CATKIN_DEPENDS: catkin_packages dependent projects also need
## DEPENDS: system dependencies of this project that dependent projects also need
catkin_package(
#  INCLUDE_DIRS include
#  LIBRARIES quadrotor_receive
CATKIN_DEPENDS message_generation message_runtime rospy std_msgs
#  DEPENDS system_lib
)

###########
## Build ##
###########

## Specify additional locations of header files
## Your package locations should be listed before other locations
include_directories(
# include
  ${catkin_INCLUDE_DIRS}
)

Next, add a single line to package.xml so that it looks like the one below. Can you identify the line that was added?

<?xml version="1.0"?>
<package format="2">
  <name>quadrotor_receive</name>
  <version>0.0.0</version>
  <description>The quadrotor_receive package</description>

  <!-- One maintainer tag required, multiple allowed, one person per tag -->
  <!-- Example:  -->
  <!-- <maintainer email="jane.doe@example.com">Jane Doe</maintainer> -->
  <maintainer email="user@todo.todo">user</maintainer>


  <!-- One license tag required, multiple allowed, one license per tag -->
  <!-- Commonly used license strings: -->
  <!--   BSD, MIT, Boost Software License, GPLv2, GPLv3, LGPLv2.1, LGPLv3 -->
  <license>TODO</license>

  <!--   <doc_depend>doxygen</doc_depend> -->
  <buildtool_depend>catkin</buildtool_depend>
  <build_depend>message_generation</build_depend>
  <build_depend>rospy</build_depend>
  <build_depend>std_msgs</build_depend>
  <build_export_depend>rospy</build_export_depend>
  <build_export_depend>std_msgs</build_export_depend>
  <build_export_depend>message_generation</build_export_depend>
  <exec_depend>message_runtime</exec_depend>
  <exec_depend>rospy</exec_depend>
  <exec_depend>std_msgs</exec_depend>


  <!-- The export tag contains other, unspecified, tags -->
  <export>
    <!-- Other tools can request additional information be placed here -->

  </export>
</package>

Finally, let’s create the receiver Python node, just as the ROS Answers user created it. Run the following in the same terminal as before. Notice that we’re making the Python script executable.

cd ~/catkin_ws/src/quadrotor_receive/src
touch custom_listener.py
chmod +x custom_listener.py

Open custom_listener.py in the IDE and paste in the following code.

#!/usr/bin/env python

import rospy
from quadrotor_receive.msg import Person 

def callback(data):
    rospy.loginfo("%s is age: %d" % (data.name, data.age))

def listener():

    rospy.init_node('custom_listener', anonymous=True)
    rospy.Subscriber("custom_chatter", Person , callback)

    # spin() simply keeps python from exiting until this node is stopped
    rospy.spin()

if __name__=='__main__':
    listener()

So much for all the hard work – let’s see if it works. Time to compile the code. In the same web shell, run the following commands:

Compile and test

cd ~/catkin_ws
catkin_make
source devel/setup.bash

Success! We have successfully created a package with a custom message. Let’s see if we can find the message. You should get an output similar to the one below.

user:~/catkin_ws$ rosmsg show quadrotor_receive/Person
string name
int32 age

Let’s also test receiver node at this point. Though there’s nothing to receive yet, it should not throw any error. First, we need to start roscore.

roscore

Then try to run your subscriber in another terminal. Leave it running!

rosrun quadrotor_receive custom_listener.py

PS: if your code did not compile correctly, please go over the instructions and ensure you have created the files in the exact locations specified.

Step 3: Create the second package that contains the publisher

Create a new folder package. This should be easy-peasy, as most of the work has been done in the previous step. Do the following in a new terminal.

cd ~/catkin_ws/src/
catkin_create_pkg transmit_thrust rospy

Next, create the custom_talker.py node.

cd transmit_thrust/src
touch custom_talker.py
chmod +x custom_talker.py

Open up custom_talker.py in the IDE and paste in the following.

#!/usr/bin/env python
import rospy
from quadrotor_receive.msg import Person

def talker():
    pub = rospy.Publisher('custom_chatter', Person)
    rospy.init_node('custom_talker', anonymous=True)
    r = rospy.Rate(10) #10hz
    msg = Person()
    msg.name = "ROS User"
    msg.age = 4

    while not rospy.is_shutdown():
        rospy.loginfo(msg)
        pub.publish(msg)
        r.sleep()

if __name__ == '__main__':
    try:
        talker()
    except rospy.ROSInterruptException: pass

Please note that:

  • We are importing the custom message from the quadrotor_receive package.
  • We are creating a publisher for the same topic we created a subscriber for in the quadrotor_receive package.

Nothing more is needed. Let’s compile our new package.

cd ~/catkin_ws
catkin_make
source devel/setup.bash

That done, let’s start the custom talker node.

rosrun transmit_thrust custom_talker.py

You should see some output similar to these on the terminal.

[INFO] [1680728823.955004]: name: "ROS User"
age: 4
[INFO] [1680728824.055152]: name: "ROS User"

And…on the terminal where you have the listener tunning, you should see something similar to:

[INFO] [1680728823.956347]: ROS User is age: 4
[INFO] [1680728824.056833]: ROS User is age: 4

And we are done here!

Step 4: Check your learning

Do you understand how to write a ROS publisher and subscriber with a custom message? If you don’t know it yet, please go over the post again, more carefully this time.

(Extra) Step 5: Watch the video to understand how to write a ROS publisher and subscriber with a custom message

Here you go:

Feedback

Did you like this post? Do you have any questions about how to write a ROS publisher and subscriber with a custom message? Please leave a comment in the comments section below, so we can interact and learn from each other.

If you want to learn about other ROS topics, please let us know in the comments area and we will do a video or post about it.

ROS2 Tutorials #7: How to create a ROS2 Custom Message

ROS2 Tutorials #7: How to create a ROS2 Custom Message

In this episode of ROS2 Tutorials Series, you will learn how to create a simple ROS2 custom message for Topics.

We are going to use a ROS2 (Dashing) installation for this, but you don’t need to install ROS, as we will use the ROS Development Studio (ROSDS), an online platform that provides access to ROS2 and ROS2 computers and other powerful ROS tools within a browser!

Now let’s get to work without further ado!

Step 1: Create a Project (ROSject) on ROSDS

Head to http://rosds.online and create a project with a similar configuration as the one shown below. You can change the details as you like, but please ensure you select “Ubuntu 18.04 + ROS2 Dashing” under “Configuration”.

Create a ROS2 project for Dashing

Once done with that, open your ROSject. This might take a few moments, please be patient.

Step 2: Source the ROS2 workspace

Once the ROSject is open, head to the Tools menu and pick the Shell tool (a terminal) and run the following command to source the workspace:

user:~$ source /opt/ros/dashing/setup.bash
ROS_DISTRO was set to 'melodic' before. Please make sure that the environment does not mix paths from different distributions.
user:~$

If you get that ROS_DISTRO warning, just ignore it.

Step 3: Create a ROS2 C++ package in your ROS2 workspace

We are creating a C++ package (ament_cmake) and adding dependencies rclcpp (ROS C++ client) and std_msgs (in-built standard messages type, on which our new message will be based).

user:~$ mkdir -p ros2_ws/src
user:~$ cd ros2_ws/src
user:~/ros2_ws/src$
user:~/ros2_ws/src$ ros2 pkg create ros2_msg --build-type ament_cmake --dependencies rclcpp std_msgs
going to create a new package
package name: ros2_msg
destination directory: /home/user/ros2_ws/src
package format: 3
version: 0.0.0
description: TODO: Package description
maintainer: ['user <user@todo.todo>']
licenses: ['TODO: License declaration']
build type: ament_cmake
dependencies: ['rclcpp', 'std_msgs']
creating folder ./ros2_msg
creating ./ros2_msg/package.xml
creating source and include folder
creating folder ./ros2_msg/src
creating folder ./ros2_msg/include/ros2_msg
creating ./ros2_msg/CMakeLists.txt
user:~/ros2_ws/src$

Step 3: Create the definition of the ROS2 custom message

user:~/ros2_ws/src$ cd ros2_msg
user:~/ros2_ws/src/ros2_msg$ mkdir -p msg
user:~/ros2_ws/src/ros2_msg$ cd msg/
user:~/ros2_ws/src/ros2_msg/msg$ touch MyMsg.msg

Pick the “IDE” tool from the Tools menu, locate the MyMsg.msg file, and paste in the following code:

int32 day
string month
int32 year

Next, open up the CMakeList.txt file in the IDE and add the required dependencies:

  1. Add these two dependencies under “#find package”, right after the three that are already there:
    • find_package(builtin_interfaces REQUIRED)
      find_package(rosidl_default_generators REQUIRED)

  2. Add the following function to CMakeList.txt.This function tells the ROS system to generate a new message from the specified message definition, using the specified interface.
    • rosidl_generate_interfaces(new_msg
        "msg/MyMsg.msg"
        DEPENDENCIES builtin_interfaces
      )
      

      Add custom function to CMakeLists.txt

Next, open up the package.xml file in the IDE and make the following changes:

  1. Change the package format from “2” to “3”, if not already “3” (in this case it was already 3):
    • Check package format is "3"
  2. Add the dependencies that complement the ones we have in CMakeList.txt:
    • <build_depend>builtin_interfaces</build_depend>
      <build_depend>rosidl_default_generators</build_depend>
      <exec_depend>builtin_interfaces</exec_depend>
      <exec_depend>rosidl_default_runtime</exec_depend>
      
      <member_of_group>rosidl_interface_packages</member_of_group>

      Add dependencies to package.xml

Step 4: Compile the package

Whew, a couple of ingredients had to be added there; now it is time to compile the message and taste the “soup”!

Get back to the terminal and run the following commands:

user:~$ cd ~/ros2_ws
user:~/ros2_ws$ colcon build --symlink-install
Starting >>> ros2_msg
Finished <<< ros2_msg [14.1s]
Summary: 1 package finished [14.3s]
user:~/ros2_ws$ source install/setup.bash
ROS_DISTRO was set to 'dashing' before. Please make sure that the environment does not mix paths from different distributions.
ROS_DISTRO was set to 'melodic' before. Please make sure that the environment does not mix paths from different distributions.
user:~/ros2_ws$

Step 5: Find and test the new custom message:

user:~/ros2_ws$ ros2 msg list | grep MyMsg
ros2_msg/msg/MyMsg

user:~/ros2_ws$ ros2 msg show ros2_msg/msg/MyMsg
int32 day
string month
int32 year
user:~/ros2_ws$ ros2 topic pub /test_topic ros2_msg/MyMsg "{day: '7', month: 'October', year: '2019'}"
publisher: beginning loop
publishing #1: ros2_msg.msg.MyMsg(day=7, month='October', year=2019)

publishing #2: ros2_msg.msg.MyMsg(day=7, month='October', year=2019)

publishing #3: ros2_msg.msg.MyMsg(day=7, month='October', year=2019)

Pick another Shell from the Tools menu and check the message being published (PS: you need to source ROS Dashing and the workspace first):

user:~$ source /opt/ros/dashing/setup.bash
ROS_DISTRO was set to 'melodic' before. Please make sure that the environment does not mix paths from different distributions.
user:~$ source ros2_ws/install/setup.bash
ROS_DISTRO was set to 'dashing' before. Please make sure that the environment does not mix paths from different distributions.
ROS_DISTRO was set to 'melodic' before. Please make sure that the environment does not mix paths from different distributions.
user:~$ ros2 topic list
/parameter_events
/rosout
/test_topic
user:~$ ros2 topic echo /test_topic
day: 7
month: October
year: 2019
---
day: 7
month: October
year: 2019
---
day: 7
month: October
year: 2019
---
day: 7
month: October
year: 2019
---
day: 7
month: October
year: 2019
---
day: 7
month: October
year: 2019
---
^Cuser:~$

Great, it ran! We’re done here!!

Extra 1: ROSject link

Get the ROSject containing all code used in the post in the following link: http://www.rosject.io/l/c3f3784/

Extra 2: Video

Prefer to watch a video demonstrating the steps above? We have one for you below!

Related Resources

Feedback

Did you like this post? Do you have questions about what is explained? Whatever the case, please leave a comment on the comments section below, so we can interact and learn from each other.

If you want to learn about other ROS or ROS2 topics, please let us know in the comments area and we will do a video or post about it 🙂

Post edited by Bayode Aderinola

#ROS2 #ROS #ROS2tutorials #Robot

[ROS Q&A] 196  – How to Output Odometry Data

[ROS Q&A] 196 – How to Output Odometry Data

In this post, you will learn how to access and output odometry data programmatically. More specifically, you will learn how to create a C++ program for subscribing to and printing different parts of the odometry message. This is useful for cases where you need to make a decision based on the robot’s current position.

This post is an answer to the following question found on ROS Answers: https://answers.ros.org/question/333391/way-to-output-odometry-info/.

Let’s get started!

Step 1: Grab the ROS Project (ROSject) on ROSDS

Click here to get a copy of the ROS project used in this post. Next, click open to load the project. Please be patient while the project loads.

Step 2: Launch the necessary tools

  1. Launch a simulation from the Simulations menu.
    • Click on the Simulations menu. A dropdown menu opens.
    • In the section “Launch a provided simulation”, leave the empty world selected and choose the Turtlebot 2 robot.
    • Click “Start simulation”.
  2. Pick a Shell tool from the Tools menu. We’re be firing some commands soon.
  3. Pick the IDE tool from the Tools menu. We’ll use this to examine the code used for solving this problem.

Step 3: Examine the structure of the Odometry message using the command line

Run the following command on the Shell tool to print the current odometry of the robot:

# The -n1 switch to the command to ensure it prints one command and exits. 
# Otherwise, it would print continuously until you press Ctrl + C.
user:~$ rostopic echo /odom -n1
header:
  seq: 4732
  stamp:
    secs: 236
    nsecs: 935000000
  frame_id: "odom"
child_frame_id: "base_footprint"
pose:
  pose:
    position:
      x: 0.00211759816401
      y: 4.81456536954e-05
      z: -0.000247189070632
    orientation:
      x: 0.000385225477218
      y: -0.00721104301471
      z: 0.000107238788561
      w: 0.99997392014
  covariance: [1e-05, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-05, 0.0,0.0, 0.0, 0.0, 0.0, 0.0, 1000000000000.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1000000000000.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1000000000000.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.001]
twist:
  twist:
    linear:
      x: -0.000279472699265
      y: -4.17203978095e-05
      z: 0.0
    angular:
      x: 0.0
      y: 0.0
      z: -7.05905617719e-06
  covariance: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
---

The command line output above shows the parts the make up an odometry message. The hottest part is pose, which tells us the current position of the robot. twist is also important, because it tells us the current message being published to move the robot.

Now let’s see how to access and output odometry data, considering the hottest part.

Step 4: See how to access and output odometry data in code

Switch to the IDE tool and locate the catkin_ws directory. You should find a C++ file in a package odom_subscriber. The full path to the file is catkin_ws/src/odom_subscriber/src/odom_sub.cpp.

Let’s see the content of this file:

#include <nav_msgs/Odometry.h> // Needed for accessing Odometry data
#include <ros/ros.h>           // Needed for creating the node, etc

// This functions get called when a new odometry message gets to the subscriber
// It automatically gets the odometry message as a parameter
// It prints out various parts of the message
void counterCallback(const nav_msgs::Odometry::ConstPtr &msg) {
  // ROS_INFO("%s", msg->header.frame_id.c_str());
  // ROS_INFO("%f", msg->twist.twist.linear.x);
  ROS_INFO("%f", msg->pose.pose.position.x);
}

int main(int argc, char **argv) {
  // Create a node to run the code
  ros::init(argc, argv, "odom_sub_node");
  ros::NodeHandle nh;

  // create a subscriber to the "/odom" topic so we can get the odometry message
  ros::Subscriber sub = nh.subscribe("odom", 1000, counterCallback);
  
  // Run program until manually stopped
  ros::spin();

  return 0;
}

I have added comments to the code to explain what each line or code block does, for better clarity.

The `counterCallback` function prints out the current x position of the robot. Observe how parts of the message are accessed in hierarchical format; using the structure in Step 3 as a guide, you can access and output any part of the Odometry message. 

You can uncomment the commented parts to print out parts of the header and twist messages or even write other statements that print out other parts of the message!

Step 5: Move the robot and see the odometry data printed in real-time!

Run the C++ program in the shell, to print out the current x position of the robot. We can see the robot is basically at the “origin” and is stationary. Leave this program running.

user:~$ rosrun odom_subscriber odom_sub_node
[ INFO] [1575339924.601377783, 49.183000000]: 0.000240
[ INFO] [1575339924.651682994, 49.233000000]: 0.000240
...

Pick another Shell tool from the tools menu and run a command to move the robot:

user:~$ rostopic pub /cmd_vel geometry_msgs/Twist "linear:
  x: 0.2
  y: 0.0
  z: 0.0
angular:
  x: 0.0
  y: 0.0
  z: 0.0"
publishing and latching message. Press ctrl-C to terminate

Now you should see the robot moving. You should also see that the Odometry data being output in the other shell is changing.

In the second Shell, press Ctrl + C to stop the current program. Then publish the following message to stop the robot. After this, you should see the odometry position data become static again.

user:~$ rostopic pub /cmd_vel geometry_msgs/Twist "linear:
  x: 0.0
  y: 0.0
  z: 0.0
angular:
  x: 0.0
  y: 0.0
  z: 0.0"
publishing and latching message. Press ctrl-C to terminate

Ant that was it!

Extra: Video

Prefer to watch a video demonstrating the steps above? We have one for you below!

Related Resources and Further Learning

If you are a ROS beginner and want to learn ROS basics fast, we recommend you take any of the following courses on Robot Ignite Academy:

Feedback

Did you like this post? Do you have questions about what is explained? Whatever the case, please leave a comment on the comments section below, so we can interact and learn from each other.

If you want to learn about other ROS topics, please let us know in the comments area and we will do a video or post about it.

Edited by Bayode Aderinola


#ROStutorials #Odometry #ROSsubscriber #ROS #Robot #C++

Pin It on Pinterest