ROS教程4 ROS自定义srv类型及使用
創建srv文件
在上一節單獨為自定義的消息和服務的包 test_msgs 里面
創建 srv文件夾
進入創建 testsrv.srv 文件 ,內容為;
(srv文件和msg文件類似,唯一不同的是它包含兩個部分——request和response。兩部分用---分隔:)
int64 A int64 B --- int64 Sum
(1)打開test_msgs 包里的package.xml文件,確保里面存在這兩行且去掉它們的注釋:(上節已做過)
<build_depend>message_generation</build_depend> <run_depend>message_runtime</run_depend>
(2)打開包目錄下的CMakeLists.txt文件,在find_message調用中添加message_generation依賴,讓你可以生成ROS信息。(上節已經做過)
find_package(catkin REQUIRED COMPONENTS roscpp rospy std_msgs message_generation )
(3) 添加srv文件
去掉注釋且修改為:
add_service_files( FILES testsrv.srv )
(4)然后是generate_messages,指定生成消息文件時的依賴項,比如上面嵌套了其他消息類型geometry_msgs,那么必須注明
#generate_messages必須在catkin_package前面 generate_messages( DEPENDENCIES geometry_msgs )
(4)然后是catkin_package設置運行依賴
catkin_package( CATKIN_DEPENDS message_runtime )
編譯
回到test_msgs文件夾下
catkin_make
查看是否成功
rossrv show test_msgs/testsrv
使用自定義的srv (testsrv.srv)
要使用自定義的消息類型必須source自定義消息所在的工作空間,否則rosmsg show test_msgs/testsrv和rostopic echo /test_msg(/test_msg是節點中使用自定義消息類型test_msgs/Test的topic)都會報錯,因為沒有source的情況下自定義消息類型是不可見的,被認為是未定義類型
1 調用自定義srv類型
(1)如果是在test_msgs包內的節點中調用test_msgs/testsrv類型,只需要在.cpp文件中如下調用即可
#include <test_msgs/testsrv.h> test_msgs::testsrv mysrv;
( 2 ) 如果是在其他包調用test_msgs/testsrv類型則還需要修改package.xml和CMakeLists.txt,
比如同樣在工作空間catkin_arduino_ros內有一個名為test1_pub_sub包,在它的src文件夾下,有兩個節點add_two_ints_client和add_two_ints_server,
調用test_msgs包下面的srv文件夾中的自定義的srv類型testsrv.srv,完成一個請求加法的服務。
add_two_ints_client.cpp
#include "ros/ros.h"
#include <test_msgs/testsrv.h>
#include <cstdlib>
int main(int argc, char **argv)
{
ros::init(argc, argv, "add_two_ints_client");
if (argc != 3)
{
ROS_INFO("usage: add_two_ints_client X Y");
return 1;
}
ros::NodeHandle n;
ros::ServiceClient client = n.serviceClient<test_msgs::testsrv>("add_two_ints");
test_msgs::testsrv srv;
srv.request.a = atoll(argv[1]);
srv.request.b = atoll(argv[2]);
if (client.call(srv))
{
ROS_INFO("Sum: %ld", (long int)srv.response.sum);
}
else
{
ROS_ERROR("Failed to call service add_two_ints");
return 1;
}
return 0;
}
add_two_ints_server.cpp
#include "ros/ros.h"
#include <test_msgs/testsrv.h>
bool add(test_msgs::testsrv::Request &req,
test_msgs::testsrv::Response &res)
{
res.sum = req.a + req.b;
ROS_INFO("request: x=%ld, y=%ld", (long int)req.a, (long int)req.b);
ROS_INFO("sending back response: [%ld]", (long int)res.sum);
return true;
}
int main(int argc, char **argv)
{
ros::init(argc, argv, "add_two_ints_server");
ros::NodeHandle n;
ros::ServiceServer service = n.advertiseService("add_two_ints", add);
ROS_INFO("Ready to add two ints.");
ros::spin();
return 0;
}
代碼中添加的關鍵點:
1頭文件調用
#include <test_msgs/testsrv.h>
2 實例化自定義srv
test_msgs::testsrv srv; (根據創建的包名test_msgs和文件名testsrv)
3 srv 分兩部分
請求部分
test_msgs::testsrv::Request &req
req.a
req.a
響應部分
test_msgs::testsrv::Response &res
res.sum
2為編譯添加依賴項
修改調用包test1_pub_sub的編譯文件,來調用包test_msgs里面的自定義服務 testsrv.srv
(1)修改package.xml (創建msg時已經添加)
<build_depend>roscpp</build_depend> <run_depend>roscpp</run_depend> <build_depend>test_msgs</build_depend> <run_depend>test_msgs</run_depend>
(2)修改CMakeLists.txt:
1 find_package中需要聲明查找包含該消息類型的包test_msgs;
find_package(catkin REQUIRED COMPONENTS roscpp rospy std_msgs geometry_msgs // 上節自定義的msg中使用 跟srv沒關系 test_msgs // 使用自定義testsrv.srv 重點調用 # message_generation )
2 add_dependencies要注明該消息的依賴 [包名]_gencpp (test_msgs_gencpp)其他地方和普通節點一樣
add_dependencies(add_two_ints_server test_msgs_gencpp)
add_dependencies(add_two_ints_client test_msgs_gencpp)
如果缺少add_dependencies中對test_msgs_gencpp的依賴聲明,在編譯的時候如果先編譯test包再編譯test_msgs包則會出現如下報錯(ROS工作空間各個軟件包的編譯順序是隨機的),因為頭文件test_msgs/Test.h還未生成
測試
roscore
總結
以上是生活随笔為你收集整理的ROS教程4 ROS自定义srv类型及使用的全部內容,希望文章能夠幫你解決所遇到的問題。