ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

ROS通信机制(四) —— 动作(action)与action文件

2021-11-03 23:01:01  阅读:191  来源: 互联网

标签:actionlib 通信 server wash action ROS 服务端 客户端


文章目录

简述

动作消息通信与服务消息通信非常相似,服务具有与请求和响应分别对应的目标(goal)和结果(result)。除此之外,动作中多了反馈(feedback)。在一些场景下,收到请求后需要很长时间才能响应,又需要中间值时,则可以使用这个反馈发送相关的数据。

特点

反馈在动作客户端(action client)和动作服务器(action server)之间执行异步双向消息通信,其中动作客户端设置动作目标(goal),而动作服务器根据目标执行指定的工作,并将动作反馈和动作结果发送给动作客户端。与服务不同,动作通常用于指导复杂的机器人任务,例如发送一个目标值之后,还可以在任意时刻发送取消目标的命令。

交互过程

action通信使用的是ROS提供的通信包集actionlib,参考http://wiki.ros.org/actionlib

action客户端与服务器应用程序之间的交互:
在这里插入图片描述
action客户端与服务端之间的消息通信接口:
在这里插入图片描述

核心元素

  1. ROS Master(管理者)
    必须首先被运行,并使用XMLRPC服务器,负责管理节点之间的消息通信中的连接信息。
  2. Server (服务端)
    服务端以请求作为输入,以响应作为输出,请求和响应都是消息,服务端收到服务请求后,执行指定的服务,并将结果下发给客户端,服务端是用于执行指定命令的节点。
  3. Client (客户端)
    客户端以请求作为输出,以响应作为输入,请求和响应都是消息,并发送服务请求到服务端后接收其结果,客户端是用于传达给定命令并接收结果值的节点。
  4. action specification(动作规范)
    参考:http://wiki.ros.org/cn/actionlib/DetailedDescription
    客户端节点和服务器节点通过建立在ROS消息之上的ROS动作协议进行通信,这些消息包括:
     
    goal:用于向服务器发送目标。goal 话题使用自动生成的ActionGoal消息(例actionlib/TestActionGoal),用于将新目标发送到动作服务器。 实质上,ActionGoal 消息包装的是一个goal消息,并将其与目标ID捆绑在一起;
     
    cancel :用于向服务器发送取消请求。cancel topic使用actionlib_msgs/GoalID消息,并允许动作客户端将cancel请求发送到action server。 每个cancel消息都有一个timestamp(时间戳)和goal ID;
     
    status :用于通知客户端系统中每个目标的当前状态。状态话题使用的话题名为actionlib_msgs/GoalStatusArray,它为动作客户端提供有关动作服务器当前正在跟踪的每个目标服务器状态信息;
     
    feedback :用于周期反馈目标的辅助信息。feedback主题使用自动生成的ActionFeedback消息,并为服务实现(server implementers)提供在处理目标期间向动作客户端发送定期更新的方法;
     
    result :用于向client发送任务的执行结果,这个topic只会发布一次。result话题使用自动生成的ActionResult消息(例如:actionlib/TestActionResult),并为服务实现(server implementers)提供完成目标后向客户端发送信息的方法。

自定义action文件

ROS的action数据类型可以在这里查看。

action 文件中的数据分成三部分,使用 “- - -” 隔开,上面是目标定义,中间是结果定义,下面是反馈定义。

下面来创建一个洗衣的action文件,首先,在action_test包中创建action文件夹,然后在文件夹中创建消息文件(Laundry.action)。

# goal,洗衣类型 1:开始快洗;2:开始高温洗;3:开始浸泡洗
uint8 wash_type
---
# result,洗涤结果
string wash_result
---
# feedback,洗涤的进度
uint8 wash_percent

在这里插入图片描述

代码示例(服务端和客户端)

需求描述:编写服务端和客户端文件,来模拟洗衣过程,客户端输入洗衣模式后开始洗衣,服务的不断反馈洗衣进度,并反馈洗衣完成的结果。

继续在service_test中分别创建server.cpp(服务端)和client.cpp(客户端)两个文件。
在这里插入图片描述

服务端(action_server.cpp)

#include "ros/ros.h"
#include "actionlib/server/simple_action_server.h"
#include "action_test/LaundryAction.h"
#include <iostream>

typedef actionlib::SimpleActionServer<action_test::LaundryAction> ActionServer;

