[ROS Q&A] 144 – What is the difference between ROS topics and messages?

In this video we are going to explain and show in a practical way the difference between ROS topics and messages.

We show two nodes running, one publishing to a given topic and another subscribing to this same topic. RQT graph is used to see the big picture of the environment.

 

Step 0. Create a project in ROS Development Studio(ROSDS)

ROSDS helps you follow our tutorial in a fast pace without dealing without setting up an environment locally. If you haven’t had an account yet, you can create a free account here. Let’s create a new project and call it ros_q_a_topics_messages.

Step 1. Difference between ros topic and ros message

We’ll start by creating a package for the code in catkin_ws

cd catkin_ws/src
catkin_create_pkg my_pkg rospy std_msgs

Let’s also create a scripts folder for our scripts. Then two script called my_subscriber.py and my_publisher.py file in it with the following content.

#!/usr/bin/env python

import rospy
from std_msgs.msg import String

def main():
    pub = rospy.Publisher('my_topic', String, queue_size=10)
    rospy.init_node('my_publisher')

    rate = rospy.Rate(1)
    
    while not rospy.is_shutdown():
        hello_str = 'hello world %s' % rospy.get_time()

        rospy.loginfo(hello_str)

        pub.publish(hello_str)

        rate.sleep()

if __name__ == '__main__':
    try:
        main()
    except rospy.ROSInterruptExeception:
        pass

Basically, a message is data through a channel called topic. In this code, the message is String type and the topic is called my_topic.

#!/usr/bin/env python

import rospy
from std_msgs import String

def main():
    pub = rospy.Publisher('my_topic', String, queue_size = 10)

    rospy.init_node('my_publisher')

    rate = rospy.Rate(1)

    while not rospy.is_shutdown():
        hello_str = "hello world %s" % rospy.get_time()

        rospy.loginfo(hello_str)

        pub.publish(hello_str)

        rate.sleep()

if __name__ == '__main__' :
    try:
        main()
    except rospy.ROSInterruptExeception:
        pass

This script established a subscriber for the message through the topic my_topic.

To run the code, we have to give the scripts permission to execute with chmod +x my_publisher.py and chmod +x my_subscriber.py

Then we can run it with

cd catkin_ws
catkin_make
source devel/setup.bash
rosrun my_pkg my_publisher.py

You should see the publisher is publishing message into the topic.

Open another shell and run

rosrun my_pkg my_subscriber.py

Open the third shell and type rqt_graph , then go to Tools->graphical tool to open the GUI.

You should see the nodes are marked with circles. You can find the /my_publisher and /my_subscriber nodes in the graph.

The topic is marked with the square. In this example, the topic is called my_topic. The two node is communicating though this topic.

Want to learn more?

If you are interested in learning ROS, please check our ROS Basics Python course.

 

Edit by: Tony Huang


RELATED LINKS

▸ Original question: https://answers.ros.org/question/63511/what-is-the-difference-between-a-topic-and-a-message/
▸ ROS Development Studio (ROSDS)
▸ Robot Ignite Academy
▸ ROS Basics Python
▸ ROS Basics C++


Feedback

Did you like this video? 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 on the comments area and we will do a video about it.

[ROS Q&A] 143 – How to connect MoveIt to the Robot

In this tutorial of ROS Q&A Series, we’re going to see how to connect movit to the (simulated, in this case) robot.

This is a video trying to answer the following question posted at the ROS answers forum: https://answers.ros.org/question/298508/how-do-i-interact-the-actual-robot-with-visualization-by-rviz-in-moveit/

Step 1. Create a project in ROS Development Studio(ROSDS)

ROSDS helps you follow our tutorial in a fast pace without dealing without setting up an environment locally. If you haven’t had an account yet, you can create a free account here. Let’s create a new project and call it moveit_real.

Step 2. Use the moveit package

