ROS(七)之动作编程:action文件

文章目录

  • 一、动作编程概念
  • 二、自定义action文件
    • 1.定义action文件
    • 2.依赖
  • 三、动作编程
    • 1.DoDishes_server.cpp
    • 2.DoDisher_client.cpp
    • 3.修改CMakeLists.txt
    • 4.运行


一、动作编程概念

动作(action):

  • 一种问答通信机制
  • 带有连续反馈
  • 可以在任务过程中中止运行
  • 基于ROS的消息机制实现

ROS(七)之动作编程:action文件_第1张图片

Action的接口

  • goal:发布任务目标
  • cancel:请求取消任务
  • status:通知客户端当前服务器的状态
  • feedback:周期反馈任务运行的监控数据
  • result:向客户端发送任务的执行结果,只发布一次
    ROS(七)之动作编程:action文件_第2张图片

二、自定义action文件

1.定义action文件

这个文件存储在功能包my_package下新建的一个action文件夹。

mkdir -p ~/catkin_ws/src/my_package/action

创建DoDishes.action文件

gedit ~/catkin_ws/src/my_package/action/DoDishes.action
# Define the goal
uint32 dishwasher_id		# specify which dishwasher we want to use
---
# Define the result
uint32 toatl_disher_cleaned
---
# Define a feedback message
float32 percent_complete

2.依赖

ROS(七)之动作编程:action文件_第3张图片
动作编程要用到自定义的动作数据结构,所以我们

  • 添加build的依赖actionlibactionlib_msgs和exec的依赖actionlibactionlib_msgs
    (话题编程messages和服务编程serviecs都是消息message,依赖build的message_generation和exec的message_runtime
    (动作编程actions是动作action,依赖build和exec都是actionlibactionlib_msgs
  • 添加我们的actions文件DoDishes.action
  • 添加动作编程actions使用的消息类型actionlib_msgs
    消息类型(messages(对应std_msgs)/services(对应std_msgs)/actions(对应actionlib_msgs))

则对应CMakeLists.txt新增修改内容:

  • find_package:添加build的依赖,即找到catkin包中需要的组件。
    除了那三项( roscpp、rospy和std_msgs)后,还要有actionlibactionlib_msgs

  • add_action_files:Generate services in the ‘srv’ folder(添加在’srv’ 文件夹中的消息文件。)
    添加我们自定义文件的DoDishes.actionFILES

  • generate_messages:Generate added messages and services with any dependencies listed here(使用此处添加的任何依赖项来生成添加了的消息和服务)
    添加消息类型actionlib_msgsDEPENDENCIES

  • catkin_package:添加exec执行的依赖CATKIN_DEPENDS
    除了添加那三项( roscpp、rospy和std_msgs)后,还要有actionlibactionlib_msgs

三、动作编程

1.DoDishes_server.cpp

#include 
#include 
#include "my_package/DoDishesAction.h"

typedef actionlib::SimpleActionServer<my_package::DoDishesAction> Server;

// 收到action的goal后调用该回调函数
void execute(const my_package::DoDishesGoalConstPtr & goal, Server * as)
{
     
	ros::Rate rate(1);
	my_package::DoDishesFeedback feedback;
	
	ROS_INFO("Dishwasher %d is working.", goal->dishwasher_id);
	
	// 假设洗盘子的进度,并且按照1Hz的频率发布进度feedback
	for(int i = 1 ; i <= 10 ; i++)
	{
     
		feedback.percent_complete = i * 10;
		as->publishFeedback(feedback);
		rate.sleep();
	}
	
	// 当action完成后,向客户端返回结果
	ROS_INFO("Dishwasher %d finish working.", goal->dishwasher_id);
	as->setSucceeded();
}

int main(int argc , char ** argv)
{
     
	ros::init(argc, argv, "do_dishes_server");
	ros::NodeHandle nodeHandle;
	
	
	// 定义一个服务器
	Server server(nodeHandle, "do_dishes", boost::bind(&execute, _1, &server), false);
	
	// 服务器开始运行
	server.start();
	
	ros::spin();
	
	return 0;
}

2.DoDisher_client.cpp

#include 
#include "my_package/DoDishesAction.h"

typedef actionlib::SimpleActionClient<my_package::DoDishesAction> Client;

// 当action完成后会调用该回调函数一次
void doneCallback(const actionlib::SimpleClientGoalState & state,
	const my_package::DoDishesResultConstPtr & result)
{
     
	ROS_INFO("The dishes are now clean");
	ros::shutdown();
}

// 当action激活后会调用该回调函数一次
void activeCallback()
{
     
	ROS_INFO("Goal just went active");
}

// 收到feedback后调用该回调函数
void feedbackCallback(const my_package::DoDishesFeedbackConstPtr & feedback)
{
     
	ROS_INFO("percent_complete: [%f]", feedback->percent_complete);
}

int main(int argc, char ** argv)
{
     
	ros::init(argc, argv, "do_dishes_client");
	
	// 定义一个客户端
	Client client("do_dishes", true);
	
	// 等待服务器端
	ROS_INFO("waiting for action server to start.");
	client.waitForServer();
	ROS_INFO("Action server started, sending goal.");
	
	//创建一个action的goal
	my_package::DoDishesGoal goal;
	goal.dishwasher_id = 1;
	
	// 发送aciton的goal给服务器端
	client.sendGoal(goal, &doneCallback, &activeCallback, &feedbackCallback);
	
	ros::spin();
	
	return 0;
}

3.修改CMakeLists.txt

# project name
project(my_package)

# using C++11
set(CMAKE_CXX_FLAGS "${CAMKE_CXX_FLAGS} -std=c++11 ")

# cmake version
cmake_minimum_required(VERSION 2.8.3)

# find catkin package需要的组件
find_package(catkin REQUIRED COMPONENTS
  roscpp
  rospy
  std_msgs
  actionlib_msgs 
  actionlib
)

# 添加动作文件
add_action_files(FILES DoDishes.action)

# 生成添加了的消息和服务
generate_messages(DEPENDENCIES actionlib_msgs)

# 添加exec执行的依赖
catkin_package(
  CATKIN_DEPENDS roscpp rospy std_msgs actionlib_msgs actionlib
)

# link headers
include_directories(
  ${catkin_INCLUDE_DIRS}
)

# 生成可执行文件
add_executable(DoDishes_client src/DoDishes_client.cpp)
add_executable(DoDishes_server src/DoDishes_server.cpp)

# after ADD_EXECUTABLE,为生成文件target添加库
target_link_libraries( DoDishes_client ${catkin_LIBRARIES})
target_link_libraries( DoDishes_server ${catkin_LIBRARIES})

4.运行

catkin_make
roscore
rosrun my_package DoDishes_client
rosrun my_package DoDishes_server

你可能感兴趣的:(ROS)