记录第一次ROS写节点,发布自定义的消息

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>#自定义消息需要添加的
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值