ROS-Subscriber

ROS-Subscriber

Study note for ROS subscriber.

Model of Topic

  • Publisher(turtlesim)
    • –[Message(geometry_msgs::Twist)]–>
  • Topic (/turtle1/pose)
    • –[Message(geometry_msgs::Twist)]–>
  • Subscriber(Pose Listener)

Programming realization

How to realize a subscriber

  • initialize ROS node
  • subscribe required topic
  • loop wait the msgs from topic, after receiving msgs, enter callback function
  • implement msgs processing in the callback function

Code

Also we put this node into function package learning_topic
Create velocity_publisher.cpp file in learning_topic/src:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <ros/ros.h>
#include <turtlesim/Pose.h>

void poseCallback(const turtlesim::Pose::ConstPtr& msg)
{
ROS_INFO("Turtle pose: x:%0.6f, y:%0.6f, ",msg->x,msg->y);
}

int main(int argc, char *argv[])
{
ros::init(argc, argv, "pose_subscriber");
ros::NodeHandle n;
ros::Subscriber pose_sub = n.subscribe("/turtle1/pose",10,poseCallback)
//queue also first in first thrown
//loop waiting for callback function, keep the endless loop
ros::spin();
return 0;
}

Note

  • Callback function must be sufficient, or newer data will be blocked

Configure the compile run of subscriber

Steps same as publisher
Add two lines to learning\_topic/CMakeLists.txt (in build part):

1
2
add_executable(velocity_publisher src/pose_subscriber.cpp)
target_link_libraries(pose_subsriber ${catkin_LIBRARIES})

Compile

1
2
3
4
5
6
7
$ cd ~/ROS_study/catkin_ws
$ catkin_make
$ source ./devel/setup.zsh
$ roscore
$ rosrun turtlesim turtlesim_node
$ rosrun learning_topic velocity_publisher
$ rosrun learning_topic pose_subscriber

The output of pose_subscriber:

1
2
3
4
5
...
[ INFO] [1650184199.757606156]: Turtle pose: x:3.100077, y:7.501662,
[ INFO] [1650184199.773327854]: Turtle pose: x:3.101826, y:7.493855,
[ INFO] [1650184199.790252785]: Turtle pose: x:3.103601, y:7.486054,
...
ROS-Publisher

ROS-Publisher

Study note for ROS publisher.

Model of Topic

  • Publisher(turtle Velocity)
    • –[Message(geometry_msgs::Twist)]–>
  • Topic (/turtle1/cmd_vel)
    • –[Message(geometry_msgs::Twist)]–>
  • Subscriber(turtlesim)

Programming realization

Take turtlesim as the example.
We write a program acting like a publisher and sending controlling messages.

Create package

1
2
$ cd catkin_ws/src
$ catkin_create_pkg learning_topic roscpp rospy std_msgs geometry_msgs turtlesim

can see:

1
2
$ ls
CMakeLists.txt include package.xml src

How to realize a publisher?

  • Initialize ROS node
  • register node info from ROS Master, including name of the topic and msg type
  • create message data
  • publish message at a specific frequency

Code

create velocity_publisher.cpp file in learning_topic/src

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <ros/ros.h>
#include <geometry_msgs/Twist.h>

int main(int argc, char *argv[])
{
//init the node
ros::init(argc,argv,"velocitypublisher");

//create node handle
ros::NodeHandle n;

//create a publisher, who publish topic names '/turtle1/cmd_vel', message type 'geometry_msgs:Twist', queue length 10
ros::Publisher turtle_vel_pub = n.advertise<geometry_msgs::Twist>("/turtle1/cmd_vel",10);

//set loop rate
ros::Rate loop_rate(10);
while (ros::ok()) {
//initialize geometry_msgs:Twist msg
geometry_msgs::Twist vel_msg;
vel_msg.linear.x = 0.5;
vel_msg.angular.z = 0.2;

//publish msgs
turtle_vel_pub.publish(vel_msg);
ROS_INFO("Publish turtle velocity command at %0.2f m/s, %0.2f rad/s",
vel_msg.linear.x,vel_msg.angular.z);

//delay
loop_rate.sleep();
}
return 0;
}

What is queue length?

  • msgs can be published very fast while the data transmission rate is limited, so the queue act as a buffer
  • first in, first thrown, keeping the remained msgs in the queue relatively new

Configure the compile rule of publisher

Steps:

  • set the code need to be complied and the generated excutable file
  • set the link library

Add two lines to learning\_topic/CMakeLists.txt (in build part):

1
2
add_executable(velocity_publisher src/velocity_publisher.cpp)
target_link_libraries(velocity_publisher ${catkin_LIBRARIES})

Compile

