From be1eba255bfe271d5d49a8e65872608b9eccc877 Mon Sep 17 00:00:00 2001 From: LiuJR Date: Wed, 18 Sep 2024 01:20:37 +0800 Subject: [PATCH] =?UTF-8?q?ROS1=20Action=20=E9=80=9A=E4=BF=A1=E6=A1=88?= =?UTF-8?q?=E4=BE=8B=EF=BC=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/action_test/CMakeLists.txt | 245 +++++++++++++++++++ src/action_test/README.md | 4 + src/action_test/action/Laundry.action | 8 + src/action_test/include/action_test/.gitkeep | 0 src/action_test/package.xml | 76 ++++++ src/action_test/src/action_client.cpp | 73 ++++++ src/action_test/src/action_server.cpp | 64 +++++ src/ros_action/CMakeLists.txt | 238 ++++++++++++++++++ src/ros_action/README.md | 4 + src/ros_action/action/heatWater.action | 9 + src/ros_action/include/ros_action/.gitkeep | 0 src/ros_action/package.xml | 76 ++++++ src/ros_action/src/heatWaterClient.cpp | 37 +++ src/ros_action/src/heatWaterServer.cpp | 55 +++++ 14 files changed, 889 insertions(+) create mode 100644 src/action_test/CMakeLists.txt create mode 100644 src/action_test/README.md create mode 100644 src/action_test/action/Laundry.action create mode 100644 src/action_test/include/action_test/.gitkeep create mode 100644 src/action_test/package.xml create mode 100644 src/action_test/src/action_client.cpp create mode 100644 src/action_test/src/action_server.cpp create mode 100644 src/ros_action/CMakeLists.txt create mode 100644 src/ros_action/README.md create mode 100644 src/ros_action/action/heatWater.action create mode 100644 src/ros_action/include/ros_action/.gitkeep create mode 100644 src/ros_action/package.xml create mode 100644 src/ros_action/src/heatWaterClient.cpp create mode 100644 src/ros_action/src/heatWaterServer.cpp diff --git a/src/action_test/CMakeLists.txt b/src/action_test/CMakeLists.txt new file mode 100644 index 0000000..698aa80 --- /dev/null +++ b/src/action_test/CMakeLists.txt @@ -0,0 +1,245 @@ +cmake_minimum_required(VERSION 3.0.2) +project(action_test) + +## Compile as C++11, supported in ROS Kinetic and newer +# add_compile_options(-std=c++11) + +## Find catkin macros and libraries +## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz) +## is used, also find other catkin packages +# find_package(catkin REQUIRED COMPONENTS +# roscpp +# rospy +# std_msgs +# ) +find_package(catkin REQUIRED COMPONENTS + roscpp + rospy + std_msgs + actionlib + actionlib_msgs +) + +## System dependencies are found with CMake's conventions +# find_package(Boost REQUIRED COMPONENTS system) + + +## Uncomment this if the package has a setup.py. This macro ensures +## modules and global scripts declared therein get installed +## See http://ros.org/doc/api/catkin/html/user_guide/setup_dot_py.html +# catkin_python_setup() + +################################################ +## Declare ROS messages, services and actions ## +################################################ + +## To declare and build messages, services or actions from within this +## package, follow these steps: +## * Let MSG_DEP_SET be the set of packages whose message types you use in +## your messages/services/actions (e.g. std_msgs, actionlib_msgs, ...). +## * In the file package.xml: +## * add a build_depend tag for "message_generation" +## * add a build_depend and a exec_depend tag for each package in MSG_DEP_SET +## * If MSG_DEP_SET isn't empty the following dependency has been pulled in +## but can be declared for certainty nonetheless: +## * add a exec_depend tag for "message_runtime" +## * In this file (CMakeLists.txt): +## * add "message_generation" and every package in MSG_DEP_SET to +## find_package(catkin REQUIRED COMPONENTS ...) +## * add "message_runtime" and every package in MSG_DEP_SET to +## catkin_package(CATKIN_DEPENDS ...) +## * uncomment the add_*_files sections below as needed +## and list every .msg/.srv/.action file to be processed +## * uncomment the generate_messages entry below +## * add every package in MSG_DEP_SET to generate_messages(DEPENDENCIES ...) + +## Generate messages in the 'msg' folder +# add_message_files( +# FILES +# Message1.msg +# Message2.msg +# ) + +## Generate services in the 'srv' folder +# add_service_files( +# FILES +# Service1.srv +# Service2.srv +# ) + +## Generate actions in the 'action' folder +# add_action_files( +# FILES +# Action1.action +# Action2.action +# ) +# 配置action源文件,FILES将引用当前功能包目录的action目录中的*.action文件,自动生成一个头文件(*.h) +add_action_files( + FILES + Laundry.action +) + +## Generate added messages and services with any dependencies listed here +# generate_messages( +# DEPENDENCIES +# std_msgs +# ) +# 生成消息时依赖于std_msgs、actionlib_msgs +generate_messages( + DEPENDENCIES + std_msgs + actionlib_msgs +) + +################################################ +## Declare ROS dynamic reconfigure parameters ## +################################################ + +## To declare and build dynamic reconfigure parameters within this +## package, follow these steps: +## * In the file package.xml: +## * add a build_depend and a exec_depend tag for "dynamic_reconfigure" +## * In this file (CMakeLists.txt): +## * add "dynamic_reconfigure" to +## find_package(catkin REQUIRED COMPONENTS ...) +## * uncomment the "generate_dynamic_reconfigure_options" section below +## and list every .cfg file to be processed + +## Generate dynamic reconfigure parameters in the 'cfg' folder +# generate_dynamic_reconfigure_options( +# cfg/DynReconf1.cfg +# cfg/DynReconf2.cfg +# ) + +################################### +## catkin specific configuration ## +################################### +## The catkin_package macro generates cmake config files for your package +## Declare things to be passed to dependent projects +## INCLUDE_DIRS: uncomment this if your package contains header files +## LIBRARIES: libraries you create in this project that dependent projects also need +## CATKIN_DEPENDS: catkin_packages dependent projects also need +## DEPENDS: system dependencies of this project that dependent projects also need +# catkin_package( +# # INCLUDE_DIRS include +# # LIBRARIES action_test +# # CATKIN_DEPENDS roscpp rospy std_msgs +# # DEPENDS system_lib +# ) +# 运行时依赖,描述了库、catkin构建依赖项和系统依赖的功能包 +catkin_package( +# INCLUDE_DIRS include +# LIBRARIES action_test + CATKIN_DEPENDS roscpp rospy std_msgs actionlib actionlib_msgs +# DEPENDS system_lib +) + + +########### +## Build ## +########### + +## Specify additional locations of header files +## Your package locations should be listed before other locations +include_directories( +# include + ${catkin_INCLUDE_DIRS} +) + +## Declare a C++ library +# add_library(${PROJECT_NAME} +# src/${PROJECT_NAME}/action_test.cpp +# ) + +## Add cmake target dependencies of the library +## as an example, code may need to be generated before libraries +## either from message generation or dynamic reconfigure +# add_dependencies(${PROJECT_NAME} ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS}) + +## Declare a C++ executable +## With catkin_make all packages are built within a single CMake context +## The recommended prefix ensures that target names across packages don't collide +# add_executable(${PROJECT_NAME}_node src/action_test_node.cpp) +add_executable(action_client src/action_client.cpp) +add_executable(action_server src/action_server.cpp) + +## Rename C++ executable without prefix +## The above recommended prefix causes long target names, the following renames the +## target back to the shorter version for ease of user use +## e.g. "rosrun someones_pkg node" instead of "rosrun someones_pkg someones_pkg_node" +# set_target_properties(${PROJECT_NAME}_node PROPERTIES OUTPUT_NAME node PREFIX "") + +## Add cmake target dependencies of the executable +## same as for the library above +# add_dependencies(${PROJECT_NAME}_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS}) +# 构建库和可执行文件之前,预先生成依赖消息 +add_dependencies(action_client ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS}) +add_dependencies(action_server ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS}) + + +## Specify libraries to link a library or executable target against +# target_link_libraries(${PROJECT_NAME}_node +# ${catkin_LIBRARIES} +# ) +# 节点构建选项,配置目标链接库 +target_link_libraries(action_client + ${catkin_LIBRARIES} +) +target_link_libraries(action_server + ${catkin_LIBRARIES} +) + +############# +## Install ## +############# + +# all install targets should use catkin DESTINATION variables +# See http://ros.org/doc/api/catkin/html/adv_user_guide/variables.html + +## Mark executable scripts (Python etc.) for installation +## in contrast to setup.py, you can choose the destination +# catkin_install_python(PROGRAMS +# scripts/my_python_script +# DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} +# ) + +## Mark executables for installation +## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_executables.html +# install(TARGETS ${PROJECT_NAME}_node +# RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} +# ) + +## Mark libraries for installation +## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_libraries.html +# install(TARGETS ${PROJECT_NAME} +# ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} +# LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} +# RUNTIME DESTINATION ${CATKIN_GLOBAL_BIN_DESTINATION} +# ) + +## Mark cpp header files for installation +# install(DIRECTORY include/${PROJECT_NAME}/ +# DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION} +# FILES_MATCHING PATTERN "*.h" +# PATTERN ".svn" EXCLUDE +# ) + +## Mark other files for installation (e.g. launch and bag files, etc.) +# install(FILES +# # myfile1 +# # myfile2 +# DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION} +# ) + +############# +## Testing ## +############# + +## Add gtest based cpp test target and link libraries +# catkin_add_gtest(${PROJECT_NAME}-test test/test_action_test.cpp) +# if(TARGET ${PROJECT_NAME}-test) +# target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME}) +# endif() + +## Add folders to be run by python nosetests +# catkin_add_nosetests(test) diff --git a/src/action_test/README.md b/src/action_test/README.md new file mode 100644 index 0000000..84b9548 --- /dev/null +++ b/src/action_test/README.md @@ -0,0 +1,4 @@ +# action_test + +ROS1 动作通信示例(洗碗机案例) + diff --git a/src/action_test/action/Laundry.action b/src/action_test/action/Laundry.action new file mode 100644 index 0000000..f4a12ae --- /dev/null +++ b/src/action_test/action/Laundry.action @@ -0,0 +1,8 @@ +# goal,洗衣类型 1:开始快洗;2:开始高温洗;3:开始浸泡洗 +uint8 wash_type +--- +# result,洗涤结果 +string wash_result +--- +# feedback,洗涤的进度 +uint8 wash_percent diff --git a/src/action_test/include/action_test/.gitkeep b/src/action_test/include/action_test/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/src/action_test/package.xml b/src/action_test/package.xml new file mode 100644 index 0000000..8ba51a3 --- /dev/null +++ b/src/action_test/package.xml @@ -0,0 +1,76 @@ + + + action_test + 0.0.0 + The action_test package + + + + + ubuntu + + + + + + TODO + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + catkin + roscpp + rospy + std_msgs + actionlib + actionlib_msgs + + roscpp + rospy + std_msgs + actionlib + actionlib_msgs + + roscpp + rospy + std_msgs + actionlib + actionlib_msgs + + + + + + + + diff --git a/src/action_test/src/action_client.cpp b/src/action_test/src/action_client.cpp new file mode 100644 index 0000000..9328e8c --- /dev/null +++ b/src/action_test/src/action_client.cpp @@ -0,0 +1,73 @@ +#include "ros/ros.h" +#include "actionlib/client/simple_action_client.h" +#include "action_test/LaundryAction.h" + +typedef actionlib::SimpleActionClient ActionClient; + +void doneCb(const actionlib::SimpleClientGoalState &state, const action_test::LaundryResultConstPtr &result) +{ + if (state.state_ == state.SUCCEEDED) + { + ROS_INFO("反馈结果:%s", result->wash_result.c_str()); + } + else + { + ROS_INFO("任务失败!"); + } +} + +void activeCb() +{ + ROS_INFO("动作已经被激活...."); +} + +void feedbackCb(const action_test::LaundryFeedbackConstPtr &feedback) +{ + ROS_INFO("洗涤进度为:%d%s", feedback->wash_percent, "%"); +} + +int main(int argc, char **argv) +{ + // 设置编码 + setlocale(LC_ALL, ""); + int flag = 0; + + // 1.初始化ROS节点 + ros::init(argc, argv, "action_client"); + + // 2.实例化ROS句柄 + ros::NodeHandle nh; + + // 3.实例化action客户端对象 + // 参数2为动作的名称,参数3默认为true,无需再调用ros::spin(),设置为false时需手动调用 + ActionClient client(nh, "laundry", true); + // 等待服务端启动 + client.waitForServer(); + + // 4.定义动作目标数据 + action_test::LaundryGoal goal; + goal.wash_type = 1; + + // 5.发送目标,同时注册回调,处理反馈以及最终结果 + // 参数1是转换为Done时处理的回调函数,参数2为转换为Active时处理的回调函数,参数3为每当收到此目标的反馈时就调用的回调函数 + // client.sendGoal(goal, &doneCb, &activeCb, &feedbackCb); + while (ros::ok()) + { + if (flag == 6) + { + client.sendGoal(goal, &doneCb, &activeCb, &feedbackCb); + } + else if (flag < 6) + { + ROS_INFO("等待中%d...",flag); + } + flag++; + ros::Duration(1).sleep(); + + } + // ros::spinOnce(); + + // ros::spin(); + + return 0; +} diff --git a/src/action_test/src/action_server.cpp b/src/action_test/src/action_server.cpp new file mode 100644 index 0000000..47032d7 --- /dev/null +++ b/src/action_test/src/action_server.cpp @@ -0,0 +1,64 @@ +#include "ros/ros.h" +#include "actionlib/server/simple_action_server.h" +#include "action_test/LaundryAction.h" +#include + +typedef actionlib::SimpleActionServer ActionServer; + +// 4.收到action的goal后调用的回调函数 +void executeCb(const action_test::LaundryGoalConstPtr &goal, ActionServer *server) +{ + // 获取目标值 + uint8_t wash_type = goal->wash_type; + std::string wash_mode; + switch (wash_type) + { + case 1: + wash_mode = "快洗"; + break; + case 2: + wash_mode = "高温洗"; + break; + case 3: + wash_mode = "浸泡洗"; + break; + default: + break; + } + ROS_INFO("目标值为%d,开始%s!", wash_type, wash_mode.c_str()); + + // 响应连续反馈 + action_test::LaundryFeedback feedback; + for (int i = 0; i <= 100; i++) + { + feedback.wash_percent = i; + server->publishFeedback(feedback); + ros::Duration(0.5).sleep(); + } + + // 反馈结果 + action_test::LaundryResult result; + result.wash_result = wash_mode + "完成!"; + server->setSucceeded(result); +} + +int main(int argc, char **argv) +{ + // 设置编码 + setlocale(LC_ALL, ""); + + // 1.初始化ROS节点 + ros::init(argc, argv, "action_server"); + + // 2.实例化ROS句柄 + ros::NodeHandle nh; + + // 3.实例化action服务端对象 + // 参数2为动作服务器名称,参数3为当一个新目标被接收时在一个单独的线程中被调用,参数4为告诉ActionServer是否在它出现时立即开始发布 + ActionServer server(nh, "laundry", boost::bind(&executeCb, _1, &server), false); + server.start(); + + ros::spin(); + + return 0; +} diff --git a/src/ros_action/CMakeLists.txt b/src/ros_action/CMakeLists.txt new file mode 100644 index 0000000..c57424e --- /dev/null +++ b/src/ros_action/CMakeLists.txt @@ -0,0 +1,238 @@ +cmake_minimum_required(VERSION 3.0.2) +project(ros_action) + +## Compile as C++11, supported in ROS Kinetic and newer +# add_compile_options(-std=c++11) + +## Find catkin macros and libraries +## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz) +## is used, also find other catkin packages +# find_package(catkin REQUIRED COMPONENTS +# roscpp +# rospy +# std_msgs +# ) +find_package(catkin REQUIRED COMPONENTS + roscpp + rospy + std_msgs + # message_generation #自定义消息类型依赖 自定义重点 + actionlib_msgs #动作编程重点 + actionlib #动作编程重点 +) + +## System dependencies are found with CMake's conventions +# find_package(Boost REQUIRED COMPONENTS system) + + +## Uncomment this if the package has a setup.py. This macro ensures +## modules and global scripts declared therein get installed +## See http://ros.org/doc/api/catkin/html/user_guide/setup_dot_py.html +# catkin_python_setup() + +################################################ +## Declare ROS messages, services and actions ## +################################################ + +## To declare and build messages, services or actions from within this +## package, follow these steps: +## * Let MSG_DEP_SET be the set of packages whose message types you use in +## your messages/services/actions (e.g. std_msgs, actionlib_msgs, ...). +## * In the file package.xml: +## * add a build_depend tag for "message_generation" +## * add a build_depend and a exec_depend tag for each package in MSG_DEP_SET +## * If MSG_DEP_SET isn't empty the following dependency has been pulled in +## but can be declared for certainty nonetheless: +## * add a exec_depend tag for "message_runtime" +## * In this file (CMakeLists.txt): +## * add "message_generation" and every package in MSG_DEP_SET to +## find_package(catkin REQUIRED COMPONENTS ...) +## * add "message_runtime" and every package in MSG_DEP_SET to +## catkin_package(CATKIN_DEPENDS ...) +## * uncomment the add_*_files sections below as needed +## and list every .msg/.srv/.action file to be processed +## * uncomment the generate_messages entry below +## * add every package in MSG_DEP_SET to generate_messages(DEPENDENCIES ...) + +## Generate messages in the 'msg' folder +# add_message_files( +# FILES +# Message1.msg +# Message2.msg +# ) + +## Generate services in the 'srv' folder +# add_service_files( +# FILES +# Service1.srv +# Service2.srv +# ) + +## Generate actions in the 'action' folder +# add_action_files( +# FILES +# Action1.action +# Action2.action +# ) +add_action_files( + FILES + heatWater.action +) + +## Generate added messages and services with any dependencies listed here +# generate_messages( +# DEPENDENCIES +# std_msgs +# ) +generate_messages( + DEPENDENCIES + std_msgs #自定义重点 + actionlib_msgs #动作重点 +) + +################################################ +## Declare ROS dynamic reconfigure parameters ## +################################################ + +## To declare and build dynamic reconfigure parameters within this +## package, follow these steps: +## * In the file package.xml: +## * add a build_depend and a exec_depend tag for "dynamic_reconfigure" +## * In this file (CMakeLists.txt): +## * add "dynamic_reconfigure" to +## find_package(catkin REQUIRED COMPONENTS ...) +## * uncomment the "generate_dynamic_reconfigure_options" section below +## and list every .cfg file to be processed + +## Generate dynamic reconfigure parameters in the 'cfg' folder +# generate_dynamic_reconfigure_options( +# cfg/DynReconf1.cfg +# cfg/DynReconf2.cfg +# ) + +################################### +## catkin specific configuration ## +################################### +## The catkin_package macro generates cmake config files for your package +## Declare things to be passed to dependent projects +## INCLUDE_DIRS: uncomment this if your package contains header files +## LIBRARIES: libraries you create in this project that dependent projects also need +## CATKIN_DEPENDS: catkin_packages dependent projects also need +## DEPENDS: system dependencies of this project that dependent projects also need +# catkin_package( +# # INCLUDE_DIRS include +# # LIBRARIES ros_action +# # CATKIN_DEPENDS roscpp rospy std_msgs +# # DEPENDS system_lib +# ) +catkin_package( +# INCLUDE_DIRS include +# LIBRARIES ros_action + CATKIN_DEPENDS roscpp std_msgs #自定义重点 +# DEPENDS system_lib +) + +########### +## Build ## +########### + +## Specify additional locations of header files +## Your package locations should be listed before other locations +include_directories( +# include + ${catkin_INCLUDE_DIRS} +) + +## Declare a C++ library +# add_library(${PROJECT_NAME} +# src/${PROJECT_NAME}/ros_action.cpp +# ) + +## Add cmake target dependencies of the library +## as an example, code may need to be generated before libraries +## either from message generation or dynamic reconfigure +# add_dependencies(${PROJECT_NAME} ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS}) + +## Declare a C++ executable +## With catkin_make all packages are built within a single CMake context +## The recommended prefix ensures that target names across packages don't collide +# add_executable(${PROJECT_NAME}_node src/ros_action_node.cpp) +add_executable(heatWaterClient src/heatWaterClient.cpp) +add_executable(heatWaterServer src/heatWaterServer.cpp) + +## Rename C++ executable without prefix +## The above recommended prefix causes long target names, the following renames the +## target back to the shorter version for ease of user use +## e.g. "rosrun someones_pkg node" instead of "rosrun someones_pkg someones_pkg_node" +# set_target_properties(${PROJECT_NAME}_node PROPERTIES OUTPUT_NAME node PREFIX "") + +## Add cmake target dependencies of the executable +## same as for the library above +# add_dependencies(${PROJECT_NAME}_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS}) +# add_dependencies(heatWaterClient ${PROJECT_NAME}_gen_cpp) #包含自定义消息类型 自定义重点 +# add_dependencies(heatWaterServer ${PROJECT_NAME}_gen_cpp) #包含自定义消息类型 自定义重点 +add_dependencies(heatWaterClient ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS}) +add_dependencies(heatWaterServer ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS}) + + +## Specify libraries to link a library or executable target against +# target_link_libraries(${PROJECT_NAME}_node +# ${catkin_LIBRARIES} +# ) +target_link_libraries(heatWaterClient ${catkin_LIBRARIES}) +target_link_libraries(heatWaterServer ${catkin_LIBRARIES}) + +############# +## Install ## +############# + +# all install targets should use catkin DESTINATION variables +# See http://ros.org/doc/api/catkin/html/adv_user_guide/variables.html + +## Mark executable scripts (Python etc.) for installation +## in contrast to setup.py, you can choose the destination +# catkin_install_python(PROGRAMS +# scripts/my_python_script +# DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} +# ) + +## Mark executables for installation +## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_executables.html +# install(TARGETS ${PROJECT_NAME}_node +# RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} +# ) + +## Mark libraries for installation +## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_libraries.html +# install(TARGETS ${PROJECT_NAME} +# ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} +# LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} +# RUNTIME DESTINATION ${CATKIN_GLOBAL_BIN_DESTINATION} +# ) + +## Mark cpp header files for installation +# install(DIRECTORY include/${PROJECT_NAME}/ +# DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION} +# FILES_MATCHING PATTERN "*.h" +# PATTERN ".svn" EXCLUDE +# ) + +## Mark other files for installation (e.g. launch and bag files, etc.) +# install(FILES +# # myfile1 +# # myfile2 +# DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION} +# ) + +############# +## Testing ## +############# + +## Add gtest based cpp test target and link libraries +# catkin_add_gtest(${PROJECT_NAME}-test test/test_ros_action.cpp) +# if(TARGET ${PROJECT_NAME}-test) +# target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME}) +# endif() + +## Add folders to be run by python nosetests +# catkin_add_nosetests(test) diff --git a/src/ros_action/README.md b/src/ros_action/README.md new file mode 100644 index 0000000..685c51d --- /dev/null +++ b/src/ros_action/README.md @@ -0,0 +1,4 @@ +# ros_action + +ROS1 动作通信示例(烧水案例) + diff --git a/src/ros_action/action/heatWater.action b/src/ros_action/action/heatWater.action new file mode 100644 index 0000000..a99375d --- /dev/null +++ b/src/ros_action/action/heatWater.action @@ -0,0 +1,9 @@ +#目标水温 +float32 tempTarget #目标 +--- +#最终水温 +float32 tempFinal #最终结果 +--- +#当前水温 +float32 tempNow #中间过程 + diff --git a/src/ros_action/include/ros_action/.gitkeep b/src/ros_action/include/ros_action/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/src/ros_action/package.xml b/src/ros_action/package.xml new file mode 100644 index 0000000..6e93021 --- /dev/null +++ b/src/ros_action/package.xml @@ -0,0 +1,76 @@ + + + ros_action + 0.0.0 + The ros_action package + + + + + ubuntu + + + + + + TODO + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + catkin + roscpp + rospy + std_msgs + actionlib + actionlib_msgs + + roscpp + rospy + std_msgs + actionlib + actionlib_msgs + + roscpp + rospy + std_msgs + actionlib + actionlib_msgs + + + + + + + + diff --git a/src/ros_action/src/heatWaterClient.cpp b/src/ros_action/src/heatWaterClient.cpp new file mode 100644 index 0000000..80547b3 --- /dev/null +++ b/src/ros_action/src/heatWaterClient.cpp @@ -0,0 +1,37 @@ +#include +#include "ros_action/heatWaterAction.h" +typedef actionlib::SimpleActionClient Client; +int main(int argc, char** argv) +{ + setlocale(LC_ALL, ""); + // ROS节点初始化 + ros::init(argc, argv, "heatWaterClient"); + //定义一个动作的客户端 + Client client("heatWater"); + //等待烧水服务 + ROS_INFO("等待烧水服务..."); + client.waitForServer(); + ROS_INFO("烧水服务已启用..."); + + ros_action::heatWaterGoal goal; + + goal.tempTarget = 100; + + client.sendGoal(goal,[](const actionlib::SimpleClientGoalState& state, + const ros_action::heatWaterResultConstPtr& result)->void{ //done + ROS_INFO("水烧开了,开水温度[%f]",result->tempFinal); + } + , + []()->void{ //activte + ROS_INFO("开始烧水..."); + } + , + [](const ros_action::heatWaterFeedbackConstPtr &feedback)->void{ //feedback + ROS_INFO("当前水温[%f]℃",feedback->tempNow); + } + + ); + ros::spin(); + return 0; +} + diff --git a/src/ros_action/src/heatWaterServer.cpp b/src/ros_action/src/heatWaterServer.cpp new file mode 100644 index 0000000..fd24e78 --- /dev/null +++ b/src/ros_action/src/heatWaterServer.cpp @@ -0,0 +1,55 @@ +#include +#include +#include "ros_action/heatWaterAction.h" + +typedef actionlib::SimpleActionServer Server; + +void execute(const ros_action::heatWaterGoalConstPtr& goal, Server* server) +{ + ros::Rate r(10000); + ros_action::heatWaterFeedback feedback; + ros_action::heatWaterResult result; + + ROS_INFO("目标水温[%f]℃.", goal->tempTarget); + + float TTemp = goal->tempTarget; + float NTemp = 0; + float deltaTemp = 5.5; + + // 假设烧水的温度增长为线性 + + while(1) + { + sleep(1); + NTemp += deltaTemp; + feedback.tempNow = NTemp; + if(NTemp > TTemp) + { + result.tempFinal = NTemp; + break; + } + server->publishFeedback(feedback); + } + + // 当action完成后,向客户端返回结果 + ROS_INFO("水烧开了.."); + server->setSucceeded(result); +} + +int main(int argc, char** argv) +{ + setlocale(LC_ALL, ""); + ros::init(argc, argv, "heatWaterServer"); + ros::NodeHandle n; + + // 定义一个服务器 + Server server(n, "heatWater", boost::bind(&execute, _1, &server), false); + + // 服务器开始运行 + server.start(); + + ros::spin(); + + return 0; +} +