ros编写自己需要的msg(C++)

ros编写自己需要的msg

1.首先,创建自己的包

$ cd catkin_ws/src
$ catkin_create_pkg test roscpp

2新建一个msg文件夹用来存放自己编写的msg文件

$ roscd test
$ mkdir msg
$ cd msg
$ vi test.msg

3.编写自己需要的类型的参数。
可供选择的有:

bool
int8
uint8
int16
uint16
int32
uint32
int64
uint64
float32
float64
string
time
duration

下面举个例子:
比如我自己编写了一个叫做test.msg的文件

$ vi test.msg

并且写入以下内容(记得不要在后边加上分号 ; ,否则到时候编译会报错)

int16 a
float32 b
string c

这里的a,b,c到时候相当于一个类的几个元素啦,后边用到你就知道了
之后再改一下自己的package.xml和CMakeLists.txt文件
先看一下我的package.xml文件
以下的build_depend和run_depend可以根据自己的需要自行增加或删除
但是,需要用到message的貌似都要有以下两句
<build_depend>message_generation</build_depend>
<run_depend>message_runtime</run_depend>

<package>
  <name>test</name>
  <version>0.0.0</version>
  <description>The test package</description>

  <maintainer email="weiwie@todo.todo">weiwie</maintainer>


  <license>TODO</license>

  <buildtool_depend>catkin</buildtool_depend>
  
  <build_depend>roscpp</build_depend>
  <build_depend>message_generation</build_depend> 

  <run_depend>roscpp</run_depend>
  <run_depend>message_runtime</run_depend>   

</package>

接下来看一下我的CMakeLists.txt文件
以下信息基本上都是必须的,但是你若是有其他的信息你也可以适当添加。

cmake_minimum_required(VERSION 2.8.3)
project(test)

#对于find_package,如果你还使用了其他的依赖,必须在其中添加对应的包的名称,
#比如你如果编写的msg文件调用了std_msg文件的信息的话,那么就必须把std_msg
#这个包也放进来
find_package(catkin REQUIRED COMPONENTS
  roscpp
  message_generation
)


#add_message_files用来添加你所使用的所有的msg文件
add_message_files(
  FILES
  test.msg
)

#generate_messages则用来添加你的信息所需要的依赖包
#同理,假如你还使用了std_msg这个包的信息,那么你必须把std_msg加进去
generate_messages(
  DEPENDENCIES
  test
)


#至于这个catkin_package,你只需要更改那个LIBRARIES为你自己的包名以及
#在CATKIN_DEPENDS后边加上你所依赖的其他的包名就可以啦
catkin_package(
INCLUDE_DIRS include
LIBRARIES test
CATKIN_DEPENDS message_runtime roscpp
DEPENDS system_lib
)

#这句一般就不用更改了
include_directories(
  ${catkin_INCLUDE_DIRS}
)

接下来,我们就可以编写自己需要的ros的发布和订阅节点啦。
首先,进入我们自己的src文件夹,创建自己需要的节点的名称(这里先写发布的节点)

$ cd src
$ vi public.cpp

写入以下内容:

#include <ros/ros.h>		//ros必备头文件
#include <test/test.h>		//自己的msg头文件,test是你的包名,test.h是将
							//你的msg文件的.msg后缀改成了.h
#include <sstream>			//这个是用来定义以下的std::stringstream的

int main(int argc,char **argv)
{
    ros::init(argc,argv,"test");				//test是你的节点名称
    ros::NodeHandle n;
    ros::Publisher test_pub = n.advertise<test::test>("test",1000);
    //上面这个句子注意了,advertise后边的<>里面放的是你想要发布的节点的
    //包名::msg文件名去掉后缀,里面是你所发布的主题的名称。1000你可以当作是一个
    //栈或者队列来看待,就是发布的消息超过1000的时候,他会开始舍弃发布过的信息
    //仅此而已,你也可以自己添加,换成1或者其他的都行
    
    ros::Rate loop_rate(10);		//设置发布的频率为10,可以自己更改

    //下面三个是我打算用来附给msg并发布出去的
    int aount = 0;					
    float bount = 0.0;				
    std::stringstream ss("Hello World!");
    while(ros::ok())
    {
    //定义一个test::test类型的msg变量。(也就是包名::msg文件名去掉后缀)
        test::test msg;
        //下面三句我们可以清楚的看到我直接用了.a还有.b跟.c,其实就是我刚才
        //在msg文件下命名的名称,如果你是其他的名称,那么你就直接叫那个名字
        //就可以啦。
        msg.a = aount;
        msg.b = bount;
        msg.c = ss.str();
        aount++;
        bount++;
        //下面之所以使用.c_str()是因为,如果直接显示msg.c的话,会出现乱码
        ROS_INFO("%d,%f,%s",msg.a,msg.b,msg.c.c_str());
        test_pub.publish(msg);		//这句就是最重要的发布消息啦。
		//最后两句跟ros::init都是固定要的,加上去就可以啦.
        ros::spinOnce();

        loop_rate.sleep();
    }
    return 0;
}

接下来,我们编写我们的监听节点

#vi listen.cpp

写入以下内容:

#include <ros/ros.h>				//ros程序固有的头文件
#include <test/test.h>				//自己的msg头文件
//以下函数中的test::test::ConstPtr &msg 分别是包名::msg文件名::ConstPtr &msg
//后边的ConstPtr你不需要知道是什么东西,因为他就是固定的,照写就可以啦
void testCallback(const test::test::ConstPtr &msg)
{
//下方注意,用msg的数据的适合,必须要用->不能用.。至于.c_str()同上,是为了
//不输出乱码
    ROS_INFO("I heard aount is %d,bount is %f,count is %s\n",msg->a,msg->b,msg->c.c_str());
}

int main(int argc,char **argv)
{
    ros::init(argc,argv,"listen");			//节点的名称
    ros::NodeHandle n;
    //监听的迭代器,第一个参数是监听的主题名,第三个是迭代器调用的函数
    ros::Subscriber sub = n.subscribe("test",1000,testCallback);
    ros::spin();
    return 0;
}

写完我们的发布跟监听的节点后,我们需要在自己的CMakeLists.txt文件后边加上这几句话。(这几句都是必须的,第三和第六句后边的test_gencpp根据你自己的包名不同进行更改,test是我自己的包名,假如你的包名叫做hello,那么test_gencpp就应该改成hello_gencpp)

add_executable(public src/public.cpp)
target_link_libraries(public ${catkin_LIBRARIES})
add_dependencies(public test_gencpp)

add_executable(listen src/listen.cpp)
target_link_libraries(listen ${catkin_LIBRARIES})
add_dependencies(listen test_gencpp)

至于第一跟第二句,后边第一个参数是生成的文件名,第二个参数则分别是你想编译的文件名的位置以及一个固定的${catkin_LIBRARIES},如果你使用了像opencv的库的话,就必须加上你需要的.so文件。
比如:我自己之前编写的发布视频的节点的这几句话是这样的

link_directories(~/opencv-3.4.0/build/lib)
target_link_libraries(public_video_node ${catkin_LIBRARIES}
libopencv_highgui.so libopencv_core.so libopencv_imgproc.so
libopencv_videoio.so libopencv_imgcodecs.so)

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值