ROS 消息通訊——動作action的來龍去脈


創建功能包:

 

 

  •  修改功能包說明文件package.xml
 1 <?xml version="1.0"?>
 2 <package>
 3   <name>action_tutorials</name>
 4   <version>0.0.0</version>
 5   <description>The action_tutorials package</description>
 6   <maintainer email="hcx@todo.todo">hcx</maintainer>
 7   <license>TODO</license>
 8   <buildtool_depend>catkin</buildtool_depend>
 9   <build_depend>actionlib</build_depend>
10   <build_depend>actionlib_msgs</build_depend>
11   <build_depend>roscpp</build_depend>
12   <run_depend>actionlib</run_depend>
13   <run_depend>actionlib_msgs</run_depend>
14   <run_depend>roscpp</run_depend>
15   <export>  </export>
16 </package>
  • CMake編譯配置文件CMakeLists.txt
 1 cmake_minimum_required(VERSION 2.8.3)
 2 project(action_tutorials)
 3 
 4 
 5 find_package(catkin REQUIRED COMPONENTS
 6   actionlib
 7   actionlib_msgs
 8   roscpp
 9 )
10 
11 
12 find_package(catkin REQUIRED genmsg actionlib_msgs actionlib)
13 add_action_files(DIRECTORY action FILES DoDishes.action)
14 generate_messages(DEPENDENCIES actionlib_msgs)
15 
16 include_directories(
17   ${catkin_INCLUDE_DIRS}
18 )
19 
20 
21 add_executable(DoDishes_client src/DoDishes_client.cpp)
22 target_link_libraries( DoDishes_client ${catkin_LIBRARIES})
23 add_dependencies(DoDishes_client ${${PROJECT_NAME}_EXPORTED_TARGETS})
24 
25 add_executable(DoDishes_server src/DoDishes_server.cpp)
26 target_link_libraries( DoDishes_server ${catkin_LIBRARIES})
27 add_dependencies(DoDishes_server ${${PROJECT_NAME}_EXPORTED_TARGETS})
  • 添加動作文件:與CMakeLists.txt對應,add_action_files(DIRECTORY action FILES DoDishes.action)

 

   內容如下:---用於分割目標、結果、反饋,順序不能打亂

1 # Define the goal
2 uint32 dishwasher_id  # Specify which dishwasher we want to use
3 ---
4 # Define the result
5 uint32 total_dishes_cleaned
6 ---
7 # Define a feedback message
8 float32 percent_complete
  • 創建動作客戶端節點:與CMakeLists.txt對應,add_executable(DoDishes_client src/DoDishes_client.cpp)

 

   內容如下:

 1 #include <actionlib/client/simple_action_client.h>
 2 #include "action_tutorials/DoDishesAction.h"
 3 
 4 typedef actionlib::SimpleActionClient<action_tutorials::DoDishesAction> Client;
 5 
 6 // 當action完成后會調用該回調函數一次
 7 void doneCb(const actionlib::SimpleClientGoalState& state,
 8         const action_tutorials::DoDishesResultConstPtr& result)
 9 {
10     ROS_INFO("Yay! The dishes are now clean");
11     ros::shutdown();
12 }
13 
14 // 當action激活后會調用該回調函數一次
15 void activeCb()
16 {
17     ROS_INFO("Goal just went active");
18 }
19 
20 // 收到feedback后調用該回調函數
21 void feedbackCb(const action_tutorials::DoDishesFeedbackConstPtr& feedback)
22 {
23     ROS_INFO(" percent_complete : %f ", feedback->percent_complete);
24 }
25 
26 int main(int argc, char** argv)
27 {
28     ros::init(argc, argv, "do_dishes_client");
29 
30     // 定義一個客戶端
31     Client client("do_dishes", true);
32 
33     // 等待服務器端
34     ROS_INFO("Waiting for action server to start.");
35     client.waitForServer();
36     ROS_INFO("Action server started, sending goal.");
37 
38     // 創建一個action的goal
39     action_tutorials::DoDishesGoal goal;
40     goal.dishwasher_id = 1;
41 
42     // 發送action的goal給服務器端,並且設置回調函數
43     client.sendGoal(goal,  &doneCb, &activeCb, &feedbackCb);
44 
45     ros::spin();
46 
47     return 0;
48 }
  • 創建動作服務器節點:與CMakeLists.txt對應,add_executable(DoDishes_server src/DoDishes_server.cpp)

 

  內容如下:

 1 #include <ros/ros.h>
 2 #include <actionlib/server/simple_action_server.h>
 3 #include "action_tutorials/DoDishesAction.h"
 4 
 5 typedef actionlib::SimpleActionServer<action_tutorials::DoDishesAction> Server;
 6 
 7 // 收到action的goal后調用該回調函數
 8 void execute(const action_tutorials::DoDishesGoalConstPtr& goal, Server* as)
 9 {
10     ros::Rate r(1);
11     action_tutorials::DoDishesFeedback feedback;
12 
13     ROS_INFO("Dishwasher %d is working.", goal->dishwasher_id);
14 
15     // 假設洗盤子的進度,並且按照1hz的頻率發布進度feedback
16     for(int i=1; i<=10; i++)
17     {
18         feedback.percent_complete = i * 10;
19         as->publishFeedback(feedback);
20         r.sleep();
21     }
22 
23     // 當action完成后,向客戶端返回結果
24     ROS_INFO("Dishwasher %d finish working.", goal->dishwasher_id);
25     as->setSucceeded();
26 }
27 
28 int main(int argc, char** argv)
29 {
30     ros::init(argc, argv, "do_dishes_server");
31     ros::NodeHandle n;
32 
33     // 定義一個服務器
34     Server server(n, "do_dishes", boost::bind(&execute, _1, &server), false);
35     
36     // 服務器開始運行
37     server.start();
38 
39     ros::spin();
40 
41     return 0;
42 }
  • 運行效果:

  •  運行rqt_graph查看節點關系:

 

 

 

 話題列表如圖所示:

 

 

 


免責聲明!

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



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