In this tutorial, we have already preconfigured the Sia Robot and moveit package for it. If you want to know how to configure the moveit package, please check our ROS-Industrial 101 course. If you launch the moveit package, you’ll see that no matter what trajectory you are planning in the moveit, it won’t affect the real robot(we use a simulation as an example here). That’s because of missing controllers. To apply the controller, a file called controller.yaml should be created in the config folder of the robot. We also have to specify the controller type in the sia10f.urdf file.  In order to use the controller, a transmission tag should be added to the urdf. You’ll also need a joint_names.yaml file in the config folder which defines the joints will be controlled. In the end, you’ll need to create launch files to launch the package.

Step 3. Plan the trajectory

After launching the controller, you can plan the trajectory with moveit package. The robot should move as the planning in the moveit package.

Want to learn more?

If you are interested in this topic and want to learn how to configure the moveit package and all the files you need to move the robot, please check our ROS-Industrial 101 course.

 

Edit by: Tony Huang

 

Related Courses

ROS Manipulation Course Cover - ROS Online Courses - Robot Ignite Academy

ROS Manipulation Course


Feedback

Did you like this video? 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 on the comments area and we will do a video about it.

[ROS Q&A] 142 – How to create launch file for URDF and open in Gazebo

In this video, we are going to show how to create a launch file to spawn a URDF robot model in a given gazebo world.

Up to the end of the video, you will be able to spawn any robot model you may have described in URDF in Gazebo.

Step 1. Create a project in ROS Development Studio(ROSDS)

ROSDS helps you follow our tutorial in a fast pace without dealing without setting up an environment locally. If you haven’t had an account yet, you can create a free account here. Let’s create a new project and call it launch_urdf_model_in_gazebo.

Step 2. Create a package

Let’s create a ROS package for our code by using the following command.

cd ~/catkin_ws/src
catkin_create_pkg my_robot_urdf rospy

Then we create a m2wr.urdf file under the my_robot_urdf/urdf folder.

