[ROS Q&A] 132 – Callback messages being executed one at a time

In this video we are going to see how to make sure callback messages are being executed one at a time.

This is a video trying to answer the following question posted at the ROS answers forum: https://answers.ros.org/question/287612/how-to-be-100-sure-that-only-one-callback-is-being-executed-at-a-time

RELATED LINKS

▸ Original question: https://answers.ros.org/question/287612/how-to-be-100-sure-that-only-one-callback-is-being-executed-at-a-time
▸ Robot Ignite Academy
▸ ROS Basics in 5 days (Python)
▸ ROS Development Studio (ROSDS)

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

We’ll answer this question by walking you through an example with ROSDS. With ROSDS, we can focus on solving the problem directly instead of finding Linux pc, install ROS and etc. You can create an account here for free. After registering, let’s create a new project and call it q_a_callback_processing.

Step 2. Create package

Then, we’ll create a package with dependencies

cd catkin_ws/src
catkin_create_pkg my_pkg rospy std_msgs

Then create a folder called script under the package directory and a file called publisher.py under the script directory with the content

#!/usr/bin/env python

import rospy
from std_msgs.msg import Int32

def publisher():
    pub = rospy.Publisher('topic_name', Int32, queue_size=10)
    rospy.init_node('publisher')
    r = rospy.Rate(30)
    
    count = 1
    msg = Int32()
    while not rospy.is_shutdown():
        msg.data = count
        count = count+1 if count < 30 else 1
        pub.publish(msg)
        rospy.loginfo(msg)
        r.sleep()

if __name__ == '__main__':
    publisher()

You can see that the topic is publishing at 30 Hz.

To run it, you have to give it permission first with chmod +x publisher.py , then you can run it with rosrun my_pkg publisher.py . You’ll see the script starts to publishing message.

Now the publisher is working, let’s create a subscriber to subscribe to the topic. Let’s call it subscriber.py and fill it with the following content

#!/usr/bin/env python

import rospy
from std_msgs.msg import Int32

processing = False
new_msg = False
msg = None

def callback(data):
    global processing, new_msg, msg
    if not processing:
        new_msg = True
        msg = data

def listener():
    global processing, new_msg, msg
    rospy.init_node('subscriber')
    rospy.Subscriber('topic_name', Int32, callback)
    r = rospy.Rate(5)
    while not rospy.is_shutdown():
        if new_msg:
            #set processing to True
            processing = True
            new_msg = False
            #simulate a process that take 0.2 seconds
            rospy.loginfo(msg)
            r.sleep()
            #set processing to False
            processing = False
    
if __name__ == '__main__':
    listener()

Here in the subscriber, we only run it for 5 Hz. Now you have to give it permission and run it. You’ll see that the subscriber only get 5 messages every second. This is the answer!

 

Take away today:

You can specify different rates and r.sleep() function for publisher and subscriber in order to make sure the node has enough time to run your algorithm.

 

Edit by: Tony Huang


Feedback

Did you like this video? 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] 134 – Simple ROS Publisher in C++

In this video we are going to see how to create a simple ROS Publisher in C++.

* This is a video based on the question 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. Let’s create a new project and call it abc_qa.

Step 2. Create a package

Let’s create a new package called abc_qa with dependency for the code.

cd catkin_ws/src
catkin_create_pkg abc_qa roscpp

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

int main()
{
     //Initialize and start the node
     ros::Publisher pub;
     //Define and create some messages
     abc;
     while(ros : ok)
     {
           ros_time = ros::time::now();
           pub.publish(abc);
           ros::spinOnce();               
     }

 }

In order to compile the code, we have to change the following BUILD part in the CMakeLists.txt.

...
## 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(abc_node src/abc_code.cpp)

## Rename C++ executable without prefix
## The above recommended prefix causes long target names, the following renames the
## target back to the shorter version for ease of user use
## e.g. "rosrun someones_pkg node" instead of "rosrun someones_pkg someones_pkg_node"
# set_target_properties(${PROJECT_NAME}_node PROPERTIES OUTPUT_NAME node PREFIX "")

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

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

