准备好的空的工作空间
.
├── build
├── devel
└── src
├── beginner_tutorials
│ ├── include
│ ├── src
│ ├── package.xml
│ └── CMakeLists.txt
└── CMakeLists.txt -> /opt/ros/melodic/share/catkin/cmake/toplevel.cmake
#如果你运行了catkin_make,那么build和devel内将会生存许多文件,此处我隐藏了
#此处的beginner_tutorials即为ros包,其下文件在你建立时就自动生成了
$ catkin_create_pkg beginner_tutorials std_msgs rospy roscpp
#重点在于此处
beginner_tutorials
├── include
├── src
├── package.xml
└── CMakeLists.txt
或者我们一样懒,继续使用上次的工作空间,那么你的工作空间如下:
.
├── build
├── devel
│ ├── cmake.lock
│ ├── env.sh
│ ├── lib
│ │ ├── beginner_tutorials
│ │ │ ├── listener
│ │ │ └── talker
│ │ └── pkgconfig
│ │ └── beginner_tutorials.pc
│ ├── local_setup.bash
│ ├── local_setup.sh
│ ├── local_setup.zsh
│ ├── setup.bash
│ ├── setup.sh
│ ├── _setup_util.py
│ ├── setup.zsh
│ └── share
└── src
├── beginner_tutorials
│ ├── CMakeLists.txt
│ ├── include
│ ├── package.xml
│ └── src
│ ├── listener.cpp
│ ├── listener.py
│ ├── talker.cpp
│ └── talker.py
└── CMakeLists.txt -> /opt/ros/melodic/share/catkin/cmake/toplevel.cmake
#build和devel内有很多文件,此处我隐藏了,可以看到~/catkin_ws/devel/lib/下
#有talker.cpp和listener.cpp编译生成的可执行文件talker和listener
#重点在于此处
beginner_tutorials
├── CMakeLists.txt
├── include
├── package.xml
└── src
├── listener.cpp
├── listener.py
├── talker.cpp
└── talker.py
说明
1、全文代码来自:http://wiki.ros.org/cn/ROS/Tutorials
2、先跑成功代码,再理解代码
3、可以使用类似vscode的ide开发,文件目录看起来将会清晰很多
4、版本ubuntu18.04.1+ROS Melodic
srv创建和直接使用(回顾)
1、在~/catkin_ws/src/beginner_tutorials/下:
2、创建文件夹 $ mkdir srv
写入以下代码:
int64 a
int64 b
---
int64 sum
3、修改CMakeLists.txt(使用notepadqq打开并调整语言为cmake方便查看)
- 在find_packag函数添加message_generation #利用find_packag函数,增加对message_generation的依赖
第10行左右
## 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
message_generation
)
- 找到add_service_files()代码块,去掉注释符号#,用你的AddTwoInts.srv文件替代: #设置运行依赖
第58行左右
## Generate services in the 'srv' folder
add_service_files(
FILES
AddTwoInts.srv
)
-找到generate_messages()代码块,去掉注释符号#
第72行
## Generate added messages and services with any dependencies listed here
generate_messages(
DEPENDENCIES
std_msgs
)
4、在~/catkin_ws/下:$ catkin_make #重新编译
5、测试运行:$ rossrv show AddTwoInts
返回如下:
[beginner_tutorials/AddTwoInts]:
int64 a
int64 b
---
int64 sum
[rospy_tutorials/AddTwoInts]:
int64 a
int64 b
---
int64 sum
cpp版
1、在~/catkin_ws/src/beginner_tutorials/src/下新建文件add_two_ints_server.cpp
2、写入:
#include "ros/ros.h"
#include "beginner_tutorials/AddTwoInts.h"
bool add(beginner_tutorials::AddTwoInts::Request &req,
beginner_tutorials::AddTwoInts::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;
}
3、在~/catkin_ws/src/beginner_tutorials/src/下新建文件add_two_ints_client.cpp
4、写入:
#include "ros/ros.h"
#include "beginner_tutorials/AddTwoInts.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<beginner_tutorials::AddTwoInts>("add_two_ints");
beginner_tutorials::AddTwoInts 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;
}
5、修改CMakeLists.txt(使用notepadqq打开并调整语言为cmake方便查看)
文件位于~/catkin_ws/src/beginner_tutorials/CMakeLists.txt
在末尾添加:
add_executable(add_two_ints_server src/add_two_ints_server.cpp)
target_link_libraries(add_two_ints_server ${catkin_LIBRARIES})
add_dependencies(add_two_ints_server beginner_tutorials_gencpp)
add_executable(add_two_ints_client src/add_two_ints_client.cpp)
target_link_libraries(add_two_ints_client ${catkin_LIBRARIES})
add_dependencies(add_two_ints_client beginner_tutorials_gencpp)
这段代码将生成两个可执行程序"add_two_ints_server"和"add_two_ints_client",这两个可执行程序在~/catkin_ws/devel/lib/share/
6、在~/catkin_ws/下:$ catkin_make #重新编译
7、测试运行:
运行Service:$ rosrun beginner_tutorials add_two_ints_server (C++)
返回:
[ INFO] [1581872530.283991094]: Ready to add two ints.
运行Client:$ rosrun beginner_tutorials add_two_ints_client 1 3 (C++)
server端返回:
[ INFO] [1581872601.141071562]: Sum: 4
client端返回:
request: x=1, y=3
sending back response: [4]
python版
可以把程序放在一起问题不大,我还是放在src下
- Writing a Service Node
1、在~/catkin_ws/src/beginner_tutorials/src/下新建文件add_two_ints_server.py
2、
修改权限为可执行:$ chmod +x add_two_ints_server.py
写入:
#!/usr/bin/env python
from beginner_tutorials.srv import AddTwoInts,AddTwoIntsResponse
import rospy
def handle_add_two_ints(req):
print "Returning [%s + %s = %s]"%(req.a, req.b, (req.a + req.b))
return AddTwoIntsResponse(req.a + req.b)
def add_two_ints_server():
rospy.init_node('add_two_ints_server')
s = rospy.Service('add_two_ints', AddTwoInts, handle_add_two_ints)
print "Ready to add two ints."
rospy.spin()
if __name__ == "__main__":
add_two_ints_server()
- Writing the Client Node
3、在~/catkin_ws/src/beginner_tutorials/src/下新建文件add_two_ints_client.py
4、
修改权限为可执行:$ chmod +x add_two_ints_client.py
写入:
#!/usr/bin/env python
import sys
import rospy
from beginner_tutorials.srv import *
def add_two_ints_client(x, y):
rospy.wait_for_service('add_two_ints')
try:
add_two_ints = rospy.ServiceProxy('add_two_ints', AddTwoInts)
resp1 = add_two_ints(x, y)
return resp1.sum
except rospy.ServiceException, e:
print "Service call failed: %s"%e
def usage():
return "%s [x y]"%sys.argv[0]
if __name__ == "__main__":
if len(sys.argv) == 3:
x = int(sys.argv[1])
y = int(sys.argv[2])
else:
print usage()
sys.exit(1)
print "Requesting %s+%s"%(x, y)
print "%s + %s = %s"%(x, y, add_two_ints_client(x, y))
6、回到~/catkin_ws/下:
$ catkin_make
#python为解释型语言不生成可执行文件,本身的py文件权限改成可执行就行了
7、运行测试
开一个终端:$ roscore
运行Service:$ rosrun beginner_tutorials add_two_ints_server (python)
返回:
Ready to add two ints.
运行Client:rosrun beginner_tutorials add_two_ints_client.py 11646 165646 (python)
server端返回:
Returning [11646 + 165646 = 177292]
client端返回:
Requesting 11646+165646
11646 + 165646 = 177292
ros的服务命令,查看所有操作:$ rosservice -h
命令 | 返回 |
---|---|
$ rosservice list | topic_name列表/话题列表 |
$ rosservice type [sevice_name] | srv_type/服务的数据类型 |
$ rosservice call [service] [args] | 调用 service |
$ rossrv show [srv_type] #查看具体的数据类型
可以键入:$ rosservice type [service_name]|rossrv show #直接查看具体的数据类型