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.
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 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.
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.
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.
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.
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.
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
—
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.
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.
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
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.
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.