<?xml version="1.0"?>
<robot name="m2wr" xmlns:xacro="http://www.ros.org/wiki/xacro">
  <material name="black">
    <color rgba="0.0 0.0 0.0 1.0"/>
  </material>
  <material name="blue">
    <color rgba="0.203125 0.23828125 0.28515625 1.0"/>
  </material>
  <material name="green">
    <color rgba="0.0 0.8 0.0 1.0"/>
  </material>
  <material name="grey">
    <color rgba="0.2 0.2 0.2 1.0"/>
  </material>
  <material name="orange">
    <color rgba="1.0 0.423529411765 0.0392156862745 1.0"/>
  </material>
  <material name="brown">
    <color rgba="0.870588235294 0.811764705882 0.764705882353 1.0"/>
  </material>
  <material name="red">
    <color rgba="0.80078125 0.12890625 0.1328125 1.0"/>
  </material>
  <material name="white">
    <color rgba="1.0 1.0 1.0 1.0"/>
  </material>
  
    <gazebo reference="link_chassis">
    <material>Gazebo/Orange</material>
  </gazebo>
  <gazebo reference="link_left_wheel">
    <material>Gazebo/Blue</material>
  </gazebo>
  <gazebo reference="link_right_wheel">
    <material>Gazebo/Blue</material>
  </gazebo>
  
  <gazebo>
    <plugin filename="libgazebo_ros_diff_drive.so" name="differential_drive_controller">
      <alwaysOn>true</alwaysOn>
      <updateRate>20</updateRate>
      <leftJoint>joint_left_wheel</leftJoint>
      <rightJoint>joint_right_wheel</rightJoint>
      <wheelSeparation>0.4</wheelSeparation>
      <wheelDiameter>0.2</wheelDiameter>
      <torque>0.1</torque>
      <commandTopic>cmd_vel</commandTopic>
      <odometryTopic>odom</odometryTopic>
      <odometryFrame>odom</odometryFrame>
      <robotBaseFrame>link_chassis</robotBaseFrame>
    </plugin>
  </gazebo>
  
  <gazebo reference="sensor_laser">
    <sensor type="ray" name="head_hokuyo_sensor">
      <pose>0 0 0 0 0 0</pose>
      <visualize>false</visualize>
      <update_rate>20</update_rate>
      <ray>
        <scan>
          <horizontal>
            <samples>720</samples>
            <resolution>1</resolution>
            <min_angle>-1.570796</min_angle>
            <max_angle>1.570796</max_angle>
          </horizontal>
        </scan>
        <range>
          <min>0.10</min>
          <max>10.0</max>
          <resolution>0.01</resolution>
        </range>
        <noise>
          <type>gaussian</type>
          <mean>0.0</mean>
          <stddev>0.01</stddev>
        </noise>
      </ray>
      <plugin name="gazebo_ros_head_hokuyo_controller" filename="libgazebo_ros_laser.so">
        <topicName>/m2wr/laser/scan</topicName>
        <frameName>sensor_laser</frameName>
      </plugin>
    </sensor>
  </gazebo>
  
   <link name="link_chassis">
    <!-- pose and inertial -->
    <pose>0 0 0.1 0 0 0</pose>
    <inertial>
      <mass value="5"/>
      <origin rpy="0 0 0" xyz="0 0 0.1"/>
      <inertia ixx="0.0395416666667" ixy="0" ixz="0" iyy="0.106208333333" iyz="0" izz="0.106208333333"/>
    </inertial>
    <!-- body -->
    <collision name="collision_chassis">
      <geometry>
        <box size="0.5 0.3 0.07"/>
      </geometry>
    </collision>
    <visual>
      <origin rpy="0 0 0" xyz="0 0 0"/>
      <geometry>
        <box size="0.5 0.3 0.07"/>
      </geometry>
      <material name="blue"/>
    </visual>
    <!-- caster front -->
    <collision name="caster_front_collision">
      <origin rpy=" 0 0 0" xyz="0.35 0 -0.05"/>
      <geometry>
        <sphere radius="0.05"/>
      </geometry>
      <surface>
        <friction>
          <ode>
            <mu>0</mu>
            <mu2>0</mu2>
            <slip1>1.0</slip1>
            <slip2>1.0</slip2>
          </ode>
        </friction>
      </surface>
    </collision>
    <visual name="caster_front_visual">
      <origin rpy=" 0 0 0" xyz="0.2 0 -0.05"/>
      <geometry>
        <sphere radius="0.05"/>
      </geometry>
    </visual>
  </link>
  
  <link name="link_right_wheel">
    <inertial>
      <mass value="0.2"/>
      <origin rpy="0 1.5707 1.5707" xyz="0 0 0"/>
      <inertia ixx="0.000526666666667" ixy="0" ixz="0" iyy="0.000526666666667" iyz="0" izz="0.001"/>
    </inertial>
    <collision name="link_right_wheel_collision">
      <origin rpy="0 1.5707 1.5707" xyz="0 0 0"/>
      <geometry>
        <cylinder length="0.04" radius="0.1"/>
      </geometry>
    </collision>
    <visual name="link_right_wheel_visual">
      <origin rpy="0 1.5707 1.5707" xyz="0 0 0"/>
      <geometry>
        <cylinder length="0.04" radius="0.1"/>
      </geometry>
    </visual>
  </link>
  
  <joint name="joint_right_wheel" type="continuous">
    <origin rpy="0 0 0" xyz="-0.05 0.15 0"/>
    <child link="link_right_wheel"/>
    <parent link="link_chassis"/>
    <axis rpy="0 0 0" xyz="0 1 0"/>
    <limit effort="10000" velocity="1000"/>
    <joint_properties damping="1.0" friction="1.0"/>
  </joint>
  
  <link name="link_left_wheel">
    <inertial>
      <mass value="0.2"/>
      <origin rpy="0 1.5707 1.5707" xyz="0 0 0"/>
      <inertia ixx="0.000526666666667" ixy="0" ixz="0" iyy="0.000526666666667" iyz="0" izz="0.001"/>
    </inertial>
    <collision name="link_left_wheel_collision">
      <origin rpy="0 1.5707 1.5707" xyz="0 0 0"/>
      <geometry>
        <cylinder length="0.04" radius="0.1"/>
      </geometry>
    </collision>
    <visual name="link_left_wheel_visual">
      <origin rpy="0 1.5707 1.5707" xyz="0 0 0"/>
      <geometry>
        <cylinder length="0.04" radius="0.1"/>
      </geometry>
    </visual>
  </link>
  
  <joint name="joint_left_wheel" type="continuous">
    <origin rpy="0 0 0" xyz="-0.05 -0.15 0"/>
    <child link="link_left_wheel"/>
    <parent link="link_chassis"/>
    <axis rpy="0 0 0" xyz="0 1 0"/>
    <limit effort="10000" velocity="1000"/>
    <joint_properties damping="1.0" friction="1.0"/>
  </joint>
  
  
