< >
Home » ROS与C++入门教程 » ROS与C++入门教程-actionlib-编写基于回调函数的客户端

ROS与C++入门教程-actionlib-编写基于回调函数的客户端

ROS与C++入门教程-actionlib-编写基于回调函数的客户端

说明:

  • 介绍如何编写基于回调函数的客户端
  • 某些情况下,阻塞直到goal完成的可扩展性很低,基于事件驱动,可能适合更多场景。
  • 示例怎么通过回调函数实现,而不是通过waitForResult()阻塞直到goal完成。

使用回调函数的action客户端

  • 创建文件,actionlib_tutorials/src/fibonacci_callback_client.cpp,参考代码
cd ~/catkin_ws/actionlib_tutorials/src
touch fibonacci_callback_client.cpp
vim fibonacci_callback_client.cpp
  • 代码如下:
#include <ros/ros.h>
#include <actionlib/client/simple_action_client.h>
#include <actionlib_tutorials/FibonacciAction.h>

using namespace actionlib_tutorials;
typedef actionlib::SimpleActionClient<FibonacciAction> Client;

// Called once when the goal completes
void doneCb(const actionlib::SimpleClientGoalState& state,
            const FibonacciResultConstPtr& result)
{
  ROS_INFO("Finished in state [%s]", state.toString().c_str());
  ROS_INFO("Answer: %i", result->sequence.back());
  ros::shutdown();
}

// Called once when the goal becomes active
void activeCb()
{
  ROS_INFO("Goal just went active");
}

// Called every time feedback is received for the goal
void feedbackCb(const FibonacciFeedbackConstPtr& feedback)
{
  ROS_INFO("Got Feedback of length %lu", feedback->sequence.size());
}

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

  // Create the action client
  Client ac("fibonacci", true);

  ROS_INFO("Waiting for action server to start.");
  ac.waitForServer();
  ROS_INFO("Action server started, sending goal.");

  // Send Goal
  FibonacciGoal goal;
  goal.order = 20;
  ac.sendGoal(goal, &doneCb, &activeCb, &feedbackCb);

  ros::spin();
  return 0;
}
  • 上面的注册goal, active, 和feedback回调函数方式来实现不是最方便的。
  • 可以使用boost::bind,参看boost::bind文档

使用类来实现action客户端

  • 创建文件,actionlib_tutorials/src/fibonacci_class_client.cpp,参考代码
cd ~/catkin_ws/actionlib_tutorials/src
touch fibonacci_class_client.cpp
vim fibonacci_class_client.cpp
  • 代码如下:
#include <ros/ros.h>
#include <actionlib/client/simple_action_client.h>
#include <actionlib_tutorials/FibonacciAction.h>

using namespace actionlib_tutorials;
typedef actionlib::SimpleActionClient<FibonacciAction> Client;

class MyNode
{
public:
  MyNode() : ac("fibonacci", true)
  {
    ROS_INFO("Waiting for action server to start.");
    ac.waitForServer();
    ROS_INFO("Action server started, sending goal.");
  }

  void doStuff(int order)
  {
    FibonacciGoal goal;
    goal.order = order;

    // Need boost::bind to pass in the 'this' pointer
    ac.sendGoal(goal,
                boost::bind(&MyNode::doneCb, this, _1, _2),
                Client::SimpleActiveCallback(),
                Client::SimpleFeedbackCallback());

  }

  void doneCb(const actionlib::SimpleClientGoalState& state,
              const FibonacciResultConstPtr& result)
  {
    ROS_INFO("Finished in state [%s]", state.toString().c_str());
    ROS_INFO("Answer: %i", result->sequence.back());
    ros::shutdown();
  }

private:
  Client ac;
};

int main (int argc, char **argv)
{
  ros::init(argc, argv, "test_fibonacci_class_client");
  MyNode my_node;
  my_node.doStuff(10);
  ros::spin();
  return 0;
}
  • 调用sendGoal函数,参数使用boost::bind方法。
  • 我们没有注册active或feeback回调函数,所以我们传递null函数指针。
  • 我们也可以将这两个参数留空,因为默认情况下回调为null。

纠错,疑问,交流: 请进入讨论区点击加入Q群

获取最新文章: 扫一扫右上角的二维码加入“创客智造”公众号


标签: ROS与C++入门教程