1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

ROS action 勉強メモ

Posted at

actionの概要

ROSの基本通信message,serviceがあるが、制御用通信としてFBを見ながら次のアクションを決めるシーン、FBの待ち時間中に他の処理ができるようにしたいシーンにはactionが2つよりも柔軟的に対応できる。

actionlibのpkgでaction機能を実現している。actionは何が違う?簡単に言うとリクエストに対して継続的なFB機能がある。例:ロボットをある方向に100m移動を指令出した場合、目的地までの距離を100,90,80,,,,0までFBを継続的にみることができる、移動終了後にaction終了報告もしてもらえる、途中で止めることもできるような通信。

messsage、serviseとの違いイメージ
ROS通信.PNG

実際の通信protcol

20200907115536323.png

goal:目標リクエスト(ユーザー定義通信内容)
cancel:キャンセルする場合のキャンセルリクエスト
status:現在の状態の返し
result:結果の返し(1回だけ)(ユーザー定義通信内容)
feedback:指定周期で指定データーの返し(ユーザー定義通信内容)

actionの定義

.msg,.srvと同じようにpkgフォルダの下にactionフォルダを作り、定義したい通信内容を***.actionファイルを作成する。

Screenshot from 2023-07-22 21-25-08.png

"---"で3部分に区切りしたが、上から、goal,result,feedbackになっている。

定義したファイルをビルトできるようにCmakeLists.txtファイルにビルト設定を追加する

find_package(catkin REQUIRED COMPONENTS
  genmsg
  actionlib_msgs
  actionlib
  actionlib_msgs
)

add_action_files(
  FILES
  DoDishes.action
)

generate_messages(
  DEPENDENCIES
  std_msgs
  actionlib_msgs # action用追加
)

catkin_package(CATKIN_DEPENDS geometry_msgs roscpp rospy std_msgs message_runtime actionlib_msgs)

package.xml にビルト関連を追加する

<build_depend>actionlib</build_depend>
<build_depend>actionlib_msgs</build_depend>
<run_depend>actionlib</run_depend>
<run_depend>actionlib_msgs</run_depend>

これでビルト(catkin_make)してみるとdevelの下に関連するmsgファイルができたことがわかる。見ている通り、actionは複数のmsg機能で構成されたapiのイメージ。

キャプチャ.PNG

actionのclientを作ってみる

#include <actionlib/client/simple_action_client.h>
#include "learning_communication/DoDishesAction.h"

typedef actionlib::SimpleActionClient<learning_communication::DoDishesAction> Client;

// actions終了時に1回だけCallされる関数
void doneCb(const actionlib::SimpleClientGoalState& state,
        const learning_communication::DoDishesResultConstPtr& result)
{
    ROS_INFO("Yay! The dishes are now clean");
    ros::shutdown();
}

// actions終了時に1回だけCallされる関数
void activeCb()
{
    ROS_INFO("Goal just went active");
}

// feedback来る度にCallされる関数
void feedbackCb(const learning_communication::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を定義する
    Client client("do_dishes", true);

    // sever待ち
    ROS_INFO("Waiting for action server to start.");
    client.waitForServer();
    ROS_INFO("Action server started, sending goal.");

    // actionのgoalをセットする
    learning_communication::DoDishesGoal goal;
    goal.dishwasher_id = 1;

    // actionのgoalを送り、callbackを設定する
    client.sendGoal(goal,  &doneCb, &activeCb, &feedbackCb);

    ros::spin();

    return 0;
}

actionのseverを作ってみる

#include <ros/ros.h>
#include <actionlib/server/simple_action_server.h>
#include "learning_communication/DoDishesAction.h"

typedef actionlib::SimpleActionServer<learning_communication::DoDishesAction> Server;

// actionのgoalを受信したらCallする関数
void execute(const learning_communication::DoDishesGoalConstPtr& goal, Server* as)
{
    ros::Rate r(1);
    learning_communication::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 server(n, "do_dishes", boost::bind(&execute, _1, &server), false);
    
    // serverを開始する
    server.start();

    ros::spin();

    return 0;
}

actionを動かしてみる

cmake_listsファイルに下記cppビルト指定をする

add_executable(DoDishes_client src/DoDishes_client.cpp)
target_link_libraries(DoDishes_client ${catkin_LIBRARIES})
add_dependencies(DoDishes_client ${PROJECT_NAME}_gencpp)

add_executable(DoDishes_server src/DoDishes_server.cpp)
target_link_libraries(DoDishes_server ${catkin_LIBRARIES})
add_dependencies(DoDishes_server ${PROJECT_NAME}_gencpp)

これでビルト(catkin_make)完了すれば、使えるようになる。

ターミナル1

roscore

ターミナル2

rosrun learning_communication DoDishes_client

ターミナル3

rosrun learning_communication DoDishes_server

結果
キャプチャ.PNG

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?