动作通信类型的消息类型是什么,动作通信如何定义的,请举例?

问题描述:

动作通信类型的消息类型是什么,动作通信如何定义的,请举例?

问题解答:

在ROS中,动作(Action)通信是一种更复杂的通信机制,用于需要较长时间才能完成的任务。动作通信使用动作消息类型,这些消息类型包含三个部分:目标(Goal)、结果(Result)和反馈(Feedback)。这些消息类型文件以.action为扩展名,包含三个部分,用三个连字符(---)分隔。

动作通信的消息类型

动作消息类型定义了动作服务器和动作客户端之间传输的数据结构,包括目标、结果和反馈。

动作通信的定义

动作通信的定义包括以下几个步骤:

  1. 定义动作消息类型

    • action目录下创建动作消息类型文件。
  2. 动作服务器

    • 编写一个ROS节点提供动作服务。
  3. 动作客户端

    • 编写一个ROS节点发送目标并处理反馈和结果。

示例

假设我们有一个自定义动作消息类型CountNumbers.action,内容如下:

#goal define
int32 target_number
int32 target_step
---
#result define
bool finish
---
#feedback define
float32 count_percent
int32 count_current
1. 定义动作消息类型

在包的action目录下创建CountNumbers.action文件:

#goal define
int32 target_number
int32 target_step
---
#result define
bool finish
---
#feedback define
float32 count_percent
int32 count_current

CMakeLists.txtpackage.xml中添加配置以支持自定义动作消息类型:

CMakeLists.txt

find_package(catkin REQUIRED COMPONENTS roscpp actionlib actionlib_msgs message_generation)

add_action_files(
  FILES
  CountNumbers.action
)

generate_messages(
  DEPENDENCIES
  actionlib_msgs std_msgs
)

catkin_package(
  CATKIN_DEPENDS actionlib_msgs message_runtime
)

package.xml

<build_depend>actionlib_msgs</build_depend>
<build_depend>message_generation</build_depend>
<exec_depend>actionlib</exec_depend>
<exec_depend>actionlib_msgs</exec_depend>
<exec_depend>message_runtime</exec_depend>

然后编译包:

catkin_make
source devel/setup.bash
2. 动作服务器

编写一个动作服务器节点count_numbers_server.cpp,提供CountNumbers动作服务:

src/count_numbers_server.cpp

#include <ros/ros.h>
#include <actionlib/server/simple_action_server.h>
#include <your_package_name/CountNumbersAction.h>

class CountNumbersAction
{
protected:
  ros::NodeHandle nh_;
  actionlib::SimpleActionServer<your_package_name::CountNumbersAction> as_;
  std::string action_name_;
  your_package_name::CountNumbersFeedback feedback_;
  your_package_name::CountNumbersResult result_;

public:
  CountNumbersAction(std::string name) :
    as_(nh_, name, boost::bind(&CountNumbersAction::executeCB, this, _1), false),
    action_name_(name)
  {
    as_.start();
  }

  void executeCB(const your_package_name::CountNumbersGoalConstPtr &goal)
  {
    ros::Rate r(1);
    bool success = true;
    int count = 0;

    for(int i = 1; i <= goal->target_number; i += goal->target_step)
    {
      if (as_.isPreemptRequested() || !ros::ok())
      {
        as_.setPreempted();
        success = false;
        break;
      }
      count = i;
      feedback_.count_current = count;
      feedback_.count_percent = (float)i / goal->target_number * 100;
      as_.publishFeedback(feedback_);
      r.sleep();
    }

    if(success)
    {
      result_.finish = true;
      as_.setSucceeded(result_);
    }
  }
};

int main(int argc, char** argv)
{
  ros::init(argc, argv, "count_numbers");
  CountNumbersAction count_numbers("count_numbers");
  ros::spin();
  return 0;
}

CMakeLists.txt中添加该节点的编译指令:

CMakeLists.txt(部分内容):

add_executable(count_numbers_server src/count_numbers_server.cpp)
target_link_libraries(count_numbers_server ${catkin_LIBRARIES})
add_dependencies(count_numbers_server ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
3. 动作客户端

编写一个动作客户端节点count_numbers_client.cpp,发送目标并处理反馈和结果:

src/count_numbers_client.cpp

#include <ros/ros.h>
#include <actionlib/client/simple_action_client.h>
#include <your_package_name/CountNumbersAction.h>

int main(int argc, char **argv)
{
  ros::init(argc, argv, "count_numbers_client");

  if (argc != 3)
  {
    ROS_INFO("Usage: count_numbers_client <target_number> <target_step>");
    return 1;
  }

  actionlib::SimpleActionClient<your_package_name::CountNumbersAction> ac("count_numbers", true);

  ROS_INFO("Waiting for action server to start...");
  ac.waitForServer();

  your_package_name::CountNumbersGoal goal;
  goal.target_number = atoi(argv[1]);
  goal.target_step = atoi(argv[2]);

  ROS_INFO("Sending goal...");
  ac.sendGoal(goal,
              [](const actionlib::SimpleClientGoalState& state,
                 const your_package_name::CountNumbersResultConstPtr& result)
              {
                ROS_INFO("Finished in state [%s]", state.toString().c_str());
                ROS_INFO("Result: %s", result->finish ? "True" : "False");
              },
              actionlib::SimpleActionClient<your_package_name::CountNumbersAction>::SimpleActiveCallback(),
              [](const your_package_name::CountNumbersFeedbackConstPtr& feedback)
              {
                ROS_INFO("Feedback: current_count = %d, percent_complete = %.2f", feedback->count_current, feedback->count_percent);
              });

  ros::spin();
  return 0;
}

CMakeLists.txt中添加该节点的编译指令:

CMakeLists.txt(部分内容):

add_executable(count_numbers_client src/count_numbers_client.cpp)
target_link_libraries(count_numbers_client ${catkin_LIBRARIES})
add_dependencies(count_numbers_client ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
4. 编译并运行

编译你的ROS包:

cd ~/catkin_ws
catkin_make
source devel/setup.bash

然后,在三个不同的终端中分别运行roscore、动作服务器和动作客户端:

roscore
rosrun your_package_name count_numbers_server
rosrun your_package_name count_numbers_client 10 2

动作客户端节点将会发送目标到count_numbers动作服务器,并处理反馈和结果,输出类似于:

Waiting for action server to start...
Sending goal...
Feedback: current_count = 2, percent_complete = 20.00
Feedback: current_count = 4, percent_complete = 40.00
Feedback: current_count = 6, percent_complete = 60.00
Feedback: current_count = 8, percent_complete = 80.00
Feedback: current_count = 10, percent_complete = 100.00
Finished in state [SUCCEEDED]
Result: True

总结

  • 消息类型:在这个示例中,定义了一个自定义动作消息类型CountNumbers.action
  • 动作服务器:提供CountNumbers动作服务,处理目标并返回结果和反馈。
  • 动作客户端:发送目标到CountNumbers动作服务器,并处理反馈和结果。

通过以上步骤和示例,你可以定义和使用自定义动作消息类型,实现ROS节点之间的动作通信。

  • 13
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

神笔馬良

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值