Reference link: Gu Yueju introduction to ROS lecture 21 Lecture 7 8 10 11 12
1. Topic communication
1.1 Topic - asynchronous communication mechanism
- An important bus used to transmit data between nodes
- Using the publish / subscribe model, data is transmitted from the publisher to the subscriber. Subscribers or publishers of the same topic can be different.
1.2 Message - topic data
- It has certain data types and data structures, including standard types and user-defined classes provided by ROS
- Use the. msg file definition of the facial features of the programming language to compile and generate the corresponding code file in the programming
It should be noted that ROSMaster only plays the role of a matchmaking agency, that is, it just lets publishers and subscribers know each other's existence. After publishers and subscribers connect, ROSMaster is no longer necessary, but it is no longer feasible to access other parameter data or other nodes after losing ROSMaster.
2. Use turtle games to understand topics
2.1 keyboard control
Enter the following command to run turnlesim under the turnlesim function package_ Node to open the turtle game:
rosrun turtlesim turtlesim_node
Re input
rosrun turtlesim turtle_teleop_key
At this time, the movement of the turtle can be controlled through the keyboard.
At this time, enter the command rqt graph to view the relationship of nodes in ros:
At this time, the turnlesim is the simulation node, teleop_turtle is a keyboard control node. The two nodes communicate through the topic "/ turtle 1 / cmd_vel".
2.2 use the command to move the turtle
First, you can use the topic related command rostopic and enter the corresponding parameters to view the topic
Enter the following command to send a topic:
rostopic pub /turtle1/cmd_vel(Topic name)
After entering the command, double-click the TAB key twice to pop up the specific data in the message structure and message content, and set relevant parameters.
2.3 topic record and topic reproduction
Topic record: rosbag record -a -O cmd_record
Topic recurrence: rosbag play cmd_record.bag
Where, - a is all, save all familiar data, and - O is to save all data as cmd_record file.
3. Programming implementation of Publisher publisher
3.1 procedures for creating function packages and publishers
Create a function package in the src file in the workspace
catkin_create_pkg Name of the created function package dependency 1 dependency 2 corresponding to the function package
Add velocity to src in the function package_ Publisher.cpp's source file:
You can use the command: sudo touch test.cpp. Test.cpp is the file name.
The command sudo chmod 777 test.cpp modifies the file permissions.
The source files are as follows:
/*********************************************************************** Copyright 2020 GuYueHome (www.guyuehome.com). ***********************************************************************/ /** * This routine publishes turnle1 / CMD_ Vel topic, message type, geometry_msgs::Twist */ #include <ros/ros.h> #include <geometry_msgs/Twist.h> int main(int argc, char **argv) { // ROS node initialization ros::init(argc, argv, "velocity_publisher"); // Create node handle ros::NodeHandle n; // Create a Publisher with the publication name / turnle1 / CMD_ The topic of vel and the message type is geometry_msgs::Twist, queue length 10 ros::Publisher turtle_vel_pub = n.advertise<geometry_msgs::Twist>("/turtle1/cmd_vel", 10); // Sets the frequency of the cycle ros::Rate loop_rate(10); int count = 0; while (ros::ok()) { // Initialize geometry_msgs::Twist type message geometry_msgs::Twist vel_msg; vel_msg.linear.x = 0.5; vel_msg.angular.z = 0.2; // Release news turtle_vel_pub.publish(vel_msg); ROS_INFO("Publsh turtle velocity command[%0.2f m/s, %0.2f rad/s]", vel_msg.linear.x, vel_msg.angular.z); // Delay according to cycle frequency loop_rate.sleep(); } return 0; }
How to implement a publisher?
- Initialize ros node
- Register the node information with the ROS Master, including the published topic name and the message type in the topic
- Create message data
- Circularly publish messages at a certain frequency
3.2 configuring publisher Code Compilation Rules
In CMakeLists.txt under the function pack, modify the Compilation Rules under build:
##Add cmake target dependency for executable ##Same as above add_executable(velocity_publisher src/velocity_publisher.cpp) ##Specify the library to link to or executable target target_link_libraries(velocity_publisher ${catkin_LIBRARIES})
3.3 compile and run publisher
Compile in workspace:
catkin_make
Add environment variable:
source devel/setup.bash
Start ros:
roscore
Start the turtle simulator:
rosrun turtlesim turtlesim_node
Run Publisher:
rosrun learning_pkg velocity_publisher
Leraning here_ PKG is the name of the function package, velocity_publisher is the name when you create node initialization in the program.
4. Programming implementation of Subscriber
4.1 subscriber procedures
Subscriber, pose_ The C + + program of subscriber.cpp is as follows:
/*********************************************************************** Copyright 2020 GuYueHome (www.guyuehome.com). ***********************************************************************/ /** * This routine will subscribe to / turnle1 / pose topic, and the message type is turnlesim:: pose */ #include <ros/ros.h> #include "turtlesim/Pose.h" // After receiving the subscribed message, it will enter the message callback function void poseCallback(const turtlesim::Pose::ConstPtr& msg) { // Print the received message ROS_INFO("Turtle pose: x:%0.6f, y:%0.6f", msg->x, msg->y); } int main(int argc, char **argv) { // Initialize ROS node ros::init(argc, argv, "pose_subscriber"); // Create node handle ros::NodeHandle n; // Create a Subscriber, subscribe to the topic named / turnle1 / pose, and register the callback function poseCallback ros::Subscriber pose_sub = n.subscribe("/turtle1/pose", 10, poseCallback); // Loop waiting callback function ros::spin(); return 0; }
- Initialize ROS node
- Subscribe to required topics
- Loop and wait for the topic message. After receiving the message, enter the callback function
- Complete message processing in callback function
4.2 adding Compilation Rules
add_executable(pose_subscriber src/pose_subscriber.cpp) target_link_libraries(pose_subscriber ${catkin_LIBRARIES})
4.3 compiling and running subscribers
Compile in workspace:
catkin_make
Add environment variable:
source devel/setup.bash
Start ros:
roscore
Start the turtle simulator:
rosrun turtlesim turtlesim_node
Run Publisher:
rosrun learning_pkg velocity_publisher
Run subscriber:
rosrun learning_pkg pose_subscriber
The publisher publishes the topic to make the turtle move. The subscriber subscribes to the pose topic brought by turtle 1 and outputs the current coordinates of the turtle, as shown in the figure. The figure on the left shows the subscriber and the figure on the right shows the publisher:
5. Definition and use of topic messages
5.1 customized topic messages
5.1.1 definition msg file
Create a new folder under the function Pack: msg for easy viewing. The folder name cannot be replaced at will. CmakeLists may make errors during compilation.
Create a new person.msg file in the MSG folder. In order to facilitate the next configuration, it is best not to change the file name, and it is all lowercase. Add the following contents. The following contents are the definition of the data interface:
string name uint8 sex uint8 age uint8 unknown = 0 uint8 male = 1 uint8 female = 2
Next, you need to add some rules according to the definition of the data interface.
5.1.2 add function package dependency in package.xml
Add a function package dependency of the dynamic generator, and add the following contents to package.xml:
<build_depend>message_generation</build_depend> <exec_depend>message_runtime</exec_depend>`
As shown in the figure:
The first is compilation dependency, which depends on a function package that dynamically generates message,
The second is run dependency
5.1.3 add compilation options in CMakeLists.txt
-
Add the previously added function packages to find_ In package
-
Add a configuration item to compile msg files into different program files
The first addition is to add a message interface
The second is to explain which packages you need to rely on when compiling Person.msg. -
At catkin_ Create a message runtime dependency in the package
5.2 adding programs
person_subscriber.cpp
/*********************************************************************** Copyright 2020 GuYueHome (www.guyuehome.com). ***********************************************************************/ /** * This routine will subscribe to / person_info topic, custom message type, learning_topic::Person */ #include <ros/ros.h> #include "learning_pkg/Person.h" // After receiving the subscribed message, it will enter the message callback function void personInfoCallback(const learning_pkg::Person::ConstPtr& msg) { // Print the received message ROS_INFO("Subcribe Person Info: name:%s age:%d sex:%d", msg->name.c_str(), msg->age, msg->sex); } int main(int argc, char **argv) { // Initialize ROS node ros::init(argc, argv, "person_subscriber"); // Create node handle ros::NodeHandle n; // Create a Subscriber named / person_info topic, register the callback function personInfoCallback ros::Subscriber person_info_sub = n.subscribe("/person_info", 10, personInfoCallback); // Loop waiting callback function ros::spin(); return 0; }
person_publisher.cpp
/*********************************************************************** Copyright 2020 GuYueHome (www.guyuehome.com). ***********************************************************************/ /** * This routine will publish / person_info topic, custom message type, learning_topic::Person */ #include <ros/ros.h> #include "learning_pkg/Person.h" int main(int argc, char **argv) { // ROS node initialization ros::init(argc, argv, "person_publisher"); // Create node handle ros::NodeHandle n; // Create a Publisher named / person_ The topic of info and the message type is learning_topic::Person, queue length 10 ros::Publisher person_info_pub = n.advertise<learning_pkg::Person>("/person_info", 10); // Sets the frequency of the cycle ros::Rate loop_rate(1); int count = 0; while (ros::ok()) { // Initialize learning_ Topic:: message of type person learning_pkg::Person person_msg; person_msg.name = "Tom"; person_msg.age = 18; person_msg.sex = learning_pkg::Person::male; // Release news person_info_pub.publish(person_msg); ROS_INFO("Publish Person Info: name:%s age:%d sex:%d", person_msg.name.c_str(), person_msg.age, person_msg.sex); // Delay according to cycle frequency loop_rate.sleep(); } return 0; }
Please pay attention to modifying the header file. The header file has the corresponding function package name and header file. Pay attention to case.
5.3 configuring Compilation Rules for publishers and subscribers
Similar to the above, the difference is that two statements are added. Because some code is dynamically generated, there needs to be a dependency between the executable file and the dynamically generated program.
5.4 compilation and operation
Compile in workspace:
catkin_make
Start ros:
roscore
Run Publisher:
rosrun learning_pkg person_publisher
Run subscriber:
rosrun learning_pkg person_subscriber
The results are shown in the figure below: