07 Basic ROS Programming
07 Basic ROS Programming
ROS Programming
Textbook
P. 148~193
1
Contents
Textbook
P. 148~193
2
Things to know before programming ROS
3
Things to know before programming ROS
Quantity Unit Quantity Unit
• Standard unit angle radian length meter
frequency hertz
• SI unit force newton
mass kilogram
time second
power watt
current ampere
voltage volt
temperature celsius
• Coordinate representation Package
Object Naming rule
under_scored Ex) first_ros_package
example
• Programing rules
Enumeration type CamelCased Ex) enum ChoiceNumber
Function camelCased Ex) addTableEntry();
Method camelCased Ex) void setNumEntries(int32_t num_entries)
Constant ALL_CAPITALS Ex) const uint8_t DAYS_IN_A_WEEK = 7; 4
Types of message communication
5
ROS Message communication
Message communication
Node1
(Topics, Services, Actions, Parameters) Node2
Topic
Publisher Subscriber
Service request
Service server Service client
Service response
Parameter
parameter parameter
server
(ROS Master)
write read 6
Topic
Node1 Node2
Topic
Publisher Subscriber
7
Service
Node1 Node2
Service request
Service server Service client
Service response
8
Action
Node1 Node2
9
Parameter
Node1 Node2
Parameter
parameter parameter
server
(ROS Master)
write read 10
Now let’s write codes
Topic: publisher, subscriber
Service: service server, service client
11
Topic
Node1 Node2
Topic
Publisher Subscriber
12
Topic / Publisher / Subscriber
• ROS uses 'Topic' message communication for unidirectional
communication. In this tutorial, the transmitter is called "Publisher"
and the receiver is called "Subscriber".
1) Creating the package
$ cd ~/catkin_ws/src
$ catkin_create_pkg ros_tutorials_topic message_generation std_msgs roscpp
$ cd ros_tutorials_topic
$ ls
include → header file folder
src → source code folder
CMakeLists.txt → build configuration file
package.xml → package configuration file
13
Topic / Publisher / Subscriber
2) Modify the package configuration file (package.xml)
• One of the required ROS configuration files, package.xml, is an XML file containing package information
that describes the package name, author, license, and dependency package.
$ gedit package.xml
<?xml version="1.0"?>
<package>
<name>ros_tutorials_topic</name>
<version>0.1.0</version>
<description>ROS turtorial package to learn the topic</description>
<license>Apache License 2.0</license>
<author email="pyo@robotis.com">Yoonseok Pyo</author>
<maintainer email="pyo@robotis.com">Yoonseok Pyo</maintainer>
<url type="bugtracker">https://github.com/ROBOTIS-GIT/ros_tutorials/issues</url>
<url type="repository">https://github.com/ROBOTIS-GIT/ros_tutorials.git</url>
<url type="website">http://www.robotis.com</url>
14
Topic / Publisher / Subscriber
<buildtool_depend>catkin</buildtool_depend>
<build_depend>roscpp</build_depend>
<build_depend>std_msgs</build_depend>
<build_depend>message_generation</build_depend>
<run_depend>roscpp</run_depend>
<run_depend>std_msgs</run_depend>
<run_depend>message_runtime</run_depend>
<export></export>
</package>
15
Topic / Publisher / Subscriber
3) Modify build configuration file (CMakeLists.txt)
$ gedit CMakeLists.txt
cmake_minimum_required(VERSION 2.8.3)
project(ros_tutorials_topic)
## The catkin_package option describes the library, catkin build dependencies, and system dependent packages.
catkin_package(
LIBRARIES ros_tutorials_topic
CATKIN_DEPENDS std_msgs roscpp
)
16
Topic / Publisher / Subscriber
17
Topic / Publisher / Subscriber
4) Create message file
• Add the following option in the CMakeLists.txt file.
add_message_files(FILES MsgTutorial.msg)
• This commands means a message should be built based on MsgTutorial.msg when it is built.
$ roscd ros_tutorials_topic → Move to package folder
$ mkdir msg → Create a message folder named msg in the package
$ cd msg → Move to the msg folder you created
$ gedit MsgTutorial.msg → Create new MsgTutorial.msg file and modify contents
time stamp
int32 data
18
Topic / Publisher / Subscriber
5) Creating the Publisher Node
• Add the option to generate the following executable file in the CMakeLists.txt file.
add_executable(topic_publisher src/topic_publisher.cpp)
// Set the loop period. & Quot; 10 & quot; refers to 10 Hz and repeats at 0.1 second intervals
ros::Rate loop_rate(10);
20
Topic / Publisher / Subscriber
while (ros::ok())
{
msg.stamp = ros::Time::now(); // Put the current time in the msg's substamp message
msg.data = count; // Put the value of the variable count in the lower data message of msg
return 0;
}
21
Topic / Publisher / Subscriber
6) Create subscriber node
• In the CMakeLists.txt file, add the option to generate the following executable file.
add_executable(topic_subscriber src/topic_subscriber.cpp)
• That is, build a file named topic_subscriber.cpp to create an executable called topic_subscriber
$ roscd ros_tutorials_topic/src → Move to the src folder, which is the source folder of the package
$ gedit topic_subscriber.cpp → New source file and modify contents
#include "ros/ros.h" // ROS basic header file
#include "ros_tutorials_topic/MsgTutorial.h" // MsgTutorial message file header (Auto-generated after build)
// A message callback function, named ros_tutorial_msg below
// This is a function that works when a message is received
// The input message is supposed to receive the MsgTutorial message from the ros_tutorials_topic package
void msgCallback(const ros_tutorials_topic::MsgTutorial::ConstPtr& msg)
{
ROS_INFO("recieve msg = %d", msg->stamp.sec); // Disaplay stamp.sec message
ROS_INFO("recieve msg = %d", msg->stamp.nsec); // Disaplay stamp.nsec message
ROS_INFO("recieve msg = %d", msg->data); // Disaplay data message
} 22
Topic / Publisher / Subscriber
int main(int argc, char **argv) // Node main function
{
ros::init(argc, argv, "topic_subscriber"); // Initialize the node name
ros::NodeHandle nh; // Declare a node handle to communicate with the ROS system
return 0;
}
23
Topic / Publisher / Subscriber
7) Build the ROS node
• Build the message file, the publisher node, and the subscriber node in the
ros_tutorials_topic package with the following command:
24
Topic / Publisher / Subscriber
8) Execute Publisher [Note: Do not forget to run roscore before running the node.]
25
Topic / Publisher / Subscriber
• [Reference] rostopic
• You can use rostopic command to check the topic list, cycle, data
bandwidth, and content of the current ROS network.
$ rostopic list
/ros_tutorial_msg
/rosout
/rosout_agg
26
Topic / Publisher / Subscriber
9) Execute Subscriber
• Below command runs the topic_subscriber node of the
ros_tutorials_topic package
$ rosrun ros_tutorials_topic topic_subscriber
27
Topic / Publisher / Subscriber
10) Checking communication status of executed nodes
$ rqt_graph
$ rqt [Plugins] → [Introspection] → [Node Graph]
28
Source code
• We have created a publisher and a subscriber node that use topic, and executed them to
learn how to communicate between nodes. The relevant sources can be found at the github
address below.
• https://github.com/ROBOTIS-GIT/ros_tutorials/tree/master/ros_tutorials_topic
• If you want to apply it right away, you can clone the source code with the following
command in the catkin_ws/src folder and build it. Then run the topic_publisher and
topic_subscriber nodes.
$ cd ~/catkin_ws/src
$ git clone https://github.com/ROBOTIS-GIT/ros_tutorials.git
$ cd ~/catkin_ws
$ catkin_make
Node1 Node2
Service request
Service server Service client
Service response
30
Service / Service server / Service client
• A service is divided into the service server that responds only when
there is a request and the service client that requests and responds.
Unlike the topic, the service is a one-time message communication.
Therefore, when the request and the response of the service are
completed, the two connected nodes are disconnected.
• This service is often used as an instruction when a robot should
perform a specific operation or a node should generate events
according to certain conditions. In addition, since it is a one-time
communication method, it is very useful communication that can
replace the topic because of the small network load.
• In this lecture, it is aimed at creating a simple service file and creating
and executing a service server node and a service client node.
31
Service / Service server / Service client
• ROS uses message communication called 'Service' when bi-
directional(or synchronized) communication is needed. 'service
server' responds only when there is a request & 'service client'
requests and responds.
1) Creating the package
$ cd ~/catkin_ws/src
$ catkin_create_pkg ros_tutorials_service message_generation std_msgs roscpp
$ cd ros_tutorials_service
$ ls
include → header file folder
src → source code folder
CMakeLists.txt → build configuration file
package.xml → package configuration file
32
Service / Service server / Service client
2) Modify the package configuration file (package.xml)
• One of the required ROS configuration files, package.xml, is an XML file containing package information,
which describes the package name, author, license, and dependency package.
$ gedit package.xml
<?xml version="1.0"?>
<package>
<name>ros_tutorials_service</name>
<version>0.1.0</version>
<description>ROS turtorial package to learn the service</description>
<license>Apache License 2.0</license>
<author email="pyo@robotis.com">Yoonseok Pyo</author>
<maintainer email="pyo@robotis.com">Yoonseok Pyo</maintainer>
<url type="bugtracker">https://github.com/ROBOTIS-GIT/ros_tutorials/issues</url>
<url type="repository">https://github.com/ROBOTIS-GIT/ros_tutorials.git</url>
<url type="website">http://www.robotis.com</url>
33
Service / Service server / Service client
<buildtool_depend>catkin</buildtool_depend>
<build_depend>roscpp</build_depend>
<build_depend>std_msgs</build_depend>
<build_depend>message_generation</build_depend>
<run_depend>roscpp</run_depend>
<run_depend>std_msgs</run_depend>
<run_depend>message_runtime</run_depend>
<export></export>
</package>
34
Service / Service server / Service client
3) Modify the build configuration file (CMakeLists.txt)
$ gedit CMakeLists.txt
cmake_minimum_required(VERSION 2.8.3)
project(ros_tutorials_service)
## The catkin package option describes the library, catkin build dependencies, and system dependent packages.
catkin_package(
LIBRARIES ros_tutorials_service
CATKIN_DEPENDS std_msgs roscpp
)
35
Service / Service server / Service client
36
Service / Service server / Service client
4) Write service file
• Add the following options in the CMakeLists.txt file.
add_service_files(FILES SrvTutorial.srv)
38
Service / Service server / Service client
// Display the values of a and b used in the service request and the result value corresponding to the service
response
ROS_INFO("request: x=%ld, y=%ld", (long int)req.a, (long int)req.b);
ROS_INFO("sending back response: %ld", (long int)res.result);
return true;
}
39
Service / Service server / Service client
int main(int argc, char **argv) // Node main function
{
ros::init(argc, argv, "service_server"); // Initialize the node name
ros::NodeHandle nh; // Declare node handle
// service server declaration, using SrvTutorial service file from ros_tutorials_service package
// Declare the service server ros_tutorials_service_server
// The service name is ros_tutorial_srv and when there is a service request,
// Set up a function called calculation ros::ServiceServer ros_tutorials_service_server =
nh.advertiseService("ros_tutorial_srv", calculation);
return 0;
}
40
Service / Service server / Service client
6) Write service client node
• In the CMakeLists.txt file, add the option to generate the following executable file.
add_executable(service_client src/service_client.cpp)
• Build a file called service_client.cpp in the src folder to create an executable called
service_client
$ roscd ros_tutorials_service/src → Move to the src folder, which is the source folder for the package
$ gedit service_client.cpp → New source file and modify contents
41
Service / Service server / Service client
int main(int argc, char **argv) // Node main function
{
ros::init(argc, argv, "service_client"); // Initialize the node name
ros::NodeHandle nh; // Declare a node handle to communicate with the ROS system
// stores the parameters used as input when the node is executed as a service request value in each of a and b
srv.request.a = atoll(argv[1]);
srv.request.b = atoll(argv[2]);
// Request the service, and if the request is accepted, display the response value
if (ros_tutorials_service_client.call(srv))
{
ROS_INFO("send srv, srv.Request.a and b: %ld, %ld", (long int)srv.request.a, (long int)srv.request.b);
ROS_INFO("receive srv, srv.Response.result: %ld", (long int)srv.response.result);
}
else
{
ROS_ERROR("Failed to call service ros_tutorial_srv");
return 1;
}
return 0;
}
43
Service / Service server / Service client
7) Build the ROS node
• Use the following command to build the service file, service server
node, and client node of the ros_tutorials_service package
$ cd ~/catkin_ws && catkin_make → move to catkin folder and run catkin build
44
Service / Service server / Service client
8) Run the service server [Note: Do not forget to run roscore before running the node.]
• The service server has programmed to wait until there is a service
request. Therefore, when the following command is executed, the
service server waits for a service request.
45
Service / Service server / Service client
9) Run the service client
• After running the service server, run the service client with the following command:
• The client is programmed to send parameter 2 and 3 as the service request value.
• 2 and 3 correspond to a and b values in the service, respectively, and receive a sum
of them(5) as a response value.
• In this case, numbers are used as execution parameters, but in actual use, an
instruction, a value to be calculated, a variable for a trigger may be used as a service
request value.
46
Service / Service server / Service client
[Reference] rqt_graph
• Service is one-time unlike the topic in the figure below, so it can
not be visualized in rqt_graph.
47
Service / Service server / Service client
[Reference] How to use rosservice call command
• The service request can be executed by the service client node,
but there is also a method called "rosservice call" or using rqt's
ServiceCaller.
• Let's look at how to use rosservice call.
48
Service / Service server / Service client
[Reference] How to use GUI tool, Service Caller
• Run the ROS GUI tool rqt.
$ rqt
49
One more!!!
• A single node can act as multiple publishers, subscribers, service
servers, and service clients!
• Use the node as you wish
ros::NodeHandle nh;
50
Source code
• We have seen how to communicate services between nodes by creating
service servers and client nodes and running them. The relevant source can
be found at the address of GitHub below.
• https://github.com/ROBOTIS-GIT/ros_tutorials/tree/master/ros_tutorials_service
• If you want to try it right away, you can clone the source code with the
following command in the catkin_ws/src folder and build. Then run the
service_server and service_client nodes.
$ cd ~/catkin_ws/src
$ git clone https://github.com/ROBOTIS-GIT/ros_tutorials.git
$ cd ~/catkin_ws
$ catkin_make
52
Parameters
1) Create nodes using parameters
• In this section, we are going to modify the service_server.cpp to use a parameter to select an
arithmetic operator, rather than merely adding a and b entered as service requests.
• Let's modify the service_server.cpp source in the following order:
$ roscd ros_tutorials_service/src → Go to the src folder, which is the source code folder of the package
$ gedit service_server.cpp → Modify source file contents
#include "ros/ros.h" // ROS basic header file
#include "ros_tutorials_service/SrvTutorial.h" // SrvTutorial.h" // SrvTutorial Service file header (auto-generated after build)
54
Parameters
case DIVISION:
if(req.b == 0){
res.result = 0; break;
}
else{
res.result = req.a / req.b; break;
}
default:
res.result = req.a + req.b; break;
}
// Display the values of a and b used in the service request and the result value corresponding to the service
response
ROS_INFO("request: x=%ld, y=%ld", (long int)req.a, (long int)req.b);
ROS_INFO("sending back response: [%ld]", (long int)res.result);
return true;
}
55
Parameters
// service server declaration, using SrvTutorial service file from ros_tutorials_service package
// Create the service server service_server. The service name is "ros_tutorial_srv"
// Set up to execute a function called calculation when there is a service request.
ros::ServiceServer ros_tutorial_service_server = nh.advertiseService("ros_tutorial_srv", calculation);
56
Parameters
ros::Rate r(10); // 10 hz
while (1)
{
nh.getParam("calculation_method", g_operator); // Change the operator to the value received from the parameter
ros::spinOnce(); // Callback function processing routine
r.sleep(); // sleep processing for routine iteration
}
return 0;
}
• Note the usage of setParam and getParam regarding parameters.
[Reference] Available as parameter Type
• Parameters can be set as integers, floats, boolean, string, dictionaries, list, and so on.
• For example, 1 is an integer, 1.0 is a float, "Internet of Things" is a string, true is a
boolean, [1,2,3] is a list of integers, a: b, c: d is a dictionary.
57
Parameters
2) Build and run the node
$ cd ~/catkin_ws && catkin_make
$ cd ~/catkin_ws/src
$ git clone https://github.com/ROBOTIS-GIT/ros_tutorials.git
$ cd ~/catkin_ws
$ catkin_make
60
roslaunch
61
How to use roslaunch
• rosrun is a command to execute a node.
• roslaunch can run one or more defined nodes.
63
How to use roslaunch
<launch>
<node pkg="ros_tutorials_topic" type="topic_publisher" name="topic_publisher1"/>
<node pkg="ros_tutorials_topic" type="topic_subscriber" name="topic_subscriber1"/>
<node pkg="ros_tutorials_topic" type="topic_publisher" name="topic_publisher2"/>
<node pkg="ros_tutorials_topic" type="topic_subscriber" name="topic_subscriber2"/>
</launch>
• The <launch> tag describes required tags to run the node with
roslaunch command. The <node> tags describe the node to be
run by roslaunch. Options include pkg, type, and name.
• pkg Package name
• type The name of the node to actually execute (node name)
• name Set the name (executable name) to be appended when the node
corresponding to the above type is executed, usually set to be the same
as type, but you can set it to change the name when you need it.
64
How to use roslaunch
• Once you have created the roslaunch file, run union.launch as
follows.
$ roslaunch ros_tutorials_topic union.launch --screen
65
How to use roslaunch
• Execution result?
$ rosnode list
/topic_publisher1
/topic_publisher2
/topic_subscriber1
/topic_subscriber2
/rosout
66
How to use roslaunch
• The problem is that, unlike the initial intention that "two separate messages
are communicated by driving two publisher nodes and subscriber nodes,"
rqt_graph shows that they are subscribing to each other's messages.
• This is because we simply changed the name of the node to be executed, but
did not change the name of the message to be used.
• Let's fix this problem with another roslaunch namespace tag.
67
How to use roslaunch
• Let’s modify union.launch
$ roscd ros_tutorials_service/launch
$ gedit union.launch
<launch>
<group ns="ns1">
<node pkg="ros_tutorials_topic" type="topic_publisher" name="topic_publisher"/>
<node pkg="ros_tutorials_topic" type="topic_subscriber" name="topic_subscriber"/>
</group>
<group ns="ns2">
<node pkg="ros_tutorials_topic" type="topic_publisher" name="topic_publisher"/>
<node pkg="ros_tutorials_topic" type="topic_subscriber" name="topic_subscriber"/>
</group>
</launch>
68
How to use roslaunch
• The appearance of executed nodes after change
69
How to use roslaunch
2) launch tag
<launch> Points to the beginning and end of the roslaunch syntax.
<node> This is a tag for node execution. You can change the package, node name, and execution name.
<machine> You can set the name, address, ros-root, and ros-package-path of the PC running the node.
<include> You can import another package or another launch belonging to the same package and run it as a launch file.
<remap> You can change the name of the ROS variable in use by the node name, topic name, and so on.
<env> Set environment variables such as path and IP. (Almost never used)
<param> Set the parameter name, type, value, etc.
<rosparam> Check and modify parameter information such as load, dump, and delete as the rosparam command..
<group> Set the parameter name, type, value, etc.
<test> Used to test the node
Similar to <node>, but with options available for testing.
<arg> You can define a variable in the launch file, so you can change the parameter when you run it like this:.
<launch>
<arg name="update_ period" default="10" />
<param name="timing" value="$(arg update_ period)"/>
</launch>
71
72
Question Time!
Advertisement #1
Download link
Language:
English, Chinese, Japanese, Korean
Direct Link
Advertisement #3
www.robotsource.org
The ‘RobotSource’ community is the space for people making robots.