天天看點

ROS機器人004-ROS通信程式設計(話題程式設計,自定義話題消息)一、ROS通訊程式設計類型二、話題程式設計三、建立釋出者四、建立訂閱者五.編譯代碼六,運作可執行檔案七、自定義話題

一、ROS通訊程式設計類型

分為以下三種

1.話題程式設計

2.服務程式設計

3.動作程式設計

二、話題程式設計

ROS機器人004-ROS通信程式設計(話題程式設計,自定義話題消息)一、ROS通訊程式設計類型二、話題程式設計三、建立釋出者四、建立訂閱者五.編譯代碼六,運作可執行檔案七、自定義話題

三、建立釋出者

在功能包learn_communication/src/目錄下添加talker.cpp檔案:

ROS機器人004-ROS通信程式設計(話題程式設計,自定義話題消息)一、ROS通訊程式設計類型二、話題程式設計三、建立釋出者四、建立訂閱者五.編譯代碼六,運作可執行檔案七、自定義話題

1.添加都檔案

//添加ROS包
#include "ros/ros.h"
//添加ROS string變量
#include "std_msgs/String.h"
           

2.Ros結點初始化,定義結點名稱

3.建立結點句柄

通過建立結點句柄,友善我們對結點進行管理(包括釋出者,訂閱者等等的管理)

//建立結點句柄
 ros::NodeHandle n;
           

4.建立釋出者

建立一個Publisher的對象,釋出名為chatter的話題,消息類型為std_msg::String,釋出者隊列長度為1000(将資料放入隊列,避免釋出過快,接受者收不到)

5.釋出消息

//釋出消息
chatter_pub.publish(msg);
           

6.完整代碼

//添加ROS包
#include "ros/ros.h"
//添加ROS string變量
#include "std_msgs/String.h"

int main(int argc, char **argv)
{

 //ROS結點初始化
 //建立talker結點
 ros::init(argc,argv,"talker");
 
 //建立結點句柄
 ros::NodeHandle n;
 
 //建立一個Publisher,釋出名為chatter的話題,消息類型為std_msgs::String
 ros::Publisher chatter_pub = n.advertise<std_msgs::String>("chatter",1000);
 //設定循環的頻率 10HZ
 ros::Rate loop_rate(10);

 int count = 0;
 while(ros::ok())
{
 //初始化std_msgs::String 類型的消息
 std_msgs::String msg;
 std::stringstream ss;
 ss<<"hello world"<<count;
 msg.data = ss.str();

//釋出消息
ROS_INFO("%s",msg.data.c_str());
chatter_pub.publish(msg);

//循環等待回調函數
ros::spinOnce();

//注意在循環中一定要有延時函數
//按照循環頻率延時
loop_rate.sleep();
++count;
}
return 0;
}
           

四、建立訂閱者

1.初始化ROS結點

//初始化ROS結點
  ros::init(argc,char **argv,"listrner");
           

2.建立結點句柄

//建立結點句柄
  ros::NodeHandle n;
           

3.建立一個訂閱者

并且綁定訂閱的話題,收到消息的回調函數

//建立一個接受者,訂閱名為chatter的話題,注冊回調函數chatterCallback
  ros::Subscriber sub = n.subscribe("chatter",1000,chatterCallback);
           

4.建立回調函數

//接收消息的回調函數
void chatterCallback(const std_msgs::String::ConstPtr& msg)
{
ROS_INFO("I heard :{%s}",msg->data.c_str());
}
           

5.循環等待回調函數

//循環等待回調函數
  ros::spin();
           

6.完整代碼

#include "ros/ros.h"
#include "std_msgs/String.h"

//接收消息的回調函數
void chatterCallback(const std_msgs::String::ConstPtr& msg)
{
ROS_INFO("I heard :{%s}",msg->data.c_str());
}

