一、ROS通訊程式設計類型
分為以下三種
1.話題程式設計
2.服務程式設計
3.動作程式設計
二、話題程式設計

三、建立釋出者
在功能包learn_communication/src/目錄下添加talker.cpp檔案:
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本身就是可執行檔案)
1.更改編譯配置檔案
更改功能包目錄下的CMakeLists.txt檔案:
将add_executable(${PROJECT_NAME}_node src/learing_communication_node.cpp)取消注釋,并更改内容
更改為:
意思是将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
編譯完成:
可以在devl目錄下看見我們編譯完成的可執行程式:
六,運作可執行檔案
1.啟動rosMaster
建立終端
roscore
2.啟動listener
用rosrun指令
rosrun功能包名 結點名
rosrun learing_communication talker
3.啟動listener
rosrun learing_communication listener
我們可以發現發送和接收保持同步
七、自定義話題
前面的話題我們都是發送一個string類型的資料,但是我們想要發送一組有類型的資料怎麼辦呢?德國自定義話題來解決
1.定義msg檔案
在功能包目錄下建立msg檔案夾(存放msg檔案)
在檔案夾下建立person.msg檔案
定義person相關資訊,并且可以定義常量(unknown,male,female):
string name
uint8 sex
uint8 age
uint8 unknown = 0
uint8 male = 1
uint8 female = 2
2.在package.xml中添加功能包依賴
打開功能包目錄下的package.xml添加以下:
<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>
注意:
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)
添加功能包:
添加編譯時的依賴:
指定消息檔案的目錄:
4.編譯
将msg檔案編譯成對應語言的頭檔案:
在工作空間根目錄進行編譯
catkin_make
可以看見他編譯成不同語言接口供我們使用
5.檢視自定義消息
rosmsg show person
證明該消息編譯沒問題,可以使用頭檔案包含進行使用了