1
首先在功能包下创建msg文件夹,在msg文件夹中创建Person.msg文件
Header header
string name
int16 sex
int16 age
int16 unknown=0
int16 male=1
int16 female=2
其中,Header可加可不加,它是标准格式头信息std_msgs/Header:
uint32 seq
time stamp
string frame_id
加入header后,catkin_make之后(这里肯定先完成后续步骤才能编译,我只是先在这里写)
source devel/setup.bash
rostopic echo /test
编译之后,.msg文件会生成对应语言的.h头文件,位于“devel/include/对应功能包/”路径之下。Person.h头文件如下,并没有完整复制过来
#ifndef TEST_MESSAGE_PERSON_H
#define TEST_MESSAGE_PERSON_H
#include <string>
#include <vector>
#include <map>
#include <ros/types.h>
#include <ros/serialization.h>
#include <ros/builtin_message_traits.h>
#include <ros/message_operations.h>
#include <std_msgs/Header.h>
namespace test//命名空间
{
template <class ContainerAllocator>
struct Person_//结构体,所以一般使用都是test::Person
{
typedef Person_<ContainerAllocator> Type;
Person_()
: header()
, name()
, sex(0)
, age(0) {
}
Person_(const ContainerAllocator& _alloc)
: header(_alloc)
, name(_alloc)
, sex(0)
, age(0) {
(void)_alloc;
}
typedef ::std_msgs::Header_<ContainerAllocator> _header_type;
_header_type header;
typedef std::basic_string<char, std::char_traits<char>, typename ContainerAllocator::template rebind<char>::other > _name_type;
_name_type name;
typedef int16_t _sex_type;
_sex_type sex;
typedef int16_t _age_type;
_age_type age;
enum {
unknown = 0,
male = 1,
female = 2,
};
typedef boost::shared_ptr< ::test::Person_<ContainerAllocator> > Ptr;
typedef boost::shared_ptr< ::test::Person_<ContainerAllocator> const> ConstPtr;//回调函数中可能会使用
}; // struct Person_
typedef ::test::Person_<std::allocator<void> > Person;
typedef boost::shared_ptr< ::test::Person > PersonPtr;
typedef boost::shared_ptr< ::test::Person const> PersonConstPtr;
//回调函数中可能会使用
// constants requiring out of line definition
template<typename ContainerAllocator>
std::ostream& operator<<(std::ostream& s, const ::test::Person_<ContainerAllocator> & v)
{
ros::message_operations::Printer< ::test::Person_<ContainerAllocator> >::stream(s, "", v);
return s;
}
} // namespace test
2.talker.cpp
#include<iostream>
#include<ros/ros.h>
#include"test/Person.h"
#include"std_msgs/String.h"
#include <std_msgs/Header.h>
using namespace std;
using namespace ros;
int main(int argc, char **argv){
init(argc, argv,"talkerzzz");
//节点名,与CmakeLists.txt中add_executable()中的第一个参数不一样,第一个参数是期望生成的可执行名,
//rosrun指令`rosrun 功能包名 cmakelists中的可执行名而不是init中的节点名`
NodeHandle n;
Publisher test_pub=n.advertise<test::Person>("/test",1000);//话题名
Rate loop_rate(10);
int count=0;
while(ok()){
test::Person person_msg;//定义一个此类型的消息以供发布
person_msg.name="zft";
person_msg.age=count;
person_msg.sex=2;
//person_msg.sex=test::Person::female;
ROS_INFO_STREAM("age"<<person_msg.age<<" "<<person_msg.name);// ROS_INFO_STREAM相当于C++中的cout
test_pub.publish(person_msg);
count++;
loop_rate.sleep();
}
return 0;
}
3. listener.cpp
#include<iostream>
#include<ros/ros.h>
#include"test/Person.h"
#include"std_msgs/String.h"
#include <ros/console.h>
#include <std_msgs/Header.h>
using namespace std;
using namespace ros;
void personcbk(const test::Person::ConstPtr& msg){
ROS_INFO("age%d,name%s,sex%d",msg->age,msg->name.c_str(),msg->sex);
//ROS_INFO_STREAM("name"<<msg.name<<"sex"<<msg.sex<<"age"<<msg.age);//我也不知道为什么,这样写就会有错,我觉得可能是回调函数参数的问
//题,因为这个参数具体怎么写其实我不知道,我也是看别人这么写的,如果有大佬知
//道,可以留言或者评论告诉我为什么,谢谢啦
//cout<<"可以"<<endl;//也可以用cout输出,注意加入头文
//件#include<iostream>
}
int main(int argc, char **argv){//这里必须加入两个参数,init()中要使用
init(argc, argv,"listenerzzz");
NodeHandle n;
Subscriber test_sub=n.subscribe("/test",1000,personcbk);
spin();
return 0;
}
节点图rqt_graph
4.Cmakelists.txt中添加如下
find_package(catkin REQUIRED COMPONENTS
roscpp
rospy
std_msgs
message_generation
)
add_message_files(
FILES
Person.msg
)
generate_messages(
DEPENDENCIES
std_msgs
)
catkin_package(
# INCLUDE_DIRS include
# LIBRARIES test
CATKIN_DEPENDS roscpp rospy std_msgs message_runtime
# DEPENDS system_lib
)
include_directories(
# include
${catkin_INCLUDE_DIRS}
)
add_executable(talker src/talker.cpp)
target_link_libraries(talker
${catkin_LIBRARIES}
)
add_dependencies(talker ${PROJECT_NAME}_generate_messages_cpp)
add_executable(listener src/listener.cpp)
target_link_libraries(listener
${catkin_LIBRARIES}
)
add_dependencies(listener ${PROJECT_NAME}_generate_messages_cpp)#注意“}”和“_" 之间没有空格
5.Package.xml中添加如下
<buildtool_depend>catkin</buildtool_depend>
<build_depend>roscpp</build_depend>
<build_depend>rospy</build_depend>
<build_depend>std_msgs</build_depend>
<build_depend>message_generation</build_depend>#自定义消息需要添加的
<build_export_depend>roscpp</build_export_depend>
<build_export_depend>rospy</build_export_depend>
<build_export_depend>std_msgs</build_export_depend>
<exec_depend>roscpp</exec_depend>
<exec_depend>rospy</exec_depend>
<exec_depend>std_msgs</exec_depend>
<exec_depend>message_runtime</exec_depend>#自定义消息需要添加的