【ROS入门】使用 ROS 动作(Action)机制实现目标请求、进度与完成结果的反馈

这篇具有很好参考价值的文章主要介绍了【ROS入门】使用 ROS 动作(Action)机制实现目标请求、进度与完成结果的反馈。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

任务要求

使用 ROS 动作(Action)机制实现目标请求、进度与完成结果的反馈:

  • 创建服务端,注册 Action
  • 客户端发送action 请求检测 40个零件
  • 服务端接收后,每隔 1s 检测一个零件 (每检测一个打印1次),并实时给客户端返回检测进度(客户端打印进度百分比),并在检测完毕时告知客户端目标完成。

话题模型

action 是一种类似于服务通信的实现,其实现模型也包含请求和响应,但是不同的是,在请求和响应的过程中,服务端还可以连续的反馈当前任务进度,客户端可以接收连续反馈并且还可以取消任务。

action结构图解:

【ROS入门】使用 ROS 动作(Action)机制实现目标请求、进度与完成结果的反馈,ROS,机器人,c++

action结构图解:
【ROS入门】使用 ROS 动作(Action)机制实现目标请求、进度与完成结果的反馈,ROS,机器人,c++

实现步骤

定义action文件

action、srv、msg 文件内的可用数据类型一致,且三者实现流程类似

按照固定格式创建action文件

首先新建功能包,并导入依赖: roscpp rospy std_msgs actionlib actionlib_msgs

然后功能包下新建 action 目录,新增 check.action文件。

action 文件内容组成分为三部分:请求目标值、最终响应结果、连续反馈,三者之间使用—分割

内容如下:
【ROS入门】使用 ROS 动作(Action)机制实现目标请求、进度与完成结果的反馈,ROS,机器人,c++

编辑配置文件

CMakeLists.txt

find_package
(catkin REQUIRED COMPONENTS
  roscpp
  rospy
  std_msgs
  actionlib
  actionlib_msgs
)
add_action_files(
  FILES
  check.action
)
generate_messages(
  DEPENDENCIES
  std_msgs
  actionlib_msgs
)
catkin_package(
#  INCLUDE_DIRS include
#  LIBRARIES demo04_action
 CATKIN_DEPENDS roscpp rospy std_msgs actionlib actionlib_msgs
#  DEPENDS system_lib
)

编译生成中间文件

编译后会生成一些中间文件。

msg文件(…/工作空间/devel/share/包名/msg/xxx.msg):

【ROS入门】使用 ROS 动作(Action)机制实现目标请求、进度与完成结果的反馈,ROS,机器人,c++

C++ 调用的文件(…/工作空间/devel/include/包名/xxx.h):

【ROS入门】使用 ROS 动作(Action)机制实现目标请求、进度与完成结果的反馈,ROS,机器人,c++

Python 调用的文件(…/工作空间/devel/lib/python3/dist-packages/包名/msg/xxx.py):

【ROS入门】使用 ROS 动作(Action)机制实现目标请求、进度与完成结果的反馈,ROS,机器人,c++

编写服务端和客户端

vscode配置

{
  "configurations": [
    {
      "browse": {
        "databaseFilename": "${default}",
        "limitSymbolsToIncludedHeaders": false
      },
      "includePath": [
        "/opt/ros/noetic/include/**",
        "/home/chenyikeng/demo01_ws/src/helloworld/include/**",
        "/home/chenyikeng/ROS_Topic_Demo/src/topic_demo/include/**",
        "/usr/include/**",
        "/home/chenyikeng/ROS_Topic_Demo/devel/include"
      ],
      "name": "ROS",
      "intelliSenseMode": "gcc-x64",
      "compilerPath": "/usr/bin/gcc",
      "cStandard": "gnu11",
      "cppStandard": "c++14"
    }
  ],
  "version": 4
}

服务端

/*
流程:
    1.包含头文件;
    2.初始化ROS节点;
    3.创建NodeHandle;
    4.创建action服务对象;
    5.处理请求,产生反馈与响应;
      a.获取并解析提交的目标值
      b.产生连续反馈
      c.最终结果响应
    6.spin().
*/


#include "ros/ros.h"
#include "actionlib/server/simple_action_server.h"  //actionlib里头服务端的库
#include "action_demo/checkAction.h"    //自定义action文件时编译生成的库

// 使用模板创建action服务对象并定义
typedef actionlib::SimpleActionServer<action_demo::checkAction> Server;


//请求处理(a.解析提交的目标值;b.产生连续反馈;c.最终结果响应) --- 回调函数
void callBack(const action_demo::checkGoalConstPtr &goalPtr, Server*  server)
{
    // a.获取并解析提交的目标值
    int goal_num = goalPtr -> num;
    ROS_INFO("客户端提交的目标值是: %d",goal_num);

    // b.产生连续反馈
    ros::Rate rate(1); //1Hz
    int result = 0;
    for(int i = 1; i<= goal_num; i++)
    {
        // 累加
        result ++;
        // 休眠
        rate.sleep();
        //产生(封装)连续反馈
        //创建feedback对象
        action_demo::checkFeedback fb;
        fb.progress_bar = i / (double)goal_num;
        //发送
        server->publishFeedback(fb);
        //打印
        ROS_INFO("检测%d个零件", result);
    }

    // c.最终结果响应
    // 创建result对象
    ROS_INFO("检测完成");
    action_demo::checkResult r;
    r.result = result;
    server -> setSucceeded(r);
}