...

Then we can try to compile it with the following command

cd ~/catkin_ws
catkin_make

You should get several compilation errors. Let’s fix the code. It should look like this after changing.

#include <ros/ros.h>
#include <std_msgs/Int32.h>

int main(int argc, char ** argv)
{
     //Initialize and start the node
     ros::init(argc, argv, "abc");
     ros::NodeHandle nh;
     
     ros::Publisher pub = nh.advertise<std_msgs::Int32>("abc_topic", 1000);
     //Define and create some messages
     std_msgs::Int32 abc;
     abc.data = 0;
     
     ros::Rate(200);
     
     while(ros::ok)
     {
           pub.publish(abc);
           ros::spinOnce();               
     }

 }

It should work now. Try to compile and run it again with the following command

cd ~/catkin_ws
catkin_make
source devel/setup.bash
rosrun abc_qa abc_node

Now we got error said that it’s missing master now. You can either run whatever simulation from Simulations or run roscore  in a new shell to solve this problem. After launching the master, execute the code again. Although it shows nothing, it is actually starting to publish to topic /abc_topic you can see it with the command rostopic echo /abc_topic. You can also try to increment the counter in the while loop.

Related Course

ROS Basics C++ Course Cover - ROS Online Courses - Robot Ignite Academy

ROS Basics for Beginners (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 in the comments area and we will do a video about it.

[ROS Q&A] 133 – How to get the position and angular acceleration of a robot?

In this video we are going to see how can we subscribe to topics so that we can get the position and acceleration of a Sphero robot.

This video is especially good for beginners who have already understood the basics, and want to start writing their own code. We will try to properly structure our Python code, as well as follow some programming good practices.

This is a video based on the following post on The Construct’s Forum: http://forum.theconstructsim.com/questions/1188/print-position-angular-acceleration

// RELATED LINKS

▸ Original question: http://forum.theconstructsim.com/questions/1188/print-position-angular-acceleration
▸ ROS Development Studio (ROSDS)
▸ 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. Let’s create a new project and call it Print_Position_QA.

Step 2. Create a package

To reproduce the question, we’ll use the original code from the forum. Let’s create a package for the code first with the following command.

cd ~/catkin_ws/src
catkin_create package print_pos rospy

Then we create a script file called main.py and put it in the scripts folder under the print_pos package with the following content from the forum.

! /usr/bin/env python
import rospy

from geometry_msgs.msg import Twist

from nav_msgs.msg import Odometry

from sensor_msgs.msg import Imu

rospy.init_node('sphero')

pub = rospy.Publisher('/cmd_vel', Twist, queue_size=1) #topic publisher that allows you to move the sphero

rate = rospy.Rate(0.5)

def odom (msg):

go = Odometry()

print "pose x = " + str(go.pose.pose.position.x)

print "pose y = " + str(go.pose.pose.position.y)

print "orientacion x = " + str(go.pose.pose.orientation.x)

print "orientacion y = " + str(go.pose.pose.orientation.y)

rate.sleep()

sub = rospy.Subscriber('odom', Odometry, odom)

def imu (msg):

allez = Imu()

print "veloc angular z = " + str(allez.angular_velocity.z)

print "veloc angular y = " + str(allez.angular_velocity.y)

print "aceleracion linear x = " + str(allez.linear_acceleration.x)

print "aceleracion linear y = " + str(allez.linear_acceleration.y)

rate.sleep()

sub = rospy.Subscriber('sphero/imu/data3', Imu, imu)

def twist (msg):

move = Twist()

print "velocidad linear x = " + str(move.linear.x)

print "velocidad angular z = " + str (move.angular.z)

rate.sleep()

sub=rospy.Subscriber('cmd_vel', Twist, twist)

while not rospy.is_shutdown():

move = Twist()

move.linear.x = 2

move.angular.z= 0.5

pub.publish(move)

rospy.spin()

Some part of the code is not correct(e.g. the subscriber is not subscribing correctly so there is no reading), let’s correct it as follows.

#! /usr/bin/env python
import rospy
from geometry_msgs.msg import Twist
from nav_msgs.msg import Odometry
from sensor_msgs.msg import Imu

def odom_callback(msg):
    # go = Odometry() is not needed
    print "------------------------------------------------"
    print "pose x = " + str(msg.pose.pose.position.x)
    print "pose y = " + str(msg.pose.pose.position.y)
    print "orientacion x = " + str(msg.pose.pose.orientation.x)
    print "orientacion y = " + str(msg.pose.pose.orientation.y)
    rate.sleep()

def imu_callback(msg):
    # allez = Imu()
    print "------------------------------------------------"
    print "veloc angular z = " + str(msg.angular_velocity.z)
    print "veloc angular y = " + str(msg.angular_velocity.y)
    print "aceleracion linear x = " + str(msg.linear_acceleration.x)
    print "aceleracion linear y = " + str(msg.linear_acceleration.y)
    rate.sleep()

def twist (msg):
    # move = Twist()
    print "velocidad linear x = " + str(move.linear.x)
    print "velocidad angular z = " + str (move.angular.z)
    rate.sleep()
    #sub=rospy.Subscriber('cmd_vel', Twist, twist)

rospy.init_node('sphero_monitor') # the original name sphero might be the same as other node.
pub = rospy.Publisher('/cmd_vel', Twist, queue_size=1) #topic publisher that allows you to move the sphero
sub_odom = rospy.Subscriber('/odom', Odometry, odom_callback) # the original name odom might be the same as other function.
sub_imu = rospy.Subscriber('/sphero/imu/data3', Imu, imu_callback)
rate = rospy.Rate(0.5)

while not rospy.is_shutdown():
    move = Twist()
    move.linear.x = 0.1 # m/s. The original value 2 is too large
    move.angular.z= 0.5 # rad/s
    pub.publish(move)
    rate.sleep() # Instead of using rospy.spin(), we should use rate.sleep because we are in a loop

Before executing the code, we have to give it permission first with chmod +x main.py  and we also need the simulation(start it from Simulations->Sphero).

Then we can run the code with rosrun print_pos main.py

You should see the readings from sensors and the robot also starts to move around.

If you are interested in this topic, please check our ROS Basics in 5 Days course. You’ll learn how to control the Sphero robot to exit the maze in this course.

 

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] 130 – How to launch multiple robots in Gazebo simulator?

 

