Ubuntu16.04 ROS 話題 服務 動作 訊息
阿新 • • 發佈:2021-01-11
Ubuntu16.04 Ros 話題 服務 動作 訊息
一、新增話題服務檔案
1、找包
find_package(catkin REQUIRED COMPONENTS
roscpp
rospy
std_msgs
message_generation
actionlib_msgs
actionlib
)
2、找檔案
add_message_files(
FILES
Person.msg
# Message1.msg
# Message2.msg
)
## Generate services in the 'srv' folder
# add_service_files(
# FILES
# Service1.srv
# Service2.srv
# )
add_service_files(FILES AddTwoInts.srv)
## Generate actions in the 'action' folder
add_action_files(
FILES
DoDishes.action
# Action1.action
# Action2.action
)
3、產生訊息
Generate_messages(DEPENDENCIES std_msgs actionlib_msgs)
4、配置package包
<buildtool_depend>catkin</buildtool_depend>
<build_depend>roscpp</build_depend>
<build_depend>rospy</build_depend>
<build_depend>std_msgs</build_depend>
<build_depend>message_generation</build_depend>
<build_depend> actionlib</build_depend>
<build_depend>actionlib_msgs</build_depend>
<build_export_depend>roscpp</build_export_depend>
<build_export_depend>rospy</build_export_depend>
<build_export_depend>std_msgs</build_export_depend>
<exec_depend>roscpp</exec_depend>
<exec_depend>rospy</exec_depend>
<exec_depend>std_msgs</exec_depend>
<exec_depend>message_runtime</exec_depend>
<exec_depend>actionlib</exec_depend>
<exec_depend>actionlib_msgs</exec_depend>
二、如何產生可執行檔案
1、希望生成一個可執行檔案
add_executable(talker可執行檔名 src/talker.cpp生成可執行檔案的原始檔)
add_executable(talker src/talker.cpp 1.cpp 2.cpp)
2、設定連結第三方庫,這裡沒有連結庫,所以連結catkin_LIBRARIES,如果需要連結第三方庫,就把catkin_LIBRARIES改為第三方庫的名子
target_link_libraries(talker ${catkin_LIBRARIES})
3、設定所需要的依賴
add_dependencies(server ${PROJECT_NAME}_gencpp)
4、整體
add_executable(talker src/talker.cpp)
target_link_libraries(talker ${catkin_LIBRARIES})
#target_link_libraries(${PROJECT_NAME}_node
# ${catkin_LIBRARIES}
# )
# add_dependencies(talker ${PROJECT_NAME}_generate_messages_cpp)
add_executable(listener src/listener.cpp)
target_link_libraries(listener ${catkin_LIBRARIES})
# target_link_libraries(${PROJECT_NAME}_node
# ${catkin_LIBRARIES}
# )
add_executable(server src/server.cpp)
target_link_libraries(server ${catkin_LIBRARIES})
add_dependencies(server ${PROJECT_NAME}_gencpp)
add_executable(client src/client.cpp)
target_link_libraries(client ${catkin_LIBRARIES})
add_dependencies(client ${PROJECT_NAME}_gencpp)
add_executable(DoDishes_client src/DoDishes_client.cpp)
target_link_libraries( DoDishes_client ${catkin_LIBRARIES})
add_dependencies(DoDishes_client ${${PROJECT_NAME}_EXPORTED_TARGETS})
add_executable(DoDishes_server src/DoDishes_server.cpp)
target_link_libraries( DoDishes_server ${catkin_LIBRARIES})
add_dependencies(DoDishes_server ${${PROJECT_NAME}_EXPORTED_TARGETS})
三、話題:
某一個功能包節點只管自己釋出訊息,以一定的迴圈頻率釋出,
另一個功能包需要是即訂閱,兩者可以不同步,
ros::Publisher chatter_pub = n.advertise<std_msgs::String>("chatter", 1000);
這裡的1000的意思是資料結構的佇列結構,如果記憶體過大,就先進先出,使此功能包所佔用的系統記憶體不超過1000,保證記憶體資源的不浪費。
四、訊息型別
自己定義,也可引用系統訊息型別,注意配置格式
用於功能包直接的通訊的資訊服務非常方便也非常必須。
五、服務
服務的核心在於服務服務方,裡面包括若干處理資訊,把客戶發來的資料進行處理,把處理結果返回給客戶端。
而客戶端主要是傳送請求資料,然後從服務方就收結果,客戶自己不關心處理過程,只關心處理結果。客戶端的請求服務程式碼為
client.call(srv)
六、動作
1、動作服務端
#include <ros/ros.h>
#include <actionlib/server/simple_action_server.h>
#include "linlinshi/DoDishesAction.h"
typedef actionlib::SimpleActionServer<linlinshi::DoDishesAction> Server;
// 收到action的goal後呼叫該回調函式
void execute(const linlinshi::DoDishesGoalConstPtr& goal, Server* as)
{
ros::Rate r(1);
linlinshi::DoDishesFeedback feedback;
ROS_INFO("Dishwasher %d is working.", goal->dishwasher_id);
// 假設洗盤子的進度,並且按照1hz的頻率釋出進度feedback
for(int i=1; i<=10; i++)
{
feedback.percent_complete = i * 10;
as->publishFeedback(feedback);
r.sleep();
}
// 當action完成後,向客戶端返回結果
ROS_INFO("Dishwasher %d finish working.", goal->dishwasher_id);
as->setSucceeded();
}
int main(int argc, char** argv)
{
ros::init(argc, argv, "do_dishes_server");
ros::NodeHandle n;
// 定義一個伺服器
Server server(n, "do_dishes", boost::bind(&execute, _1, &server), false);
// 伺服器開始執行
server.start();
ros::spin();
return 0;
}
2、動作客戶端
#include <actionlib/client/simple_action_client.h>
#include "linlinshi/DoDishesAction.h"
typedef actionlib::SimpleActionClient<linlinshi::DoDishesAction> Client;
// 當action完成後會呼叫該回調函式一次
void doneCb(const actionlib::SimpleClientGoalState& state,
const linlinshi::DoDishesResultConstPtr& result)
{
ROS_INFO("Yay! The dishes are now clean");
ros::shutdown();
}
// 當action啟用後會呼叫該回調函式一次
void activeCb()
{
ROS_INFO("Goal just went active");
}
// 收到feedback後呼叫該回調函式
void feedbackCb(const linlinshi::DoDishesFeedbackConstPtr& feedback)
{
ROS_INFO(" percent_complete : %f ", feedback->percent_complete);
}
int main(int argc, char** argv)
{
ros::init(argc, argv, "do_dishes_client");
// 定義一個客戶端
Client client("do_dishes", true);
// 等待伺服器端
ROS_INFO("Waiting for action server to start.");
client.waitForServer();
ROS_INFO("Action server started, sending goal.");
// 建立一個action的goal
linlinshi::DoDishesGoal goal;
goal.dishwasher_id = 1;
// 傳送action的goal給伺服器端,並且設定回撥函式
client.sendGoal(goal, &doneCb, &activeCb, &feedbackCb);
ros::spin();
return 0;
}