ROS学习笔记二:Defining messages

ROS学习笔记二:Defining messages

发现把build文件夹删掉后,或者把包给别人后,重新编译就会报缺少自定义消息的头文件,检查了CMakeLists和package.xml都没发现有问题,后来仔细想想其实顺序错了,应该先把CMakeLists里面那些要调用到头文件生成可执行程序的cpp文件先去掉,先catkin_make 把自定义消息的头文件生成出来先,然后再把这些需要用到对应头文件 来生成可执行文件的cpp加上去。这样就可以了,如下:

add_executable(robot_ik src/robot_ik.cpp)
target_link_libraries(robot_ik ${catkin_LIBRARIES})

像上面这种,要调用到自定义消息的cpp,先删掉,catkin_make第一次,再把它们加上,catkin_make第二次,就不会报错了。

2021.05.05


ROS有14种内置的消息类型,可供调用,当然可以即可单独使用也可以混合使用,利用这些内置的消息类型就可以构建出复杂的消息类型。
##一.创建自定义的message
以下是一个将三个内置消息类型组合成一个自定义的message例子(这三个消息类型的定义都在package std_msgs里面):
###1.创建message文件
①先再工作空间内创建一个package
catkin_create_pkg example_ros_msg roscpp std_msgs
也可以使用
cs_create_pkg example_ros_msg roscpp std_msgs
它们的功能很相像,第二条指令生成的CMakeLists会更简洁一点,还有README file(markdown格式)。
②在package里面创建一个msg文件夹,存放message文件
cd example_ros_msg
mkdir msg
③在msg文件夹里面创建一个message文件
touch ExampleMessage.msg
④在第三步创建的.msg文件中写入以下信息

Header header
int32 demo_int
float64 demo_double

###2.编辑package.xml文件
要使编译器能顺利编译并生成新的message头文件,需要在package.xml中添加以下语句:

<build_depend>message_generation</build_depend>
<run_depend>message_runtime</run_depend>

###3.编辑CMakeLists.txt文件
①添加需要调用的package,这里调用的三个消息类型都在std_msgs这个package里面,所以需要加上这个包,在CMakeLists.txt中添加以下语句:

find_package(catkin REQUIRED COMPONENTS roscpp rospy message_generation std_msgs)

②指定.msg文件,这里使用的.msg文件是ExampleMessage.msg,所以添加以下语句:

add_message_files(
  FILES
  ExampleMessage .msg
)

③指定生成新的message头文件需要的依赖项,这里的消息类型都是在std_msgs中的,添加以下语句:

generate_messages(
 DEPENDENCIES
 std_msgs
)

注意,generate_messages必须在catkin_package前面。
④最后是设置运行的依赖项

catkin_package(

CATKIN_DEPENDS message_runtime

)

至此,自定义的message文件的准备工作已经完成了,现在可以尝试编译这个message文件
cd catkin_ws
catkin_make
编译之后会生成一个头文件,名称与.msg文件的名称相同,它生成的位置在

~/catkin_ws/devel/include/example_ros_msg/ExampleMessage.h

然后使用功能rosmsg show查看显示的消息类型是否与我们预想的一样:
rosmsg show example_ros_msg/ExampleMessage
若显示如下,则说明我们成功的创建了一个自定义的message类型。

std_msgs/Header header
  uint32 seq
  time stamp
  string frame_id
int32 demo_int
float64 demo_double

##二.调用自定义的message类型
要想在任意节点中调用自定义的message类型,需要在该节点的源代码中添加对应的package及包含的头文件,如下:

#include <example_ros_msg/ExampleMessage.h>

格式为

#include <packageName/headerfileName.h>

以下是一个调用刚刚我们自定义的message类型的节点程序:

#include <ros/ros.h>
#include <example_ros_msg/ExampleMessage.h>//添加message类型对应的package和header file是关键
#include <math.h>

int main(int argc, char **argv) {
    ros::init(argc, argv, "example_ros_message_publisher"); //命名这个节点
    ros::NodeHandle n; //创建一个与ROS沟通的发布对象
    ros::Publisher my_publisher_object = n.advertise<example_ros_msg::ExampleMessage>("example_topic", 1);
//"example_topic"为topic的名称,后面的数字"1"为queue size
    
    example_ros_msg::ExampleMessage  my_new_message;
    //创建一个类型为ExampleMessage的变量
   
   ros::Rate naptime(1.0); //create a ros object from the ros “Rate” class; 
   //set the sleep timer for 1Hz repetition rate (arg is in units of Hz)

    my_new_message.header.stamp = ros::Time::now(); //初始化各项参数的值
    my_new_message.header.seq=0; // 初始化各项参数的值
    my_new_message.header.frame_id = "base_frame"; // 初始化各项参数的值
    my_new_message.demo_int= 1; // 初始化各项参数的值
    my_new_message.demo_double=100.0; //初始化各项参数的值
    
    double sqrt_arg;

    while (ros::ok()) 
    {
       my_new_message.header.seq++; //叠加seq的数值
       my_new_message.header.stamp = ros::Time::now(); //更新时间标签
       my_new_message.demo_int*=2.0; //倍乘
       sqrt_arg = my_new_message.demo_double;
       my_new_message.demo_double = sqrt(sqrt_arg);开根号
       
        my_publisher_object.publish(my_new_message); // 发布以自定义message类型为格式的变量到topic上
	naptime.sleep(); 
    }
}

若以上这个节点是在自定义的message文件夹里面的,那么到这里就完成了,即只需要在源代码中添加对应的头文件。
若是在其他包中调用这个自定义的message包中的消息类型,这还需要编辑调用这个消息类型的包中的package.xml和CMakeLists.txt文件:
①编辑package.xml
添加一下语句:

<build_depend>example_ros_msg</build_depend>
<run_depend>example_ros_msg</run_depend>

②编辑CMakeLists.txt
find_package 中添加自定义的message包

find_package(catkin REQUIRED COMPONENTS
  roscpp
  example_ros_msg
)

到这里就完成了调用其他包中的消息类型所需完成的工作了,下面就可以编译运行,看看是不是如我们预期的一样。


有一种情况会报错,是因为编辑好自定义的message包后,没有编译,也就没有生成对应的头文件,所以在编译节点的时候会报错

fatal error: example_ros_msg/ExampleMessage.h: 没有那个文件或目录

最后,在catkin_make 编译完成后,运行上述的节点(默认已经运行roscore)
rosrun example_ros_msg example_ros_message_publisher
然后在另一个terminal中运行
rostopic echo example_topic
查看是否有如下的输出:

header: 
  seq: 1
  stamp: 
    secs: 1520818931
    nsecs: 955151058
  frame_id: base_frame
demo_int: 4
demo_double: 3.16227766017
---
header: 
  seq: 2
  stamp: 
    secs: 1520818932
    nsecs: 955130728
  frame_id: base_frame
demo_int: 8
demo_double: 1.77827941004
---

若正确输出,则说明成功的调用了其他包中的消息类型。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值