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。
获取最新文章: 扫一扫右上角的二维码加入“创客智造”公众号