</robot>

This file defines the physical parameters of our robot and the type of controller that we want to use.

We’ll create a launch file to launch this description. We name it spawn_urdf.launch and put it under the launch folder.

<?xml version="1.0" encoding="UTF-8"?>
<launch>
    <param name="robot_description" command="cat '$(find my_robot_urdf)/urdf/m2wr.urdf'" />
    
    <node name="mybot_spawn" pkg="gazebo_ros" type="spawn_model" output="screen"
          args="-urdf -param robot_description -model m2wr" />
          
</launch>

You can see that the launch file try to find the description file from the my_robot_urdf package.

Now we have to compile it with the following command

cd ~/catkin_ws
catkin_make
source devel/setup.bash

Now you can launch an empty world simulation from Simulations->Empty, then use the command roslaunch my_robot_urdf spawn_urdf.launch  to spawn the robot!

If you are interested in this topic and want to learn more about URDF, please check our Robot Creation with URDF course.

 

Edit by: Tony Huang

Related resources and links:

[ROS Q&A] 141 – How to Modify Logger Level in ROS (C++)

 

In this video we are going to see how to modify the Logger Level in ROS using C++.

This is a video trying to answer the following question posted at the ROS answers forum: https://answers.ros.org/question/98521/problems-with-logger-levels/

RELATED LINKS

▸ Original question: https://answers.ros.org/question/98521/problems-with-logger-levels/
▸ ROS Development Studio (RDS)
▸ Robot Ignite Academy

Step 1. Create a project in ROS Development Studio(ROSDS)

ROSDS helps you follow our tutorial in a fast pace without dealing without setting up an environment locally. If you haven’t had an account yet, you can create a free account here.

Step 2. Create package and file

Let’s create a package for testing in RDS by typing the following command.

cd ~/catkin_ws/src
catkin_create_pkg logs_test roscpp

Then we create a source file under the logs_test/src directory called logs.cpp with the following content.

#include <ros/ros.h>
#include <ros/console.h>
#include <stdlib.h>

int main(int argc, char** argv) {
    if (ros::console::set_logger_level(ROSCONSOLE_DEFAULT_NAME, ros::console::levels::Debug))
    {
        ros::console::notifyLoggerLevelsChanged();
    }
    
    ros::init(argc,argv,"log_demo");
    ros::NodeHandle nh;
    ros::Rate loop_rate(0.5); // We create a Rate object of 2Hz
    
    while (ros::ok()) //Endless loop until Ctrl+c
    {
        ROS_DEBUG("This is a DEBUG message");
        ROS_INFO("This is a INFO message");
        ROS_WARN("This is a WARN message");
        ROS_ERROR("This is a ERROR message");
        ROS_FATAL("This is a FATAL message");
        
        loop_rate.sleep();
        ros::spinOnce();
    }
    
    return 0;
}

In the CMakeLists.txt, please change the following content in build part.

...

## Declare a C++ executable
## With catkin_make all packages are built within a single CMake context
## The recommended prefix ensures that target names across packages don't collide
add_executable(logs_test src/logs.cpp)

...

## Add cmake target dependencies of the executable
## same as for the library above
add_dependencies(logs_test ${logs_test_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})

## Specify libraries to link a library or executable target against
target_link_libraries(logs_test
  ${catkin_LIBRARIES}
)

...