// 4.收到action的goal后调用的回调函数
void executeCb(const action_test::LaundryGoalConstPtr &goal, ActionServer *server)
{
    // 获取目标值
    uint8_t wash_type = goal->wash_type;
    std::string wash_mode;
    switch (wash_type)
    {
    case 1:
        wash_mode = "快洗";
        break;
    case 2:
        wash_mode = "高温洗";
        break;
    case 3:
        wash_mode = "浸泡洗";
        break;
    default:
        break;
    }
    ROS_INFO("目标值为%d,开始%s!", wash_type, wash_mode.c_str());

    // 响应连续反馈
    action_test::LaundryFeedback feedback;
    for (int i = 0; i <= 100; i++)
    {
        feedback.wash_percent = i;
        server->publishFeedback(feedback);
        ros::Duration(0.5).sleep();
    }

    // 反馈结果
    action_test::LaundryResult result;
    result.wash_result = wash_mode + "完成!";
    server->setSucceeded(result);
}

int main(int argc, char **argv)
{
    // 设置编码
    setlocale(LC_ALL, "");

    // 1.初始化ROS节点
    ros::init(argc, argv, "action_server");

    // 2.实例化ROS句柄
    ros::NodeHandle nh;

    // 3.实例化action服务端对象
    // 参数2为动作服务器名称,参数3为当一个新目标被接收时在一个单独的线程中被调用,参数4为告诉ActionServer是否在它出现时立即开始发布
    ActionServer server(nh, "laundry", boost::bind(&executeCb, _1, &server), false);
    server.start();

    ros::spin();

    return 0;
}

客户端(action_client.cpp)

#include "ros/ros.h"
#include "actionlib/client/simple_action_client.h"
#include "action_test/LaundryAction.h"

typedef actionlib::SimpleActionClient<action_test::LaundryAction> ActionClient;

void doneCb(const actionlib::SimpleClientGoalState &state, const action_test::LaundryResultConstPtr &result)
{
    if (state.state_ == state.SUCCEEDED)
    {
        ROS_INFO("反馈结果:%s", result->wash_result.c_str());
    }
    else
    {
        ROS_INFO("任务失败!");
    }
}

void activeCb()
{
    ROS_INFO("动作已经被激活....");
}

void feedbackCb(const action_test::LaundryFeedbackConstPtr &feedback)
{
    ROS_INFO("洗涤进度为:%d%s", feedback->wash_percent, "%");
}

int main(int argc, char **argv)
{
    // 设置编码
    setlocale(LC_ALL, "");

    // 1.初始化ROS节点
    ros::init(argc, argv, "action_client");

    // 2.实例化ROS句柄
    ros::NodeHandle nh;

    // 3.实例化action客户端对象
    // 参数2为动作的名称,参数3默认为true,无需再调用ros::spin(),设置为false时需手动调用
    ActionClient client(nh, "laundry", true);
    // 等待服务端启动
    client.waitForServer();

    // 4.定义动作目标数据
    action_test::LaundryGoal goal;
    goal.wash_type = 1;

    // 5.发送目标,同时注册回调,处理反馈以及最终结果
    // 参数1是转换为Done时处理的回调函数,参数2为转换为Active时处理的回调函数,参数3为每当收到此目标的反馈时就调用的回调函数
    client.sendGoal(goal, &doneCb, &activeCb, &feedbackCb);

    ros::spin();

    return 0;
}

配置 CMakeLists.txt

# catkin构建时依赖的组件包
find_package(catkin REQUIRED COMPONENTS
  roscpp
  rospy
  std_msgs
  actionlib
  actionlib_msgs
)

# 配置action源文件,FILES将引用当前功能包目录的action目录中的*.action文件,自动生成一个头文件(*.h)
add_action_files(
  FILES
  Laundry.action
)

# 生成消息时依赖于std_msgs、actionlib_msgs
generate_messages(
  DEPENDENCIES
  std_msgs
  actionlib_msgs
)

# 运行时依赖,描述了库、catkin构建依赖项和系统依赖的功能包
catkin_package(
#  INCLUDE_DIRS include
#  LIBRARIES action_test
 CATKIN_DEPENDS roscpp rospy std_msgs actionlib actionlib_msgs 
#  DEPENDS system_lib
)

# 节点构建选项,配置可执行文件
add_executable(action_client src/action_client.cpp)
add_executable(action_server src/action_server.cpp)

# 构建库和可执行文件之前,预先生成依赖消息
add_dependencies(action_client ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
add_dependencies(action_server ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})

# 节点构建选项,配置目标链接库
target_link_libraries(action_client
  ${catkin_LIBRARIES}
)
target_link_libraries(action_server
  ${catkin_LIBRARIES}
)

编译和运行

使用Ctrl+Shift+B进行编译,然后先使用roscore命令启动主节点。在新终端source下环境变量,然后分别运行服务端和客户端,此时可以看到服务端接收到了客户端的请求并不断反馈中间状态,并在最终反馈结果。
在这里插入图片描述
☝ ★★★ — 返回 《ROS机器人开发笔记汇总》总目录 — ★★★ ☝

标签:actionlib,通信,server,wash,action,ROS,服务端,客户端
来源: https://blog.csdn.net/zbw1185/article/details/121003478

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有