int main(int argc,char **argv)
{
  //初始化ROS結點
  ros::init(argc,argv,"listrner");

  //建立結點句柄
  ros::NodeHandle n;
  //建立一個接受者,訂閱名為chatter的話題,注冊回調函數chatterCallback 1000代表消息隊列的大小
  ros::Subscriber sub = n.subscribe("chatter",1000,chatterCallback);

  //循環等待回調函數
  ros::spin();
return 0;
}
           

五.編譯代碼

當我們用c++寫完這兩個結點功能後,需要将代碼編譯為可執行檔案(用python寫就不用編譯,Python本身就是可執行檔案)

ROS機器人004-ROS通信程式設計(話題程式設計,自定義話題消息)一、ROS通訊程式設計類型二、話題程式設計三、建立釋出者四、建立訂閱者五.編譯代碼六,運作可執行檔案七、自定義話題

1.更改編譯配置檔案

更改功能包目錄下的CMakeLists.txt檔案:

ROS機器人004-ROS通信程式設計(話題程式設計,自定義話題消息)一、ROS通訊程式設計類型二、話題程式設計三、建立釋出者四、建立訂閱者五.編譯代碼六,運作可執行檔案七、自定義話題

将add_executable(${PROJECT_NAME}_node src/learing_communication_node.cpp)取消注釋,并更改内容

ROS機器人004-ROS通信程式設計(話題程式設計,自定義話題消息)一、ROS通訊程式設計類型二、話題程式設計三、建立釋出者四、建立訂閱者五.編譯代碼六,運作可執行檔案七、自定義話題

更改為:

意思是将src目錄下的talker.cpp編譯為talker可執行檔案

連結第三方庫:

因為這裡沒用到其他庫,隻有ROS預設的庫,是以我們連結catkin_LIBRARIES

更改後的完整内容為:

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

2.編譯

在工作空間目錄 catkin_ws下打開終端:

指令:

catkin_make
           
ROS機器人004-ROS通信程式設計(話題程式設計,自定義話題消息)一、ROS通訊程式設計類型二、話題程式設計三、建立釋出者四、建立訂閱者五.編譯代碼六,運作可執行檔案七、自定義話題

編譯完成:

ROS機器人004-ROS通信程式設計(話題程式設計,自定義話題消息)一、ROS通訊程式設計類型二、話題程式設計三、建立釋出者四、建立訂閱者五.編譯代碼六,運作可執行檔案七、自定義話題

可以在devl目錄下看見我們編譯完成的可執行程式:

ROS機器人004-ROS通信程式設計(話題程式設計,自定義話題消息)一、ROS通訊程式設計類型二、話題程式設計三、建立釋出者四、建立訂閱者五.編譯代碼六,運作可執行檔案七、自定義話題

六,運作可執行檔案

1.啟動rosMaster

建立終端

roscore
           
ROS機器人004-ROS通信程式設計(話題程式設計,自定義話題消息)一、ROS通訊程式設計類型二、話題程式設計三、建立釋出者四、建立訂閱者五.編譯代碼六,運作可執行檔案七、自定義話題

2.啟動listener

用rosrun指令

rosrun功能包名 結點名

rosrun learing_communication talker
           
ROS機器人004-ROS通信程式設計(話題程式設計,自定義話題消息)一、ROS通訊程式設計類型二、話題程式設計三、建立釋出者四、建立訂閱者五.編譯代碼六,運作可執行檔案七、自定義話題

3.啟動listener

rosrun learing_communication listener
           

我們可以發現發送和接收保持同步

ROS機器人004-ROS通信程式設計(話題程式設計,自定義話題消息)一、ROS通訊程式設計類型二、話題程式設計三、建立釋出者四、建立訂閱者五.編譯代碼六,運作可執行檔案七、自定義話題

七、自定義話題

前面的話題我們都是發送一個string類型的資料,但是我們想要發送一組有類型的資料怎麼辦呢?德國自定義話題來解決

