Robot Operating System Cookbook
上QQ阅读APP看书,第一时间看更新

How to do it…

It is time for us to practice what we have learned until now. Following, we will see examples to practice, along with creating packages, using nodes, using parameter servers, and moving a simulated robot with turtlesim.

To run ROS master and parameter server, use the following command:

$ roscore

In the following screenshot, we can see a log file is created inside the /home/kbipin/.ros/log folder for collecting logs from ROS nodes, in the first part of the screen. This file can be used for debugging purposes.

The next part shows that the theroslaunch command is executing a ROS launch file called roscore.xml. When a launch file executes, it automatically starts rosmaster and the ROS parameter server. The roslaunch command is a Python script, which can start rosmaster and the ROS parameter server whenever it tries to execute a launch file.

It also shows the address of the ROS parameter server within the port:

Terminal messages while running the roscore command

In the third part of the screen, we can see parameters such as rosdistro and rosversion displayed on the terminal. These parameters are displayed when the roslaunch command executes roscore.xml.

In the fourth section, we can see that the rosmaster node is started using ROS_MASTER_URI, which is an environment variable. As discussed in the previous section, it provides the address. In the last part, we can see that the rosout node is started, which will start subscribing the /rosout topic and rebroadcasting into /rosout_agg.

When the roscore command is executed, initially, it checks the command line argument for a new port number for rosmaster. If it gets the port number, it will start listening to the new port number, otherwise it will use the default port. This port number and the roscore.xml launch file will pass to the roslaunch system. The roslaunch system is implemented in a Python module; it will parse the port number and launch the roscore.xml file.

The content of the roscore.xml file is as follows:

<launch> 
  <group ns="/"> 
    <param name="rosversion" command="rosversion roslaunch" /> 
    <param name="rosdistro" command="rosversion -d" /> 
    <node pkg="rosout" type="rosout" name="rosout" respawn="true"/> 
  </group> 
</launch> 

In the roscore.xml file, we can see the ROS parameters and nodes are encapsulated in a group XML tag with a / namespace. The group XML tag indicates that all the nodes inside this tag have the same settings. The two parameters, called rosversion and rosdistro, store the output of the rosversion roslaunch and rosversion -d commands using the command tag, which is a part of the ROS param tag. The command tag will execute the command mentioned on it and store the output of the command in these two parameters.

The rosout node will collect log messages from other ROS nodes and store them in a log file, and will also rebroadcast the collected log messages to another topic. The topic /rosout is published by ROS nodes working using ROS client libraries such as roscpp and rospy and this topic is subscribed by the rosout node, which rebroadcasts the message in another topic called /rosout_agg. This topic has an aggregate stream of log messages.

Let's check the ROS topics and ROS parameters created after running roscore. The following command will list the active topics on the Terminal:

$ rostopic list

The list of topics is as follows:

/rosout
/rosout_agg

The following command lists out the parameters available when running roscore. The following is the command to list the active ROS parameter:

$ rosparam list

The parameters are mentioned here; they have the ROS distribution name, version, and address of roslaunch server and run_id, where run_id is a unique ID associated with a particular run of roscore:

/rosdistro 
/roslaunch/uris/host_ubuntu__33187 
/rosversion 
/run_id 

A list of the ROS services generated during the running of roscore can be checked using the following command:

$ rosservice list

The list of services running is as follows:

/rosout/get_loggers 
/rosout/set_logger_level 

These ROS services are generated for each ROS node for setting the logging levels. After understanding the basics of ROS master, the parameter server, and roscore, we can revisit the concepts of ROS nodes, topics, messages, and services in more detail.

As discussed in the previous section, nodes are executable programs, and, once built, these executables can be found in the devel space. To practice and learn about nodes, we will use a typical package called turtlesim.

The turtlesim package is preinstalled with the desktop installation by default; if not, we can install it with the following command:

$ sudo apt-get install ros-kinetic-ros-tutorials

In the previous section, we have started the roscore in one of our open terminals.

Now, we are going to start a new node in another Terminal with rosrun, using the following command:

$ rosrun turtlesim turtlesim_node

We will then see a new window appear with a little turtle in the middle, as shown in the following screenshot:



Turtlesim

We are going to get information about the nodes that are running, using the following command:

$ rosnode list

We will see a new node with the name /turtlesim. We can get information about the node using the following command:

$ rosnode info /turtlesim

The previous command will print the following information:

Node information

In the information, we can see the publications (topics), subscriptions (topics), and services (srv) that the node has and the unique name of each.

In the next section, we will learn how to interact with the node using topics and services.

We have the rostopic tool to interact with and get information about topics. Using the rostopic pub, we can publish topics that can be subscribed to by any node. We have to publish the topic with the correct name.

We will start the turtle_teleop_key node in the turtlesim package with the following command:

$ rosrun turtlesim turtle_teleop_key