Then we can compile the code with the following command

cd ~/catkin_ws
catkin_make

While waiting for compilation, let’s create a launch file to launch the code much easier. Please create a launch folder under the logs_test directory and create a file called logs_test.launch under it with the following code.

<launch>
    <node pkg = "logs_test" type="logs_test" name="log_demo" output="screen" />
</launch>

Then we can run the following command in shell to launch the node.

roslaunch logs_test logs_test.launch

Since we set the lowest level logger in our code(DEBUG) we’ll see all 5 levels logs are printing. If you change it(e.g. to ERROR) and compile again, you should only see the ERROR and FATAL message.

 

Edit by: Tony Huang


Feedback

Did you like this video? 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 on the comments area and we will do a video about it.

[ROS Q&A] 140 – How to Modify a Robot’s Coordinates When it Arrives at a Checkpoint?


In this video we are going to see how to programmatically modify a robot’s coordinates when it arrives at a known checkpoint. We will use the same technique as clicking on the 2D Pose Estimate in RViz, but with a Python script. This is useful for the robot to know its exact location whenever it arrives at a checkpoint.

This is a video trying to answer the following question posted at the ROS answers forum.

Step 1. Create a project in ROS Development Studio(ROSDS)

ROSDS helps you follow our tutorial in a fast pace without dealing without setting up an environment locally. If you haven’t had an account yet, you can create a free account here.

Step 2. Start simulation

In this post, we’re going to start bt running turtlebot navigation simulation first with the following commands. Please open an empty gazebo simulation environment from tools->gazebo and then execute the commands in 3 different shells(you can find them in Tools->Shell).

roslaunch turtlebot_navigation_gazebo main.launch

This command spawns the turtlebot and world in gazebo

roslaunch turtlebot_navigation_gazebo move_base_demo.launch

The second command launch the amcl algorithm for the turtlebot

roslaunch turtlebot_rviz_launchers view_navigation.launch

The third one launches the rviz tool for visualization. You can open the graphical window from Tools->graphical tools.

Step 3. Create a new package for the task

In rviz, you can click 2D post Estimate button to estimate the current location of the robot. Our idea is whenever the robot detects a RFID, it will update it’s current location. When you click the button, it publishes a message for you to the topic /initialpose. To check the type of the message, type rostopic info /initialpost , you’ll see that the message type is geometry_msgs/PoseWithCovarianceStamped. If we want to update the pose, we have to be able to send this message.

Let’s create a package to do this task.

cd ~/catkin_ws/src
catkin_create_pkg set_point rospy

Under the package directory, create a script folder and put our script called main.py inside it with the following content

#!/usr/bin/env python

import rospy
from geometry_msgs.msg import PoseWithCovarianceStamped
from tf.transformations import quaternion_from_euler

rospy.init_node('init_pos')
pub = rospy.Publisher('/initialpose', PoseWithCovarianceStamped, queue_size = 10)
rospy.sleep(3)
checkpoint = PoseWithCovarianceStamped()

checkpoint.pose.pose.position.x = 0.0
checkpoint.pose.pose.position.y = 0.0
checkpoint.pose.pose.position.z = 0.0

[x,y,z,w]=quaternion_from_euler(0.0,0.0,0.0)
checkpoint.pose.pose.orientation.x = x
checkpoint.pose.pose.orientation.y = y
checkpoint.pose.pose.orientation.z = z
checkpoint.pose.pose.orientation.w = w

print checkpoint
pub.publish(checkpoint)

In this script, we set the initial point to x,y,z all equal to zero. If you run the script, you’ll see that the robot model moves to the origin of the map!

 

 

Edit by: Tony Huang

 

// RELATED LINKS

▸ Original question: https://answers.ros.org/question/278551/how-do-i-modifychange-base_footprint-by-program/
▸ ROS Development Studio (RDS): https://goo.gl/bUFuAq
▸ Robot Ignite Academy: https://goo.gl/6nNwhs

—
Feedback
—
Did you like this video? 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 on the comments area and we will do a video about it.

Pin It on Pinterest