int main(int argc, char *argv[])
{
    setlocale(LC_ALL,"");

    ros::init(argc,argv,"check_server");

    ros::NodeHandle n;

    // 创建action服务对象
    /*SimpleActionServer(ros::NodeHandle n,     #句柄
                        std::string name,       #话题名称
                        boost::function<void (const action_demo::checkGoalConstPtr &)> execute_callback,    
                        #回调函数,可以解析传入的目标值,产生连续反馈,以及响应最终结果
                        bool auto_start)        #布尔值,是否自动启动
    */
    Server server(n,"check",boost::bind(&callBack,_1,&server),false);

    //如果auto_start为false,那么需要手动调用该函数启动服务
    server.start();     
    ROS_INFO("服务启动……");

    //spin()回旋
    ros::spin();
    return 0;
}

客户端

/*
流程:
    1.包含头文件;
    2.初始化ROS节点;
    3.创建NodeHandle;
    4.创建action客户端对象;
    5.发送目标,处理反馈以及最终结果;
      a.连接建立 --- 回调函数
      b.处理连续反馈 --- 回调函数
      c.处理最终响应 --- 回调函数
    6.spin().
*/
#include "ros/ros.h"
#include "actionlib/client/simple_action_client.h"  //actionlib里头服务端的库
#include "action_demo/checkAction.h"    //自定义action文件时编译生成的库


// 创建action客户端对象
typedef actionlib::SimpleActionClient<action_demo::checkAction> Client;

// 服务端返回最终响应结果时候触发的回调
void done_cb(const actionlib::SimpleClientGoalState &state, const action_demo::checkResultConstPtr &result)
{
    // 判断响应状态是否成功
    if (state.state_ == state.SUCCEEDED)
        ROS_INFO("检测完成");
    else 
        ROS_INFO("任务失败!");
}

// 连接被激活的时候触发的回调
void active_cb()
{
    ROS_INFO("服务已经被激活....");
}

// 连续反馈时的回调函数
void feedback_cb(const action_demo::checkFeedbackConstPtr &feedback)
{   
    float progress_bar_percentage = feedback->progress_bar*100;
    if(progress_bar_percentage-(int)progress_bar_percentage==0)
        ROS_INFO("当前进度:%d%%",(int)progress_bar_percentage);
    else
        ROS_INFO("当前进度:%.1f%%",progress_bar_percentage);
}

int main(int argc, char *argv[])
{
    setlocale(LC_ALL,"");

    ros::init(argc,argv,"check_client");

    ros::NodeHandle n;

    // 创建action客户端对象;
    // SimpleActionClient(ros::NodeHandle & n, const std::string & name, bool spin_thread = true)
    // actionlib::SimpleActionClient<demo01_action::AddIntsAction> client(nh,"addInts");
    Client client(n,"check",true);

    //等待服务启动
    ROS_INFO("等待服务器启动……");
    client.waitForServer();

    // 发送目标,处理反馈以及最终结果;
    /*  
        void sendGoal(const demo01_action::AddIntsGoal &goal, 
            boost::function<void (const actionlib::SimpleClientGoalState &state, const demo01_action::AddIntsResultConstPtr &result)> done_cb, 
            用于处理最终响应
            boost::function<void ()> active_cb, 
            连接被激活的时候使用的回调
            boost::function<void (const demo01_action::AddIntsFeedbackConstPtr &feedback)> feedback_cb)
            处理连续反馈时相关的回调函数
    */

    // 设置目标值:40个零件
    // 声明对象
    action_demo::checkGoal goal;
    goal.num = 40;

    // 发送目标数据
    client.sendGoal(goal,&done_cb,&active_cb,&feedback_cb);


    // spin()回旋
    ros::spin();
    return 0;
}

编译配置文件

add_executable(check_server_c src/check_server_c.cpp)
add_executable(check_client_c src/check_client_c.cpp)
...