With this node, we can move the turtle using the arrow keys, as shown in the following screenshot:

Turtlesim teleoperation

Let us understand why the turtle moves when turtle_teleop_key is running. Looking into the information provided by the rosnode information about the /teleop_turtle and /turtlesim nodes, we can notice that there exists a topic called /turtle1/cmd_vel [geometry_msgs/Twist] in the publications section of the /teleop_turtle node, and in the subscriptions section of the /turtlesim node, there is /turtle1/cmd_vel [geometry_msgs/Twist]:

$ rosnode info /teleop_turtle

Teleop node information

This shows that the first node is publishing a topic that the second node can subscribe to. We can observe the topic list using the following command line:

$ rostopic list

The output will be as follows:

/rosout 
/rosout_agg 
/turtle1/colour_sensor 
/turtle1/cmd_vel 
/turtle1/pose 

We can get the information sent by the node using the echo parameter by running the following command:

$ rostopic echo /turtle1/cmd_vel

We will see something similar to the following output:

--- 
linear: 
x: 0.0 
y: 0.0 
z: 0.0 
angular: 
x: 0.0 
y: 0.0 
z: 2.0 
--- 

Similarly, we can get the type of message sent by topic using the following command line:

$  rostopic type /turtle1/cmd_vel

The output will be as follows:

Geometry_msgs/Twist 

For getting the message fields, we can use the following command:

$ rosmsg show geometry_msgs/Twist

We will get something similar to the following output:

geometry_msgs/Vector3 linear 
  float64 x 
  float64 y 
  float64 z 
geometry_msgs/Vector3 angular 
  float64 x 
  float64 y 
  float64 z 

This is useful information. We can publish topics using the rostopic pub [topic] [msg_type] [args] command:

$ rostopic pub /turtle1/cmd_vel  geometry_msgs/Twist -r 1 -- "linear: 
x: 1.0 
y: 0.0 
z: 0.0 
angular: 
x: 0.0 
y: 0.0 
z: 1.0" 

We can observe the turtle doing a curve, as shown in the following screenshot:

Turtle doing a curve

Services are another method through which nodes can communicate with each other, and which allow nodes to send a request and receive a response. As discussed in the preceding section, Understating ROS services, we have the rosservice tool to interact with and get information about services.

The following command will list the services available for the turtlesim node (run roscore and the turtlesim node if they are not currently running):

$ rosservice list

The following output will be shown:

/clear
/kill
/reset
/rosout/get_loggers
/rosout/set_logger_level
/spawn
/teleop_turtle/get_loggers
/teleop_turtle/set_logger_level
/turtle1/set_pen
/turtle1/teleport_absolute
/turtle1/teleport_relative
/turtlesim/get_loggers
/turtlesim/set_logger_level

The following command can be used to get the type of any service—for example, the /clear service:

$ rosservice type /clear

The following output will be shown:

std_srvs/Empty

To invoke a service, we can use rosservice call [service] [args]. For example, the following command will invoke the /clear service:

$ rosservice call /clear

In the turtlesim window, we can now see that the lines created by the movements of the turtle will be deleted.

Now, we can look into another service, for example, the /spawn service. This will create another turtle at a given location and with a specified orientation. Let's start with the following command:

$ rosservice type /spawn | rossrv show

The output will be as follows:

float32 x
float32 y
float32 theta
string name
---
string name

The preceding command is the same as the following commands (for more detail, search in Google for piping Linux):

$ rosservice type /spawn
$ rossrv show turtlesim/Spawn

We will get something similar to the output shown by the previous command. We can know how to invoke the /spawn service by knowing its fields. It requires the position of x and y, the orientation (theta), and the name of the new turtle:

$ rosservice call /spawn 3 3 0.2 "new_turtle"

We will obtain the following output in the Turtlesim window:

Turtlesim spawn

The ROS parameter server is used to store data at a central location that is accessible to all running nodes in a ROS computational network. As we have learned in the preceding section, Understating ROS parameter server, we have the rosparam tool to manage parameter servers.

For example, we can see the parameters in the server that are used by all currently running nodes:

$ rosparam list

We will obtain the following output:

/background_b 
/background_g 
/background_r 
/rosdistro 
/roslaunch/uris/host_ubuntu__33187 
/rosversion 
/run_id 

The background parameters of the turtlesim node define the color of the windows, which is initially blue. We can read a value by using the get parameter:

$ rosparam get /background_b

Similarly, to set a new value, we can use the set parameter:

$ rosparam set /background_b 120

One of the most important features of rosparam is the dump parameter, which is used to save or load the contents of the parameter server.

To save the contents of a parameter server, we can use rosparam dump [file_name] as follows:

$ rosparam dump save.yaml

Similarly, to load a file with new data for a parameter server, we can use rosparam load [file_name] [namespace], as follows:

$ rosparam load load.yaml namespace