业务与数据
在Service通讯模型中,我们通常都是Client将数据发送给Server,Server经过业务逻辑处理,将结果返回给client。如下图:

在此处,我们需要特别关注的就是传输过程中的Request和Response,这两个都是数据,一个是请求的数据,一个是响应的数据。从数据的角度来说,数据由业务所产生,但不应该与业务无关,应该与规范相关,其实就是定义规范来限制数据类型,来规范业务间的通讯。
在此,ROS提供的是srv数据来做此操作,如下图:

在数据交互过程中的请求阶段,我们将整个包当成一个srv,包含了request和response,这个阶段交给client端去填充request的数据。
在数据交互过程中的server处理阶段,server拿到client发送的srv包,从中获得request数据,根据业务逻辑来去处理操作数据。
在数据交互过程中的响应阶段,将server操作的结果填充到srv的response,将srv返回。
在这三个阶段中,srv自始至终就是一个数据包,规范了client的数据填充,也规范了server的数据填充。
在ROS中对于Service通讯模式的数据类型,系统提供了一些现成的类型供我们参考和使用。
查询所有的消息类型
rossrv list
可以查询出当前支持的所有消息类型。例如我们用到过的roscpp_tutorials/TwoInts
查询消息类型的数据结构
我们还可以对一个消息的数据结构进行查询。
rossrv show roscpp_tutorials/TwoInts
显示的结果为:
int64 a
int64 b
---
int64 sum
结果显示分为两个部分,中间用---分隔。
上面部分是request的数据规范。
下面部分是response的数据规范。
发散与探讨
我们在前面可以发现,ros系统还是提供了大量的数据类型供我们使用。但是数据类型再多,很有可能也满足不了我的实际业务场景,这个时候,我们就需要定制自己的数据类型了。
在Ros中,如果没有现成的消息类型来描述要去传递的消息时,我们会自定义消息。
我们会新建一个Package来去自定义消息,通常这个Package写任何的业务逻辑,只是用来声明自定义的消息类型,可以只定义一种消息类型,也可以定义多种消息类型,根据业务需求来定。
所以,首先我们单独的创建一个package,我们取名为demo_srvs,一定要要添加roscpp,rospy,rosmsg的依赖。
这个包名取名也是有讲究的,业务名_srvs。
自定义消息流程
1 . 创建srv目录,移除不需要的目录
在pakage目录下新建srv目录,删除掉include和src目录
2. 新建.srv文件
创建的这个NumOption.srv文件就是自定义消息文件,需要去描述消息的格式。
我们可以编辑代码如下
float64 a
float64 b
string option
---
float64 result
这个.srv文件以---分隔为两部分,上面一部分包含a,b,option,下面一部分包含一个result.
在这里,上面部分是request的数据,下面部分是response的数据。
此案例中,我们要去做的就是,发送request,例如,a=3,b=3,option=*,那么server端接收到数据后,做a option b 的操作,即3 * 3,结果放到response中。
这个srv文件遵循一定规范的,每一行表示一种数据。前面是类型,后面是名称。和msg的规范一致
ros不只是提供了int64和string两种基本类型供我们描述,其实还有很多:
| msg类型 | C++对应类型 | Python对应类型 |
|---|---|---|
bool |
uint8_t |
bool |
int8 |
int8_t |
int |
int16 |
int16_t |
int |
int32 |
int32_t |
int |
int64 |
int64_t |
int,long
|
uint8 |
uint8_t |
int |
uint16 |
uint16_t |
int |
uint32 |
uint32_t |
int |
uint64 |
uint64_t |
int,long
|
float32 |
float |
float |
float64 |
float |
float |
string |
std:string |
str,bytes
|
time |
ros:Time |
rospy.Time |
duration |
ros::Duration |
rospy.Duration |
3. 配置package.xml文件
在package.xml种添加如下配置:
<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>
message_generation是消息生成工具,在打包编译时会用到
message_runtime运行时消息处理工具
4. 配置CMakeLists.txt
在find_package添加message_generation,结果如下:
find_package(catkin REQUIRED COMPONENTS
roscpp
rosmsg
rospy
message_generation
)
添加add_message_file,结果如下:
add_service_files(
FILES
NumOption.srv
)
这里的NumOption.srv要和你创建的srv文件名称一致,且必须时在srv目录下,否则编译会出现问题
添加generation_msg,结果如下:
generate_messages(
DEPENDENCIES
std_msgs
)
这个配置的作用是添加生成消息的依赖,默认的时候要添加std_msgs
修改catkin_package,结果如下:
catkin_package(
# INCLUDE_DIRS include
# LIBRARIES demo_msg
# CATKIN_DEPENDS roscpp rosmsg rospy
# DEPENDS system_lib
CATKIN_DEPENDS message_runtime
)
为catkin编译提供了依赖message_runtime
检验自定义消息
1. 编译项目
来到工作空间目录下,运行编译
catkin_make
2. 查看生成的头文件
来到devel的include目录下,如果生成了头文件说明,自定义消息创建成功。
3. 通过rossrv工具校验
rossrv show demo_srvs/NumOption
查看运行结果,运行结果和自己定义的相一致,说明成功。