一般情况下,建议将消息文件msg和服务文件srv制作成一个只包含消息文件的单独的包,而不是将其包含在可执行节点中的目录中.
-
生成功能包
-
catkin_create_pkg ros_tutorials_action message_generation std_msgs actionlib_msgs actionlib roscpp
改写 CMakeLists.txt
add_action_files(FILES Fibonacci.action)
$ roscd ros_tutorials_action → 移动到功能包目录
$ mkdir action → 在功能包中创建一个名为action的动作目录
$ cd action → 移至创建的action目录
$ gedit Fibonacci.action → 创建Fibonacci.action文件并修改内容
-
#goal definition
-
int32 order
-
---
-
#result definition
-
int32[] sequence
-
---
-
#feedback
-
int32[] sequence
动作的5种基本消息
除目标(goal)、结果(result)和反馈(feedback)外,动作还用额外的消息:取消(cancel)和状态(status)
取消(cancel)消息使用actionlib_msgs/GoalID,它在动作运行时可以取消动作客户端和
单独节点上的动作的执行。
状态(status)消息可以根据状态转换(如PENDING、ACTIVE、PREEMPTED和SUCCEEDED 12 )检查当前动作的状态。
修改 CMakeLists.txt
add_executable(action_server src/action_server.cpp)
-
#include <ros/ros.h> // ROS的基本头文件
-
#include <actionlib/server/simple_action_server.h> // 动作库头文件
-
#include <ros_tutorials_action/FibonacciAction.h> // FibonacciAction动作头文件(生成后自动生成)
-
class FibonacciAction
-
{
-
protected:
-
// 声明节点句柄
-
ros::NodeHandle nh_;
-
// 声明动作服务器
-
actionlib::SimpleActionServer<ros_tutorials_action::FibonacciAction> as_;
-
// 用作动作名称
-
std::string action_name_;
-
// 声明用于发布的反馈及结果
-
ros_tutorials_action::FibonacciFeedback feedback_;
-
ros_tutorials_action::FibonacciResult result_;
-
public:
-
// 初始化动作服务器(节点句柄、动作名称、动作后台函数)
-
FibonacciAction(std::string name) :
-
as_(nh_, name, boost::bind(&FibonacciAction::executeCB, this, _1), false),
-
action_name_(name)
-
{
-
as_.start();
-
}
-
~FibonacciAction(void)
{
}
// 接收动作目标(goal)消息并执行指定动作(此处为斐波那契数列)的函数。
void executeCB(const ros_tutorials_action::FibonacciGoalConstPtr &goal)
{
ros::Rate r(1); // 循环周期:1 Hz
bool success = true; // 用作保存动作的成功或失败的变量
// 斐波那契数列的初始化设置,也添加了反馈的第一个(0)和第二个消息(1)
feedback_.sequence.clear();
feedback_.sequence.push_back(0);
feedback_.sequence.push_back(1);
// 将动作名称、目标和斐波那契数列的两个初始值通知给用户
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]);
// 动作细节
for(int i=1; i<=goal->order; i++)
{
// 从动作客户端得知动作取消
if (as_.isPreemptRequested() || !ros::ok())
{
ROS_INFO("%s: Preempted", action_name_.c_str()); // 通知动作取消
as_.setPreempted(); // 取消动作
success = false; // 看作动作失败并保存到变量
break;
}
// 除非有动作取消或已达成动作目标
// 将当前斐波纳契数字加上前一个数字的值保存到反馈值。
feedback_.sequence.push_back(feedback_.sequence[i] + feedback_.sequence[i-1]);
as_.publishFeedback(feedback_); // 发布反馈。
r.sleep(); // 按照上面定义的循环周期调用暂歇函数。
}
// 如果达到动作目标值,则将当前斐波那契数列作为结果值传输。
if(success)
{
result_.sequence = feedback_.sequence;
ROS_INFO("%s: Succeeded", action_name_.c_str());
as_.setSucceeded(result_);
}
}
};
int main(int argc, char** argv) // 节点主函数
{
ros::init(argc, argv, "action_server"); // 初始化节点名称
FibonacciAction fibonacci("ros_tutorial_action"); // 声明Fibonacci (动作名: ros_tutorial_action)
ros::spin(); // 等待动作目标
return 0;
}
#创建动作客户端节点
#添加 CMakeLists.txt
add_executable(action_client src/action_client.cpp)
-
#include <ros/ros.h> // ROS的基本头文件
-
#include <actionlib/client/simple_action_client.h> // 动作库头文件
-
#include <actionlib/client/terminal_state.h> // 动作目标状态头文件
-
#include <ros_tutorials_action/FibonacciAction.h> // FibonacciAction动作头文件(构建后自动生成)
-
int main (int argc, char **argv) // 节点主函数
-
{
-
ros::init(argc, argv, "action_client"); // 初始化节点名称
-
// 声明动作客户端(动作名称:ros_tutorial_action)
-
actionlib::SimpleActionClient<ros_tutorials_action::FibonacciAction> ac("ros_tutorial_action",true);
-
ROS_INFO("Waiting for action server to start.");
-
ac.waitForServer(); // 等待动作服务器启动
-
ROS_INFO("Action server started, sending goal.");
-
ros_tutorials_action::FibonacciGoal goal; // 声明动作目标
-
goal.order = 20; // 指定动作目标(进行20次斐波那契运算)
-
ac.sendGoal(goal); // 发送动作目标
-
// 设置动作完成时间限制(这里设置为30秒)
-
bool finished_before_timeout = ac.waitForResult(ros::Duration(30.0));
-
// 在动作完成时限内收到动作结果值时
-
if (finished_before_timeout)
-
{
-
// 获取动作目标状态值并将其显示在屏幕上
-
actionlib::SimpleClientGoalState state = ac.getState();
-
ROS_INFO("Action finished: %s",state.toString().c_str());
-
}
-
else
-
ROS_INFO("Action did not finish before the time out."); // 超过了动作完成时限的情况
-
//exit
-
return 0;
-
}
#cd ~/catkin_ws && catkin_make → 转到catkin目录并运行catkin构建
#运行
roscore
rosrun ros_tutorials_action action_server
rosrun ros_tutorials_action action_client
阅读(1450) | 评论(0) | 转发(0) |