在学习古月居的教程中,提到,不同于消息通信,服务通信过程中服务的数据类型需要自己定义。节点并不提供标准服务类型。服务类型的定义文件一般是:*.srv为扩展名,且一般都放在功能包下的srv文件夹目录。ros中的服务数据可以通过srv文件进行语言无关的接口定义。一般写在功能包的srv目录。目的是client输入两个数,server返回这两个数相加的结果,下面是实践:
本地环境: ubuntu16.04 + ROS kinetic
1.在一个catkin_ws/src 下,创建一个pkg:catkin_create_pkg learning_communication roscpp rospy
依赖会被默认写到功能包的CMakeLists.txt和package.xml中
2.创建自定义服务数据结构在learning_communication/srv 下创建 AddTwoInts.srv文件,文件内容:
1 | int64 a |
中间用’—‘隔开,上面的client的数据结构,下面是 server的数据结构
注:定义好服务数据结构后,要想让服务类型在c++,python中使用,必须要做相应的编译与运行配置。
编译依赖message_generation
运行依赖message_runtime
本文为了方便演示,只说在vscode等下,找不到自定义数据结构的情况,所以server, client的源代码只包含头文件进行测试。
server.cpp的内容:
1 | #include<ros/ros.h> |
client.cpp的内容:
1 | #include<ros/ros.h> |
接着打开package.xml (这里,这里打开的是包learning_communication下的package.xml, 后面的CMakeLists.txt也是, catkin_ws工作空间下的CMakeLists.txt是锁死了的,无法进行更改)
在
1 | <build_depend>message_generation</build_depend> |
根据上文所说,这里添加这两个编译与运行依赖
这里:原书下面写的是run_depend,经过测试,无法运行,会报错
这里添加的这两行目前还不清楚是什么意思,但是,发现,如果不自定义的话,package.xml这个文件是不需要进行修改的,只要在create_pkg 把需要添加的依赖全部添加到,这个xml会自动进行生成的.
接着打开CMakeLists.txt
在一开始的find_package那里的末尾添加为这样
1 | find_package(catkin REQUIRED COMPONENTS |
在find_package的下面添加
1 | add_service_files(FILES AddTwoInts.srv) |
再在末尾添加:
1 | add_executable(server src/server.cpp) |
上述做完了,检验自定义的数据结构是否被识别rossrv show learning_communication/AddTwoInts
若正常显示我们定义的结果就说明成功
以上就是c++ 在linux下的标准编译链接过程
add_executable(server src/server.cpp) //这个意思是用于设置需要编译的代码和生成的可执行文件(cpp),第一个参数是希望生成的可执行文件名称,后面的是需要编译的文件路径
add_dependencies(server ${PROJECT_NAME}_gencpp) //用于设置依赖,我们在许多应用中,需要定义与语言无关的消息类型,消息类型会在编译过程中产生相应语言的代码,生成python就是_genpy
target_link_libraries(server ${catkin_LIBRARIES}) //用于设置链接库,有时候需要第三方的库函数。 第一个跟上面一样,是可执行文件的名字。 第二个是需要链接的库,这里不需要第三方库,使用默认链接库即可。
这样弄了后, catkin_make
就会成功,接着打开vscode, 就不会提示找不到文件了.
以下是完整代码
server.cpp
1 |
|
client.cpp
1 | #include <cstdlib> |
一个node可以发布,接收多个消息,服务。所以对于client来说,请求的是服务名,而不是服务节点的名字。所以这里ros::ServiceClient client = n.serviceClient<learning_communication::AddTwoInts>("add_two_ints");
是创建一个client对象,用来向名字叫add_two_ints的服务发起请求。
注: 在client.cpp 中的> if (argc != 3)
在c系列语言中 argc 是输入的参数个数, argv是字串串指针
如果这样输入: rosrun learning_communication client 3 5
那么argc=3
第一个参数是 ***/catkin_ws/devel/lib/learning_communication/client
第二个参数是 3
第三个参数是5
要想打印的话可以使用:printf("%s",argv[1])
补充:linux 下c++的atoi, atol, atoll, atof
atoi 将字符串转化为int类型变量
atol 将字符串转换为long类型变量
atoll 将字符串转化为long long 类型变量
atof 将字符串转化为double类型变量
详细使用见: linux下上述的调用示例
运行前需要先:
cd catkin_ws
source devel/setup.bash
运行结果,server会一直等待,client执行一次就会终止
大致流程图
- 本文作者: 蓉城蒲菊
- 本文链接: https://github.com/liangpu597/2020/07/14/自己写srv文件vscode提示找不到文件/
- 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!