The definition and use of topic messages
1 Introduction
In the previous two articles "Programming implementation of publisher publisher" and "subscriber Programming Implementation of Subscriber》Learn how publisher and subscriber publish and subscribe to messages. But whether it is the Twist message published by the publisher or the turtle position post information subscribed by the subscriber, they have been defined in ROS and we can use them directly. Then during our own development process, when these ROS-defined messages cannot meet our needs, we can define the message types ourselves. The following is to complete the customization of the message.
2. Model
3. Start customizing messages
Step 1: Define msg file
Create a new folder in the learning_topic
directory to store subsequent message files. Enter the folder and open the command line in the folder, and use the command to create a new file. msg
touch Person.msg
Person.msg
Open the file, enter the following and save:
string name
uint8 sex
uint8 age
uint8 unknown = 0
uint8 male = 1
uint8 female = 2
What is written here is not cpp or python. But it will be automatically compiled into cpp or python by ros during the compilation process.
Step 2: Add function package dependencies in package.xml
Openinglearning_topic
Text item addedpackage.xml
Text item.
If your computer has a browser installed, the xml file may be opened by the browser by default and cannot be edited. You can open the command line in this directory and enter the
gedit package.xml
command to open the file.
Add the following statement at the bottom as shown in the picture and save:
<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>
<build_depend> is used to add compilation dependencies, add here
message_generation
Function package
<exec_depend< is used to add execution dependencies, add here< /span>message_runtime
Function package
Step 3: Add compilation options to CMakeLists.txt
Openinglearning_topic
Text item addedCMakeLists.txt
.
- Add to the top
find_package
: This step is to add function package dependencies. ----- -----message_generation
- Find the position
Declare ROS dynamic reconfigure parameters
and add the following sentence above:
add_message_files(FILES Person.msg)
generate_messages(DEPENDENCIES std_msgs)
-
The first sentence tells the compiler that
Person.msg
is the message interface we defined -
The second sentence tells the compiler which libraries/packages it needs to depend on when compiling
Person.msg
the file. Here we need to rely onstd_msgs
. What we just wrote likestring
,uint8
is instd_msgs
defined in.
-----
- Find
catkin specific configuration
(that is, above## Build ##
), add the following statement at the location shown (I am special here, the commented out statement directly above is the same as The statements to be added are exactly the same. In this case, you can directly uncomment that sentence without adding a new statement)
CATKIN_DEPENDS geometry_msgs roscpp rospy std_msgs turtlesim
After completing the above three steps, save and exit.
Go back to the root directory of the workspacecatkin_ws
, open the command line, and enter the commandcatkin_make
to compile.
After is compiled successfully, you can find the file you just wrote under the /learning_topic/devel/include/learning_topic/
path and it has been compiled into document. Person.msg
Person.h
Step 4: Write cpp program
Create two cpp files in the path shown in the figure. code show as below.
person_publisher.cpp:
/**
* 该例程将发布/person_info话题,自定义消息类型learning_topic::Person
*/
#include <ros/ros.h>
//!!!!!关键!!!!!
#include "learning_topic/Person.h"
int main(int argc, char **argv)
{
// ROS节点初始化
ros::init(argc, argv, "person_publisher");
// 创建节点句柄
ros::NodeHandle n;
// 创建一个Publisher,发布名为/person_info的topic,消息类型为learning_topic::Person,队列长度10
//!!!!!关键!!!!!
ros::Publisher person_info_pub = n.advertise<learning_topic::Person>("/person_info", 10);
// 设置循环的频率
ros::Rate loop_rate(1);
int count = 0;
while (ros::ok())
{
// 初始化learning_topic::Person类型的消息
learning_topic::Person person_msg;
person_msg.name = "Tom";
person_msg.age = 18;
person_msg.sex = learning_topic::Person::male;
// 发布消息
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);
// 按照循环频率延时
loop_rate.sleep();
}
return 0;
}
person_subscriber.cpp:
/**
* 该例程将订阅/person_info话题,自定义消息类型learning_topic::Person
*/
#include <ros/ros.h>
//!!!!!关键!!!!!
#include "learning_topic/Person.h"
// 接收到订阅的消息后,会进入消息回调函数
void personInfoCallback(const learning_topic::Person::ConstPtr& msg)
{
// 将接收到的消息打印出来
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)
{
// 初始化ROS节点
ros::init(argc, argv, "person_subscriber");
// 创建节点句柄
ros::NodeHandle n;
// 创建一个Subscriber,订阅名为/person_info的topic,注册回调函数personInfoCallback
//!!!!!关键!!!!!
ros::Subscriber person_info_sub = n.subscribe("/person_info", 10, personInfoCallback);
// 循环等待回调函数
ros::spin();
return 0;
}
After the cpp file is written, write the justCMakeLists.txt
file again and configure the cpp content just written.
Find above the ## Install ##
position, add the following statement, and save.
Note: Compared with the previous configuration
CMakeLists.txt
, there are moreadd_dependencies
statements to make the executable file (the work done by the first two sentences) and Dynamically generated files generate dependencies
add_executable(person_publisher src/person_publisher.cpp)
target_link_libraries(person_publisher ${
catkin_LIBRARIES})
add_dependencies(person_publisher ${
PROJECT_NAME}_generate_messages_cpp)
add_executable(person_subscriber src/person_subscriber.cpp)
target_link_libraries(person_subscriber ${
catkin_LIBRARIES})
add_dependencies(person_subscriber ${
PROJECT_NAME}_generate_messages_cpp)
Step 5: Compile and run
The steps are exactly the same as before. (If you have modified the .bashrc file before, you can omit the source devel/setup.bash
statement)
cd ~/catkin_ws
catkin_make
source devel/setup.bash
roscore
rosrun learning_topic person_subscriber
rosrun learning_topic person_publisher
As you can see, the message sender publisher and the message receiver subscriber have established a relationship.
If the environment variables have been modified and the executable file corresponding to the function package can be found, but the function package name cannot be automatically completed when executing the
rosrun
command, execute it again at this time< /span>rospack list
command is enough.
4. Little knowledge
ROS Master helps with the creation and linking of nodes. Once a node is successfully created and linked, it is no longer affected by ROS Master.
At this time, if you press Exit on the terminal executing the commandroscore
(that is, exit ROS Master), You will find that the subscriber and publisher are still sending and receiving data as usual. ctrl+c
roscore
The participation of ROS Master is only required when the parameters involved by ROS Master need to be accessed again. For example, if there is a third node that wants to communicate with any of the two nodes, this communication is impossible without the help of ROS Master. ongoing.