ROS教程3 ROS自定義msg類型及使用


1ROS自定義msg類型及使用 

 http://blog.csdn.net/u013453604/article/details/72903398

首先創建一個空的package單獨存放msg類型(當然也可以在任意的package中自定義msg類型) 
這里為便於說明,建立一個名為test_msgs的包,用於對自定義msg類型的用法舉例

2參考西工大

https://github.com/HANDS-FREE/handsfree

一、創建msg消息

首先創建一個空的package單獨存放msg類型(當然也可以在任意的package中自定義msg類型) 
這里為便於說明,建立一個名為test_msgs的包,用於對自定義msg類型的用法舉例

cd catkin_arduino_ros/src
catkin_create_pkg test_msgs

  

1.新建msg文件

cd test_msgs
mkdir msg

創建Test.msg的內容如下,  

基本類型可參考: std_msgscommon_msgs

 
        
float32[] data
float32 vel
geometry_msgs/Pose pose
string name

2.修改package.xml

接下來需要message_generation生成C++或Python能使用的代碼,需要message_runtime提供運行時的支持,所以package.xml中添加以下兩句

 

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

 

3.修改CMakeLists.txt

(1)首先調用find_package查找依賴的包,必備的有roscpp rospy message_generation,其他根據具體類型添加,比如上面的msg文件中用到了geometry_msgs/Pose pose類型,那么必須查找geometry_msgs

find_package(catkin REQUIRED COMPONENTS roscpp rospy message_generation std_msgs geometry_msgs)

(2)然后是add_message_files,指定msg文件

add_message_files(
  FILES
  Test.msg
  # Message2.msg
)

(3)然后是generate_messages,指定生成消息文件時的依賴項,比如上面嵌套了其他消息類型geometry_msgs,那么必須注明

#generate_messages必須在catkin_package前面
generate_messages(
 DEPENDENCIES
 geometry_msgs
) 

(4)然后是catkin_package設置運行依賴

catkin_package(

CATKIN_DEPENDS message_runtime

)

到這里新的msg類型test_msgs/Test就可以使用了,下面編譯這個包,然后利用rosmsg show指令查看

$ cd catkin_ws
$ catkin_make
$ rosmsg show test_msgs/Test 
float32[] data
float32 vel
geometry_msgs/Pose pose
  geometry_msgs/Point position
    float64 x
    float64 y
    float64 z
  geometry_msgs/Quaternion orientation
    float64 x
    float64 y
    float64 z
    float64 w
string name

  

二、msg的使用

要使用自定義的消息類型必須source自定義消息所在的工作空間,否則rosmsg show test_msgs/Testrostopic echo /test_msg(/test_msg是節點中使用自定義消息類型test_msgs/Test的topic)都會報錯,因為沒有source的情況下自定義消息類型是不可見的,被認為是未定義類型

 

1.其他包調用自定義msg類型

如果是在test_msgs包內的節點中調用test_msgs/Test類型,只需要在.cpp文件中如下調用即可

 
        
#include <test_msgs/Test.h>

test_msgs::Test msg;

如果是在其他包調用test_msgs/Test類型則需要修改package.xml和CMakeLists.txt,比如同樣在工作空間catkin_arduino_ros內有一個名為test1_pub_sub的包,我們可以在這個包內寫一個節點talker.cpp,使用我們剛才自定義的消息類型test_msgs/Test,如下:  

 (1)修改package.xml 

<build_depend>roscpp</build_depend>
<run_depend>roscpp</run_depend>

<build_depend>test_msgs</build_depend>
<run_depend>test_msgs</run_depend>

 

(2)修改CMakeLists.txt   

調用自定義消息類型主要修改兩個地方,以下是重點: 一是find_package中需要聲明查找包含該消息類型的包; 二是add_dependencies要注明該消息的依賴,其他地方和普通節點一樣

find_package(catkin REQUIRED COMPONENTS
  roscpp
  geometry_msgs
  test_msgs
)

add_dependencies(test1 test_msgs_gencpp)#調用同一工作空間的自定義消息類型時注明依賴關系,防止發生頭文件找不到的報錯

如果缺少add_dependencies中對test_msgs_gencpp的依賴聲明,在編譯的時候如果先編譯test包再編譯test_msgs包則會出現如下報錯(ROS工作空間各個軟件包的編譯順序是隨機的),因為頭文件test_msgs/Test.h還未生成  

fatal error: test_msgs/Test.h: 沒有那個文件或目錄
 #include "test_msgs/Test.h"

  2 程序調用

#include "ros/ros.h"
#include "std_msgs/String.h"
#include <test_msgs/Test.h> // 添加自定義的消息
// 文件包 test_msgs下面 有一個自定義的 Test.msg
#include <sstream> int main(int argc, char **argv){ ros::init(argc, argv, "talker"); ros::NodeHandle n; //ros::Publisher chatter_pub = n.advertise<std_msgs::String>("chatter", 1000); ros::Publisher chatter_pub = n.advertise<test_msgs::Test>("chatter", 1000); ros::Rate loop_rate(10); //發布自定義消息類型test_msgs::Test int count = 0; while (ros::ok()) { std_msgs::String msg; std::stringstream ss; ss << "hello world " << count; msg.data = ss.str(); ROS_INFO("%s", msg.data.c_str()); test_msgs::Test mymsg; //創建自定義消息test_msgs::Test /* float32[] data float32 vel geometry_msgs/Pose pose string name */ mymsg.name=ss.str(); // 為其中的分量 mymsg.vel=1; // chatter_pub.publish(msg); chatter_pub.publish(mymsg); //發布 ros::spinOnce(); loop_rate.sleep(); ++count; } return 0; }

  

3 查看結果

  運行

roscore


rosrun test1_pub_sub talker

  

查看消息

rostopic list

rostopic type /chatter

 rosmsg show test_msgs/Test 

  

  結果看到和我們定義的是一樣的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM