ROS-I学习笔记(4)-Actions(1.Server)

共两部分:Server和Client

1.SimpleActionServer:actionlib_tutorials/Tutorials/SimpleActionServer(ExecuteCallbackMethod) - ROS Wiki

2.SimpleActionClient:

actionlib_tutorials/Tutorials/SimpleActionClient - ROS Wiki

第一部分:使用Execute回调编写简单操作服务器

Description:本教程介绍如何使用simple_action_server库创建斐波那契动作服务器。此示例操作服务器生成斐波那契序列,目标是序列的顺序,反馈是计算的序列,结果是最终序列。

1.创建Action Messages

在编写Action之前,定义目标、结果和反馈信息非常重要。创建的.action文件中定义了Action的目标、结果和反馈话题的类型和格式。

  1)创建actionlib_tutorials/action/Fibonacci.action文件:

#goal definition
int32 order
---
#result definition
int32[] sequence
---
#feedback
int32[] sequence

  2).修改CMakeList.txt

        ·添加actionlib_msgs包到find_package宏变量里面:

find_package(catkin REQUIRED COMPONENTS actionlib_msgs)

        ·使用add_action_files宏声明要生成的操作:

add_action_files(
  DIRECTORY action
  FILES Fibonacci.action
)

        ·调用generate_messages宏,不要忘记对actionlib_msg和其他消息包(如std_msg)的依赖关系:

generate_messages(
  DEPENDENCIES actionlib_msgs std_msgs  # Or other packages containing msgs
)

        ·将actionlib_msg添加到catkin_package宏,如下所示:

catkin_package(
  CATKIN_DEPENDS actionlib_msgs
)

        注意:有时您必须设置package.xml文件,因为我们正在生成消息,所以您必须在清单文件上声明,在运行时您必须生成消息。您可以插入下面的行。

<exec_depend>message_generation</exec_depend>

按下面步骤在你的action文件夹中创建msg文件:

$ cd ../.. # Go back to the top level of your catkin workspace
$ catkin_make
$ ls devel/share/actionlib_tutorials/msg/
FibonacciActionFeedback.msg  FibonacciAction.msg        FibonacciFeedback.msg
FibonacciResult.msg          FibonacciActionGoal.msg    FibonacciActionResult.msg  FibonacciGoal.msg
$ ls devel/include/actionlib_tutorials/
FibonacciActionFeedback.h  FibonacciAction.h        FibonacciFeedback.h  FibonacciResult.h
FibonacciActionGoal.h      FibonacciActionResult.h  FibonacciGoal.h

  (同样你可以通过在actionlib_msgs文件夹中python脚本文件generation.py手动编译)

2.写一个简单的服务器

首先:创建actionlib_tutorials/src/fibonacci_server.cpp文件,并参考下面代码:

   1 #include <ros/ros.h>
   2 #include <actionlib/server/simple_action_server.h>
   3 #include <actionlib_tutorials/FibonacciAction.h>
   4 
   5 class FibonacciAction
   6 {
   7 protected:
   8 
   9   ros::NodeHandle nh_;
  10   actionlib::SimpleActionServer<actionlib_tutorials::FibonacciAction> as_; // 节点句柄必须在这一行之前创建,否则会报错
  11   std::string action_name_;
  12   // 创建用来发布“反馈/结果”的Message    
  13   actionlib_tutorials::FibonacciFeedback feedback_;
  14   actionlib_tutorials::FibonacciResult result_;
  15 
  16 public:
  17 //此处的bind()函数可以从网上搜一下看,在这里就是执行了函数executeCB参数是this指针
  18   FibonacciAction(std::string name) :
  19     as_(nh_, name, boost::bind(&FibonacciAction::executeCB, this, _1), false),
  20     action_name_(name)
  21   {
  22     as_.start();
  23   }
  24 
  25   ~FibonacciAction(void)
  26   {
  27   }
  28 
  29   void executeCB(const actionlib_tutorials::FibonacciGoalConstPtr &goal)
  30   {
  31     // helper variables
  32     ros::Rate r(1);  //1Hz的频率执行循环
  33     bool success = true;
  34 
  35     // 将初始值压入反馈sequence队列
  36     feedback_.sequence.clear();
  37     feedback_.sequence.push_back(0);
  38     feedback_.sequence.push_back(1);
  39 
  40     // 将信息发布到终端
  41     ROS_INFO("%s: Executing, creating fibonacci sequence of order %i with seeds %i, %i", action_name_.c_str(), goal->order, feedback_.sequence[0], feedback_.sequence[1]);
  42 
  43     // 开始执行action
  44     for(int i=1; i<=goal->order; i++)
  45     {
  46       // 检查preempted是否已经被客户端请求
  47       if (as_.isPreemptRequested() || !ros::ok())
  48       {
  49         ROS_INFO("%s: Preempted", action_name_.c_str());
  50         // 设置action的状态到as_的preempted中
  51         as_.setPreempted();
  52         success = false;
  53         break;
  54       }
  55       feedback_.sequence.push_back(feedback_.sequence[i] + feedback_.sequence[i-1]);
  56       // 发布反馈
  57       as_.publishFeedback(feedback_);
  58       // 这个延时不是必要的,因为计算速度1Hz足够快
  59       r.sleep();
  60     }
  61 
  62     if(success)
  63     {
  64       result_.sequence = feedback_.sequence;
  65       ROS_INFO("%s: Succeeded", action_name_.c_str());
  66       // 设置状态成功,退出
  67       as_.setSucceeded(result_);
  68     }
  69   }
  70 
  71 
  72 };
  73 
  74 
  75 int main(int argc, char** argv)
  76 {
  77   ros::init(argc, argv, "fibonacci");
  78 
  79   FibonacciAction fibonacci("fibonacci");
  80   ros::spin();
  81 
  82   return 0;
  83 }

代码详解:

1).头文件,包含了action文件的使用的常见的库函数等;

 1 #include <ros/ros.h>
 2 #include <actionlib/server/simple_action_server.h> 

2).上面.action文件自动编译产生的,或者用python脚本生成;

3 #include <actionlib_tutorials/FibonacciAction.h>

3).action类中被保护的变量,在这里创建了 ros节点句柄和action服务器的句柄,其中action服务器在下面的构造函数中构造,另外这里创建了要发布的反馈和结果;

   7 protected:
   8 
   9   ros::NodeHandle nh_;
  10   actionlib::SimpleActionServer<actionlib_tutorials::FibonacciAction> as_; // NodeHandle instance must be created before this line. Otherwise strange error occurs.
  11   std::string action_name_;
  12   // create messages that are used to published feedback/result
  13   actionlib_tutorials::FibonacciFeedback feedback_;
  14   actionlib_tutorials::FibonacciResult result_;

4).在构造函数里创建了action服务器as_,并且赋值其中的变量:nh_,name还有可选函数executeCB(其参数为this,_1是占位符);同样action_name_赋值为name;

  18   FibonacciAction(std::string name) :
  19     as_(nh_, name, boost::bind(&FibonacciAction::executeCB, this, _1), false),
  20     action_name_(name)
  21   {
  22     as_.start();
  23   }

5).executeCB函数创建,参数是常量指针,指向了goal;

  29   void executeCB(const actionlib_tutorials::FibonacciGoalConstPtr &goal)
  30   {

6).函数内容:

  32     ros::Rate r(1);
  33     bool success = true;
  34 
  35     // push_back the seeds for the fibonacci sequence
  36     feedback_.sequence.clear();
  37     feedback_.sequence.push_back(0);
  38     feedback_.sequence.push_back(1);
  39 
  40     // publish info to the console for the user
  41     ROS_INFO("%s: Executing, creating fibonacci sequence of order %i with seeds %i, %i", action_name_.c_str(), goal->order, feedback_.sequence[0], feedback_.sequence[1]);

7).一个重要的功能是一个action客户端能发请求使当前的目标计算结束。频率是设置客户端抢占服务器的速度。

  43     // start executing the action
  44     for(int i=1; i<=goal->order; i++)
  45     {
  46       // check that preempt has not been requested by the client
  47       if (as_.isPreemptRequested() || !ros::ok())
  48       {
  49         ROS_INFO("%s: Preempted", action_name_.c_str());
  50         // set the action state to preempted
  51         as_.setPreempted();
  52         success = false;
  53         break;
  54       }
  55       feedback_.sequence.push_back(feedback_.sequence[i] + feedback_.sequence[i-1]);

8).这里是斐波那契数列的中间结果放在反馈队列中,并通过ROS_INFO发布到控制台,一边计算一边循环发布;

  56       // publish the feedback
  57       as_.publishFeedback(feedback_);
  58       // this sleep is not necessary, the sequence is computed at 1 Hz for demonstration purposes
  59       r.sleep();
  60     }

9).成功后的状态设置;

  62     if(success)
  63     {
  64       result_.sequence = feedback_.sequence;
  65       ROS_INFO("%s: Succeeded", action_name_.c_str());
  66       // set the action state to succeeded
  67       as_.setSucceeded(result_);
  68     }
  69   }

10).主函数。

  75 int main(int argc, char** argv)
  76 {
  77   ros::init(argc, argv, "fibonacci");
  78 
  79   FibonacciAction fibonacci("fibonacci");
  80   ros::spin();
  81 
  82   return 0;
  83 }

3.编译Compiling

1)添加下面到CMakeLIstanbul.txt

add_executable(fibonacci_server src/fibonacci_server.cpp)

target_link_libraries(
  fibonacci_server
  ${catkin_LIBRARIES}
)

add_dependencies(
  fibonacci_server
  ${actionlib_tutorials_EXPORTED_TARGETS}
)

完成之后,前后大概这个样子

 

 4.运行试试(终端输入)

1)roscore

2)rosrun actionlib_tutorials fibonacci_server

        你会看到:

  • [ INFO] 1250790662.410962000: Started node [/fibonacci], pid [29267], bound on [aqy], xmlrpc port [39746], tcpros port [49573], logging to [~/ros/ros/log/fibonacci_29267.log], using [real] time

3)检查一下发布的话题

rostopic list -v

4)你会看到

  • Published topics:
     * /fibonacci/feedback [actionlib_tutorials/FibonacciActionFeedback] 1 publisher
     * /fibonacci/status [actionlib_msgs/GoalStatusArray] 1 publisher
     * /rosout [rosgraph_msgs/Log] 1 publisher
     * /fibonacci/result [actionlib_tutorials/FibonacciActionResult] 1 publisher
     * /rosout_agg [rosgraph_msgs/Log] 1 publisher
    
    Subscribed topics:
     * /fibonacci/goal [actionlib_tutorials/FibonacciActionGoal] 1 subscriber
     * /fibonacci/cancel [actionlib_msgs/GoalID] 1 subscriber
     * /rosout [rosgraph_msgs/Log] 1 subscriber

 5)作图显示

rqt_graph

OK!!

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

D124lab

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

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

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

打赏作者

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

抵扣说明:

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

余额充值