1. 程式人生 > 其它 >ROS節點通訊(三)action

ROS節點通訊(三)action

官方wiki:http://wiki.ros.org/actionlib

目錄

1、說明

ROS中的action也是節點通訊的一種方式,其和service-client的不同點在於,service-client是一問一答模式,而action則多了一個反饋機制,即服務端不間斷給客戶端反饋

api參考:https://docs.ros.org/en/api/actionlib/html/classactionlib_1_1SimpleActionClient.html

2、程式碼示例

跳過建立工作區和功能包步驟

2.1、定義資料結構

action定義的資料結構分成三個部分,中間用 --- 隔開,按照順序如下:

2.1.1、goal

為了使action完成任務,引入一個目標概念,由客戶端傳送到服務端

2.1.4、result

結果由服務端傳送給客戶端,在完成 goal 之後,傳送的任務結果

2.1.3、feedback

反饋為服務端傳送到客戶端,高度客戶端,當前任務的進展

TestData.action

#請求的資料,一般由客戶端傳送給服務端
uint32 id
---
#請求結果,一般由服務端傳送給客戶端
uint32 total
---
#反饋的訊息內容,一般由服務端不間斷髮送到客戶端
float32 percent

.action 檔案預設儲存在 action 目錄下

對於該檔案,會生成7個訊息型別,以便客戶端和服務端通訊,這些型別由 genaction.py 生成:

  1. TestDataAction.msg
  2. TestDataActionGoal.msg
  3. TestDataActionResult.msg
  4. TestDataActionFeedback.msg
  5. TestDataGoal.msg
  6. TestDataResult.msg
  7. TestDataFeedback.msg

2.2、服務端

#include <ros/ros.h>
#include <test_action/TestDataAction.h>
#include <actionlib/server/simple_action_server.h>

typedef actionlib::SimpleActionServer<test_action::TestDataAction> Server;

void execute(const test_action::TestDataGoalConstPtr& goal, Server* server)
{
    ros::Rate rate(1);
    test_action::TestDataFeedback feedback;

    ROS_INFO("Dishwasher %d is working.", goal->id);

    for(int index = 1; index <= 10; index++)
    {
        feedback.percent = index * 10;
        server->publishFeedback(feedback);
        rate.sleep();
    }

    ROS_INFO("Dishwasher %d finish working.", goal->id);
    server->setSucceeded();
}

int main(int argc, char** argv)
{
    ros::init(argc, argv, "test_action_service");
    ros::NodeHandle handle;
    //構建一個action服務,第二個引數是服務的名稱,客戶端需要根據這個唯一的名稱進行連線
    //最後一個引數表示是否構建完成之後就開始執行,一般應該設定為false,並在構建完成之後使用start()方法開始
    Server server(handle, "do_action", 
                  boost::bind(&execute, _1, &server), false);
    server.start();
    ros::spin();
    return 0;
}

2.3、客戶端

#include <ros/ros.h>
#include <test_action/TestDataAction.h>
#include <actionlib/client/simple_action_client.h>

typedef actionlib::SimpleActionClient<test_action::TestDataAction> Client;

//完成呼叫回撥
void doneCb(const actionlib::SimpleClientGoalState& state,
            const test_action::TestDataResultConstPtr& result)
{
    ROS_INFO("The dishes are now clean");
    ros::shutdown();
}

void activeCb()
{
    ROS_INFO("goal just went active");
}

//反饋
void feedbackCb(const test_action::TestDataFeedbackConstPtr& feedback)
{
    ROS_INFO("percent: %f", feedback->percent);
}

int main(int args, char** argv)
{
    ros::init(args, argv, "test_action_client");
    Client client("do_action", true);
    ROS_INFO("waiting for action server to start");
    client.waitForServer();
    ROS_INFO("action server started, sending goal");

    test_action::TestDataGoal goal;
    goal.id = 9;//填入goal
    //客戶端傳送目標,後三個是各個階段的回撥,分別在完成時、通訊剛啟用時和反饋過程中
    client.sendGoal(goal, &doneCb, &activeCb, &feedbackCb);
    ros::spin();

    return 0;
}

2.4、構建配置

CMakeLists.txt需要新增以下包依賴

find_package(catkin REQUIRED genmsg actionlib_msgs actionlib)
add_action_files(DIRECTORY action FILES DoDishes.action)
generate_messages(DEPENDENCIES actionlib_msgs)

其中,genmsgactionlib_msgs 是構建 .action 檔案的時候需要的依賴,actionlib 是編譯的時候需要的依賴

packages.xml 配置

<buildtool_depend>catkin</buildtool_depend>
<buildtool_depend>genmsg</buildtool_depend>
<build_export_depend>actionlib_msgs</build_export_depend>
<build_depend>actionlib</build_depend>
<build_depend>actionlib_msgs</build_depend>
<exec_depend>actionlib</exec_depend>
<exec_depend>actionlib_msgs</exec_depend>

2.5、結果

服務端:

[ INFO] [1621921903.942496821]: Dishwasher 9 is working.
[ INFO] [1621921913.942535907]: Dishwasher 9 finish working.

客戶端:

[ INFO] [1621921903.728245862]: waiting for action server to start
[ INFO] [1621921903.941538934]: action server started, sending goal
[ INFO] [1621921903.942692392]: goal just went active
[ INFO] [1621921903.943088999]: percent: 10.000000
[ INFO] [1621921904.942911217]: percent: 20.000000
[ INFO] [1621921905.942921653]: percent: 30.000000
[ INFO] [1621921906.942895095]: percent: 40.000000
[ INFO] [1621921907.942843906]: percent: 50.000000
[ INFO] [1621921908.942901935]: percent: 60.000000
[ INFO] [1621921909.942896131]: percent: 70.000000
[ INFO] [1621921910.942844776]: percent: 80.000000
[ INFO] [1621921911.942889215]: percent: 90.000000
[ INFO] [1621921912.942941318]: percent: 100.000000
[ INFO] [1621921913.943146759]: The dishes are now clean