1
2
3
4
5
6
$ cd ~/ROS_study/catkin_ws
$ catkin_make
$ source ./devel/setup.zsh
$ roscore
$ rosrun turtlesim turtlesim_node
$ rosrun learning_topic velocity_publisher

Then, you can see turtle:

And outputs:

1
2
3
4
5
...
[ INFO] [1650088100.376299177]: Publish turtle velocity command at 0.50 m/s, 0.20 rad/s
[ INFO] [1650088100.476312726]: Publish turtle velocity command at 0.50 m/s, 0.20 rad/s
[ INFO] [1650088100.576304995]: Publish turtle velocity command at 0.50 m/s, 0.20 rad/s
...
ROS Orgmode Note

ROS Orgmode Note

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
Study note for ROS
* Core Concept
** Node and ROS Master
*** Node
implement functions for purposes
support various language
can have thousands of nodes
*** ROS Master
mange the registion and name of various nodes
support(trace and record) communication between different nodes
for nodes to find each other
provide parameter server(store global variables...)[[about parameter]]
** Communication between nodes
| | Topic | Service |
|--------------------+---------------------+----------------|
| sync | n | y |
| model | publish/subscribe | service/client |
| protocol | ROSTCP/ROSUDP | ROSTCP/ROSUDP |
| response | n | y |
| buffer | y | n |
| real-time | weak | strong |
| nodes relationship | multi/one to multi | one to multi |
| scene | data transformation | logic process |
*** Topic
Node(publisher)->Topic(/example)&Message_Tyoe(std_msgs/String)->other ROS nodes(subscriber)
Message: define the data type and struct of data, defined by .msg file
async
*** Service
C/S model(Client/Server)
client send requests, server return response data
defined by .srv file, defines the structure of the requests and response
ROS node(Service Server)
^ |response
request| v
ROS node(Service Client)
sync
** Parameter
<<about parameter>>
talker -> ROS master : setParam("foo",1)
listener -> ROS master: getParam("foo")
ROS master ->listener: {"foo",1}

multiple variable dictionary
for storing static nonbinary configuration, not suitable for dynamic
** File system
*** package
Basic unit in ROS, include the src of nodes, cfg, data def
*** package manifest
record the basic information of packages
*** Meta packages
orgnize multi packages for one common purpose
* Commond Line Tools
** rqt_graph
visualize tool
display the calculate process graph
** rosnode
display node information
*** rosnode list
list all node
default node /rosout
*** rosnode info /turtle_sim
show info of a node
** rostopic
usage like rosnode(list,info)
*** rostopic pub /../.. data_structure data
publish message as a topic
add -r num to repeat sending at rate num/s
** rosmsg
*** rosmsg show data_structure
show the data structure
** rosservice
| commond addition | |
|------------------------+-----------------------------------|
| list | list all service the node provide |
| call service_name data | |
** rosbag
| command addition | | | |
|-------------------------+-----------------------------------------------+--------+-----------------|
| record -a -O cmd_record | record the topic data in the system | -a:all | -O as a package |
| play cmd_record.bag | play the recorded data of previous simulation | | |
| | | | |
* setup workspace and function package
** workspace
*** overview
| src | source space | |
| build | build space | no need to touch |
| devel | develop space | script, executable file |
| install | install sapce | |

work space folder/
src/
CmakeLists.txt
package_1/
CmakeList.txt
package.xml
...
package_n/
CmakeList.txt
package.xml
...
build/
CATKIN_IGNORE
devel/
bin/
etc/
include/
lib/
share/
.catkin
env.bash
setup.bash
setup.sh
...
install/
bin/
etc/
include/
lib/
share/
.catkin
env.bash
setup.bash
setup.sh
...
*** setup
**** establish ws
mkdir -p ./catkin_ws/src
cd ./catkin_ws/src
catkin_init_workspace
**** compile ws
cd ./catkin_ws/
catkin_make -DPYTHON_EXECUTABLE=/usr/bin/python3
catkin_make install
**** set env variables
source devel/setup.bash
**** check env variables
echo $ROS_PACKAGE_PATHH
** fucntion package
*** setup
| establish package | cd ./src | |
| | catkin_create_pkg <pkg_name> [depend1] [depend2].. (rospy,roscpp,std_msgs) | |
| source env path | source devel/setup.bash | make sure that ros can detect the pkg |

*** package.xml
| label | description |
|------------------------------+-----------------------------------------------------|
| <name> | |
| <version> | |
| <description> | |
| <maintainer email=""> | maintainer's name and email |
| <license> | |
| <buildtool depend> | usually catkin |
| <build_depend>/<exec_depend> | package dependencies ,usually roscpp rospy std_msgs |
*** CmakeList.txt
TODO