add_dependencies(check_server_c ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
add_dependencies(check_client_c ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
...

target_link_libraries(check_server_c
  ${catkin_LIBRARIES}
)
target_link_libraries(check_client_c
  ${catkin_LIBRARIES}
)

执行

首先启动 roscore,然后分别启动action服务端与action客户端,最终运行结果与案例类似。

结果如下:

【ROS入门】使用 ROS 动作(Action)机制实现目标请求、进度与完成结果的反馈,ROS,机器人,c++文章来源地址https://www.toymoban.com/news/detail-729288.html

到了这里,关于【ROS入门】使用 ROS 动作(Action)机制实现目标请求、进度与完成结果的反馈的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【ROS2指南-7】理解ROS2的Action

    目标: 理解并学习ROS 2 中的Action通信方式。 教程级别: 初学者 时间: 15分钟 内容 背景 先决条件 任务 1 设置 2 使用动作 3 ros2节点信息 4 ros2 动作列表 5 ros2 动作信息 6 ros2界面展示 7 ros2 动作 send_goal 概括 下一步 相关内容 动作是 ROS 2 中的一种通信类型,用于长时间运行的任

    2023年04月16日
    浏览(50)
  • ROS2 学习(五)接口,动作

    通信双方统一规定好接口。比如图像 img,控制运动的线速度和角速度…… 我们也不用了解具体实现,基本就是了解接口会去用就行。 添加接口 不是说我们写一个接口文件就算添加好了,我们也要通过读取文件。 在 CMakeList.txt 中可以看到: 指从相应的相对目录文件中找接口

    2024年02月11日
    浏览(48)
  • ubutu下ros2实现小车仿真建模与目标检测

    1.安装ros2 这里使用小鱼的一键安装,根据自己的喜好安装,博主用的是ros2的foxy版本 2.下载代码(这里使用的是古月居的代码) https://book.guyuehome.com/ 可以结合古月居的B站视频来自己一步一步操作,里面有讲解基础理论与一些环境的配置 https://www.bilibili.com/video/BV16B4y1Q7jQ?p=1

    2024年02月04日
    浏览(40)
  • ROS:古月居第一次作业(话题与服务编程、动作编程、TF编程)

    话题与服务编程:通过代码新生一只海龟,放置在(5,5)点,命名为“turtle2”;通过代码订阅turtle2的实时位置并打印在终端;控制turtle2实现旋转运动; demo_turtle.launch demo_turtle.cpp CMakeList.txt 运行: 结果: 动作编程:客户端发送一个运动目标,模拟机器人运动到目标位置的过

    2024年02月07日
    浏览(48)
  • JAVA使用反射机制和注解实现对信息的处理-----JAVA入门基础教程

    import java.lang.annotation.Annotation; import java.lang.reflect.Field; public class AnnotationTest { public static void main(String[] args) throws Exception { Class c = Class.forName(\\\"Customer\\\"); c = Customer.class; Table table = (Table)c.getDeclaredAnnotation(Table.class); System.out.println(table.value()); Annotation[] annotations = c.getDeclaredAnnotatio

    2024年02月15日
    浏览(46)
  • 基于ros和openpcdet使用自己的雷达进行实时三维目标检测

    参考博主hello689的教程,文中主要介绍了对于kitti的三维目标检测,本文对代码进行修改,添加旋转坐标轴的代码,以适配自己的雷达,可以参考这个博主的流程,再看本文对旋转参数的修改。 3.1 ros.py代码修改 3.2 pointpillar.launch代码修改 3.3 pointpillar.rviz代码修改 3.4 ros.py订阅话

    2024年01月23日
    浏览(42)
  • yolov8跟踪模式部署Ros系统上,跟踪鼠标选择的目标,实时发布目标的坐标信息(python实现)

    鼠标不点击目标,不发送任何信息,图像显示的是yolov8检测目标的所有结果 鼠标点击后,跟踪鼠标选择的目标并实时循环发布目标的坐标信息,图像显示的是目标的坐标框 若选择的目标丢失在摄像头内,暂停发送坐标信息,且图像显示的是yolov8检测目标的所有结果,等待鼠

    2024年04月27日
    浏览(42)
  • ROS通信机制之话题(Topics)的发布与订阅以及自定义消息的实现

    我们知道在 ROS 中,由很多互不相干的节点组成了一个复杂的系统,单个的节点看起来是没起什么作用,但是节点之间进行了通信之后,相互之间能够交互信息和数据的时候,就变得很有意思了。 节点之间进行通信的一个常用方法就是使用 话题(topic) ,话题表示的是一个定义

    2024年02月11日
    浏览(37)
  • 创建 ROS action操作涉及编写操作定义以及相应的服务器和客户端代码

    架构师指南 创建 ROS 操作涉及编写操作定义以及相应的服务器和客户端代码。我将提供详细的分步指南来说明如何完成此操作。 第 1 步:定义操作 首先,您需要在** .action 文件中定义您的操作。让我们创建一个名为 的简单操作 Example.action **,用于发送一个数字、对其进行处

    2024年02月22日
    浏览(44)
  • 【运动规划算法项目实战】如何实现机器人多目标点导航(附ROS C++代码)

    在ROS机器人应用中,实现机器人多目标点导航是非常常见的需求。本文将介绍如何使用ROS和actionlib来实现机器人的多目标点导航,目标点信息将被记录在YAML文件中。 我们可以通过使用MoveBaseAction来实现机器人的导航功能。MoveBaseAction是一个ROS中的action类型,它提供了控制机器

    2024年02月10日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包