action的基本用法,包括客户端与服务端的执行和反馈等。
首先保证ROS已经安装。
1. 创建 catkin 空间
mkdir -p catkin_ws/src
cd catkin_ws
catkin_make
此时如果出错,说明ROS没有正确安装。
2. 创建 package : action_demo
取包名为action_demo,并且创建必要的文件夹。
cd src
catkin_create_pkg action_demo roscpp rospy std_msgs
cd action_demo
mkdir src
mkdir action
3. 编辑 action_demo 内容 使用roscpp
3.1 新建 DoDishes.action
创建 action_demo/action/DoDishes.action
# Define the goal
uint32 dishwasher_id # Specify which dishwasher we want to use
---
# Define the result
uint32 total_dishes_cleaned
---
# Define a feedback message
float32 percent_complete
3.2 修改 CMakeLists.txt
以下是修改部分,可通过取消注释然后修改的方式来做
find_package(catkin REQUIRED COMPONENTS
roscpp
rospy
std_msgs
genmsg actionlib_msgs actionlib #add
)
add_action_files(
DIRECTORY action
FILES DoDishes.action
)
generate_messages(
DEPENDENCIES
std_msgs
actionlib_msgs # add
)
3.3 修改 package.xml
增加如下内容
<build_depend>actionlib</build_depend>
<build_depend>actionlib_msgs</build_depend>
<exec_depend>actionlib</exec_depend>
<exec_depend>actionlib_msgs</exec_depend>
上面是format2的,也可以写成下面的format1的,两种格式都可以
<build_depend>actionlib</build_depend>
<build_depend>actionlib_msgs</build_depend>
<run_depend>actionlib</run_depend>
<run_depend>actionlib_msgs</run_depend>
3.4 返回 catkin_ws 编译
返回工作空间catkin_ws
然后 catkin_make
,看是否能够编译成功,如果报错,先解决错误,再往下走
3.5 新建 dishes_server.cpp
创建 action_demo/src/dishes_server.cpp
#include <ros/ros.h>
#include <actionlib/server/simple_action_server.h>
#include "action_demo/DoDishesAction.h"
typedef actionlib::SimpleActionServer<action_demo::DoDishesAction> Server;
// execute when receive a goal from client
void execute(const action_demo::DoDishesGoalConstPtr& goal, Server* as)
{
ros::Rate rate(1);
action_demo::DoDishesFeedback feedback;
ROS_INFO("Dishwasher %d is working.", goal->dishwasher_id);
// publish feedback
for(int i=1; i<=10; i++) {
feedback.percent_complete = i * 10;
as->publishFeedback(feedback);
rate.sleep();
}
// done. return result
ROS_INFO("Dishwasher %d finish working.", goal->dishwasher_id);
action_demo::DoDishesResult result;
result.total_dishes_cleaned = 10;
as->setSucceeded(result);
}
int main(int argc, char** argv)
{
ros::init(argc, argv, "do_dishes_server");
ros::NodeHandle nh;
// create a server
Server server(nh, "do_dishes", boost::bind(&execute, _1, &server), false);
// start the server
server.start();
ros::spin();
return 0;
}
3.6 新建 dishes_client.cpp
创建 action_demo/src/dishes_client.cpp
#include <ros/ros.h>
#include <actionlib/client/simple_action_client.h>
#include "action_demo/DoDishesAction.h"
typedef actionlib::SimpleActionClient<action_demo::DoDishesAction> Client;
// execute when the goal is done
void doneCb(const actionlib::SimpleClientGoalState& state,
const action_demo::DoDishesResultConstPtr& result)
{
ROS_INFO("Yay! The dishes(%d) are now clean", result->total_dishes_cleaned);
}
// execute when the goal is active
void activeCb()
{
ROS_INFO("Goal just went active");
}
// execute when receiving the feedback from server
void feedbackCb(const action_demo::DoDishesFeedbackConstPtr& feedback)
{
ROS_INFO(" percent_complete : %f ", feedback->percent_complete);
}
int main(int argc, char** argv)
{
ros::init(argc, argv, "do_dishes_client");
// create a client
Client client("do_dishes", true);
// wait for server
ROS_INFO("Waiting for action server to start.");
client.waitForServer();
ROS_INFO("Action server started, sending goal.");
// create goal
action_demo::DoDishesGoal goal;
goal.dishwasher_id = 1;
// send goal to server. set callback
client.sendGoal(goal, &doneCb, &activeCb, &feedbackCb);
client.waitForResult();
ros::Duration(1).sleep();
return 0;
}
3.7 修改 CMakLists.txt
以下内容加载合适位置,注释标识的位置。如果没找到位置,就放到文件末尾。
add_executable(server src/dishes_server.cpp)
add_dependencies(server ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
target_link_libraries(server ${catkin_LIBRARIES})
add_executable(client src/dishes_client.cpp)
add_dependencies(client ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
target_link_libraries(client ${catkin_LIBRARIES})
3.8 编译运行
返回工作空间 catkin_ws
catkin_make
看是否编译成功,如果有错误,要逐个去解决
刷新环境
source ~/catkin_ws/devel/setup.bash
rospack profile
在一个终端开启roscore
:
roscore
在一个终端开启server:
rosrun action_demo server
在一个终端开启client:
rosrun action_demo client
这样之后,就能看到信息输出
网友评论