ROS機器人004-ROS通信程式設計(話題程式設計,自定義話題消息)一、ROS通訊程式設計類型二、話題程式設計三、建立釋出者四、建立訂閱者五.編譯代碼六,運作可執行檔案七、自定義話題

1.定義msg檔案

在功能包目錄下建立msg檔案夾(存放msg檔案)

ROS機器人004-ROS通信程式設計(話題程式設計,自定義話題消息)一、ROS通訊程式設計類型二、話題程式設計三、建立釋出者四、建立訂閱者五.編譯代碼六,運作可執行檔案七、自定義話題

在檔案夾下建立person.msg檔案

ROS機器人004-ROS通信程式設計(話題程式設計,自定義話題消息)一、ROS通訊程式設計類型二、話題程式設計三、建立釋出者四、建立訂閱者五.編譯代碼六,運作可執行檔案七、自定義話題

定義person相關資訊,并且可以定義常量(unknown,male,female):

string name
uint8 sex
uint8 age

uint8 unknown = 0
uint8 male = 1
uint8 female = 2
           
ROS機器人004-ROS通信程式設計(話題程式設計,自定義話題消息)一、ROS通訊程式設計類型二、話題程式設計三、建立釋出者四、建立訂閱者五.編譯代碼六,運作可執行檔案七、自定義話題

2.在package.xml中添加功能包依賴

打開功能包目錄下的package.xml添加以下:

<build_depend>message_generation</build_depend> 
<exec_depend>message_runtime</exec_depend>
           

注意:

ROS機器人004-ROS通信程式設計(話題程式設計,自定義話題消息)一、ROS通訊程式設計類型二、話題程式設計三、建立釋出者四、建立訂閱者五.編譯代碼六,運作可執行檔案七、自定義話題

3.在Cmakelist.txt添加編譯選項

打開功能包目錄下的cmakelist.txt做以下更改

• find_package( ……  message_generation)
• catkin_package(CATKIN_DEPENDS geometry_msgs roscpp rospy std_msgs message_runtime)
• add_message_files(FILES Person.msg) generate_messages(DEPENDENCIES  std_msgs)
           

添加功能包:

ROS機器人004-ROS通信程式設計(話題程式設計,自定義話題消息)一、ROS通訊程式設計類型二、話題程式設計三、建立釋出者四、建立訂閱者五.編譯代碼六,運作可執行檔案七、自定義話題

添加編譯時的依賴:

ROS機器人004-ROS通信程式設計(話題程式設計,自定義話題消息)一、ROS通訊程式設計類型二、話題程式設計三、建立釋出者四、建立訂閱者五.編譯代碼六,運作可執行檔案七、自定義話題

指定消息檔案的目錄:

ROS機器人004-ROS通信程式設計(話題程式設計,自定義話題消息)一、ROS通訊程式設計類型二、話題程式設計三、建立釋出者四、建立訂閱者五.編譯代碼六,運作可執行檔案七、自定義話題
ROS機器人004-ROS通信程式設計(話題程式設計,自定義話題消息)一、ROS通訊程式設計類型二、話題程式設計三、建立釋出者四、建立訂閱者五.編譯代碼六,運作可執行檔案七、自定義話題

4.編譯

将msg檔案編譯成對應語言的頭檔案:

在工作空間根目錄進行編譯

catkin_make
           

可以看見他編譯成不同語言接口供我們使用

ROS機器人004-ROS通信程式設計(話題程式設計,自定義話題消息)一、ROS通訊程式設計類型二、話題程式設計三、建立釋出者四、建立訂閱者五.編譯代碼六,運作可執行檔案七、自定義話題

5.檢視自定義消息

rosmsg show person
           
ROS機器人004-ROS通信程式設計(話題程式設計,自定義話題消息)一、ROS通訊程式設計類型二、話題程式設計三、建立釋出者四、建立訂閱者五.編譯代碼六,運作可執行檔案七、自定義話題

證明該消息編譯沒問題,可以使用頭檔案包含進行使用了