In this video, we are going to see how can we launch multiple robots in a single Gazebo simulation.

We will be introduced to the concept of namespace and tf_prefix, which are essential to make sure that the robots will be able to work correctly. We will create a series of launch files that will enable us to easily add robots into our Gazebo simulation.

This is a video based on the following post on ROS Answers: https://answers.ros.org/question/41433/multiple-robots-simulation-and-navigation/

NOTICE: most of the code would be the same in the ROS Answer, however, we’ll make some change to make sure it is compatible with ROS kinetic. Please use the code below.

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 a package

We’ll create a package to put our source code for the project with the following command

cd ~/catkin_ws/src
catkin_create_pkg multi_robot rospy gazebo_ros

Then we’ll create a folder called launch under the package directory and create 3 launch files that we need.

<launch>
    <arg name="robot_name"/>
    <arg name="init_pose"/>

    <node name="spawn_minibot_model" pkg="gazebo_ros" type="spawn_model"
     args="$(arg init_pose) -urdf -param /robot_description -model $(arg robot_name)"
     respawn="false" output="screen" />

    <node pkg="robot_state_publisher" type="state_publisher" 
          name="robot_state_publisher" output="screen"/>

    <!-- The odometry estimator, throttling, fake laser etc. go here -->
    <!-- All the stuff as from usual robot launch file -->
</launch>

This launch file will launch one robot in the simulation.

<launch>
  <!-- No namespace here as we will share this description. 
       Access with slash at the beginning -->
  <param name="robot_description"
    command="$(find xacro)/xacro.py $(find turtlebot_description)/robots/kobuki_hexagons_asus_xtion_pro.urdf.xacro" />

  <!-- BEGIN ROBOT 1-->
  <group ns="robot1">
    <param name="tf_prefix" value="robot1_tf" />
    <include file="$(find multi_robot)/launch/one_robot.launch" >
      <arg name="init_pose" value="-x 1 -y 1 -z 0" />
      <arg name="robot_name"  value="Robot1" />
    </include>
  </group>

  <!-- BEGIN ROBOT 2-->
  <group ns="robot2">
    <param name="tf_prefix" value="robot2_tf" />
    <include file="$(find multi_robot)/launch/one_robot.launch" >
      <arg name="init_pose" value="-x -1 -y 1 -z 0" />
      <arg name="robot_name"  value="Robot2" />
    </include>
  </group>
</launch>

Please notice that it should have a different namespace and tf_prefix for each robot.

<launch>
  <param name="/use_sim_time" value="true" />

  <!-- start world -->
  <node name="gazebo" pkg="gazebo_ros" type="gazebo" 
   args="$(find turtlebot_gazebo)/worlds/empty_wall.world" respawn="false" output="screen" />

  <!-- start gui -->
  <!-- <node name="gazebo_gui" pkg="gazebo" type="gui" respawn="false" output="screen"/> -->

  <!-- include our robots -->
  <include file="$(find multi_robot)/launch/robots.launch"/>
</launch>

You can launch the simulation with the following command

roslaunch multi_robot main.launch

Then you have to open the gazebo window from Tools->Gazebo

You should see 2 robots are spawned in the simulation. You can spawn more by changing the robots.launch if you want.

Step 3. Move the robot

Open another terminal, if you type rostopic list , you’ll see there are 2 cmd_vel topics for the robots. The simplest way to control them is with the teleop_twist. We can run it and remap the cmd_vel with the robot you want to control. For example

rosrun teleop_twist_keyboard teleop_twist_keyboard.py /cmd_vel:=/robot1/cmd_vel

Now you can control the robot you want.

 

Edit by: Tony Huang

 

 

// RELATED LINKS

▸ Original question: https://answers.ros.org/question/41433/multiple-robots-simulation-and-navigation/
▸ ROS Development Studio (RDS)
▸ Robot Ignite Academy

—
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] 129 – Which ROS controllers required for PR2 ?

 

In this video we are going to see why a ROS developer can’t launch a PR2 Gazebo simulation, mainly because the ROS controllers are not found.

We will see which are the ROS packages which provide all the required controllers for the PR2. We will also see how you can apply this check to your own robot simulation, in case it complains about the controllers not being loaded.

This is a video trying to answer the following question posted at the ROS answers forum: https://answers.ros.org/question/294245/roslaunch-pr2_gazebo-pr2_empty_worldlaunch/

 

The following steps take throught the development as shown in the video

  • Open Robot Development Studio and create a new project (use a suitable name for project).
  • Launch the PR2 simulation by entering the following commands in a SHELL

    $ roslaunch pr2_gazebo pr2_empty_world.launch

It will take a while to load the simulation and we need to open a gazebo window (Tools>Gazebo) to see the visualization.

If the simulation doesn’t launch then we need to check for a few things

  • Controller manager : It is important that controller manager be running, we can check that with the following command

$ rosservice list| grep controller_manager

In the output of the above command, if you see enteries starting with /pr2_controller_manager/ that means everything is OK.

The different types of controllers available can be checked with command

$ rosservice call /pr2_controller_manager/list_controller_types

If you see controller types in the output of the above command then everything is OK.

We can check if these controllers are loaded or not using the following command

$ rosservice call /pr2_controller_manager/list_controllers

The above command should output various controllers and thier status.

Now the above case is for the working environment where all the required packages are installed. If some packages are missing then we should systematically look for packages and dependencies. The packages mostly fall into two categories: gazebo-ros controllers and robot specific controllers (pr2-controllers specifically for our case)

  • ros-control : To list the available ros-control packages use the following command

$ dpkg -l | grep ros-control

There are two important packages in this category ros-kinetic-gazebo-ros-control and ros-kinetic-ros-controllers

  • gazebo-ros : To list the available gazebo-ros related packages use the following command

$ dpkg -l | grep gazebo-ros

The output of the command should contain the following two names ros-kinetic-gezebo-ros and ros-kinetic-gezebo-ros-control (this one was seen in previous commands output also)

  • controller interfaces : To list the installed controller interface packages use the command

$ dpkg -l | grep controller-interface

The output of this command should show the following names ros-kinetic-controller-interface, ros-kinetic-controller-manager, ros-kinetic-controller-manager-msgs

  • controllers : In gazebo we use various controllers to actuate different types of joints. We need to check for the following ones
    • joint state controllers : The output of the following command should contain ros-kinetic-joint-state-controller

      $ dpkg -l | grep joint-state

    • joint trajectory controllers : The output of the following command should contain ros-kinetic-joint-trajectory-controller

      $ dpkg -l | grep joint-trajectory

    • effort controllers : The output of the following command should contain ros-kinetic-effort-controllers

      $ dpkg -l | grep effort-controllers

    • velocity controllers : The output of the following command should contain ros-kinetic-velocity-controllers

      $ dpkg -l | grep velocity-controllers

Finally we need to check for PR2 robot related controllers to be able to launch the simulation. Use the following commands

$ dpkg -l | grep pr2-controller $ dpkg -l | grep pr2-mechanism

We expect to see the following names in the output of those commands

  • ros-kinetic-pr2-controller-manager,
  • ros-kinetic-pr2-controller-interface,
  • ros-kinetic-pr2-controller-configuration-gazebo,
  • ros-kinetic-pr2-controllers-msgs,
  • ros-kinetic-pr2-mechanism-controllers,
  • ros-kinetic-pr2-mechanism-diagnostics,
  • ros-kinetic-pr2-mechanism-models,
  • ros-kinetic-pr2-mechanism-msgs

If we have all of these packages installed in our computer, we will be able to launch the pr2 robot. That’s all for this post. Thanks for watching the video, please leave your comments and subscribe the channel if you want to see more such videos.

RELATED LINKS AND RESOURCES

▸ Original question: https://answers.ros.org/question/294245/roslaunch-pr2_gazebo-pr2_empty_worldlaunch/
▸ ROS Development Studio (RDS)
▸ Robot Ignite Academy
▸ ROS Control 101 online course

LIST OF ROS PACKAGES REQUIRED

1st- Gazebo – ROS controllers
* ros-kinetic-ros-control
* ros-kinetic-ros-controllers

* ros-kinetic-controller-interface
* ros-kinetic-controller-manager
* ros-kinetic-controller-manager-msgs

* ros-kinetic-gazebo-ros
* ros-kinetic-gazebo-ros-control

* ros-kinetic-joint-state-controller
* ros-kinetic-joint-trajectory-controller
* ros-kinetic-effort-controllers
* ros-kinetic-velocity-controllers

2nd- PR2 robot specific controllers

* ros-kinetic-pr2-controller-manager
* ros-kinetic-pr2-controllers
* ros-kinetic-pr2-controller-interface
* ros-kinetic-pr2-controller-configuration-gazebo

* ros-kinetic-pr2-mechanism-controllers
* ros-kinetic-pr2-mechanism
* ros-kinetic-pr2-mechanism-diagnostics
* ros-kinetic-pr2-mechanism-model


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-control-course-banner

Pin It on Pinterest