• 8.ROS编程学习:自定义服务数据python调用


    目录

    一、准备工作——vscode配置

    二、服务端实现

    1.创建demo01_server_p.py

    2.添加可执行权限

    3.配置CMakeList.txt(melodic不用配置也行,noetic需要配置)

    4.测试服务端

    三、客户端实现

    1.创建demo01_client_p.py

    2.添加可执行权限+CMakeList.txt配置

    3.测试客户端

    4.客户端优化

    参考:赵虚左课程+古月的ROS机器人开发实践

    一、准备工作——vscode配置

     选择在集成终端中打开,输入:

    pwd

     输出一个路径。

    1. rosmelodic@rosmelodic-virtual-machine:~/catkin_ws/devel/lib/python2.7/dist-packages$ pwd
    2. /home/rosmelodic/catkin_ws/devel/lib/python2.7/dist-packages

    将输出的路径加入.vscode文件夹中的setting.json文件

    1. {
    2. "python.autoComplete.extraPaths": [
    3. "/opt/ros/melodic/lib/python2.7/dist-packages",
    4. "/home/rosmelodic/catkin_ws/devel/lib/python2.7/dist-packages"
    5. ],
    6. "python.analysis.extraPaths": [
    7. "/opt/ros/melodic/lib/python2.7/dist-packages"
    8. ]
    9. }

    这是为了vscode开发时能够找到自定义服务数据类型的库。

    二、服务端实现

    1.创建demo01_server_p.py

     demo01_server_p.py

    1. #! /usr/bin/env python
    2. # -*- coding: UTF-8 -*-
    3. import rospy
    4. from server_client.srv import AddInts,AddIntsRequest,AddIntsResponse
    5. def huidiao(request):
    6. # request = AddIntsRequest()
    7. num11 = request.num1
    8. num22 = request.num2
    9. sum12 = num11 + num22
    10. response = AddIntsResponse()
    11. response.sum = sum12
    12. rospy.loginfo("服务器解析数据:num11 = %d, num22 = %d, 响应结果为:sun12 = %d", num11, num22, sum12)
    13. return response
    14. if __name__ == "__main__":
    15. rospy.init_node("jiafa_server_p")
    16. server = rospy.Service(name="add_ints", service_class=AddInts, handler=huidiao)
    17. rospy.loginfo("服务器已经启动了")
    18. rospy.spin()

    相较于c++实现精简了很多。

    python版本声明,和utf-8编码,不声明编码格式默认ascii码,防止程序中有中文出现报错。

    1. #! /usr/bin/env python
    2. # -*- coding: UTF-8 -*-

     调用rospy库,和之前自定义的服务数据类型库,自定义的服务数据类型库中包含了这三个类。

    1. import rospy
    2. from server_client.srv import AddInts,AddIntsRequest,AddIntsResponse

     /home/rosmelodic/catkin_ws/devel/lib/python2.7/dist-packages/server_client/srv

     

     回调函数部分

    1. def huidiao(request):
    2. # request = AddIntsRequest()
    3. num11 = request.num1
    4. num22 = request.num2
    5. sum12 = num11 + num22
    6. response = AddIntsResponse()
    7. response.sum = sum12
    8. rospy.loginfo("服务器解析数据:num11 = %d, num22 = %d, 响应结果为:sun12 = %d", num11, num22, sum12)
    9. return response
    def huidiao(request):

    回调函数部分,由于request只是个形参,而且没有声明request的数据类型,导致num1没有代码的自动补齐。尝试了加上request = AddIntsRequest(),但是会导致回调函数接受不到请求request的数值,这个方法失败了,只能在没有代码补齐的情况下硬着去编写。而在c++代码中,转入的形参通过指针的方式给了数据类型,自然有了代码补齐,但是python没有指针功能。

    1. num11 = request.num1
    2. num22 = request.num2
    3. sum12 = num11 + num22
    4. response = AddIntsResponse()
    5. response.sum = sum12
    6. rospy.loginfo("服务器解析数据:num11 = %d, num22 = %d, 响应结果为:sun12 = %d", num11, num22, sum12)
    7. return response

    首先解析请求的两个参数,再将两个参数相加,再将得到的结果赋值给应答,此时的request的num1和num2和response的sum实现着存放请求和应答数据的功能,这些数据是可以通过ROS服务通信去操作的,而num11、num22、sum12只是个符合自定义服务数据类型的数。

    1. if __name__ == "__main__":
    2. rospy.init_node("jiafa_server_p")
    3. server = rospy.Service(name="add_ints", service_class=AddInts, handler=huidiao)
    4. rospy.loginfo("服务器已经启动了")
    5. rospy.spin()

    初始化节点,相较于c++不用再初始化句柄操作。

    创建服务端,name为服务名,service_class服务参数的数据类型,handler回调函数。

    设置回头函数,不断循环。

    2.添加可执行权限

    3.配置CMakeList.txt(melodic不用配置也行,noetic需要配置)

    1. catkin_install_python(PROGRAMS
    2. scripts/demo01_server_p.py
    3. DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
    4. )

    melodic不用配置也行,noetic需要配置,在melodic中这个配置也是生效的,如果打错了路径会出现找不到文件。

    4.测试服务端

    roscore
    rosrun server_client demo01_server_p.py 
    1. rosservice call add_ints "num1: 0
    2. num2: 0"

    通过调整num1和num2数值,观察结果:

     

    三、客户端实现

    1.创建demo01_client_p.py

    1. #! /usr/bin/env python
    2. # -*- coding: UTF-8 -*-
    3. import rospy
    4. from server_client.srv import AddInts,AddIntsRequest,AddIntsResponse
    5. if __name__ == "__main__":
    6. rospy.init_node("jiafa_client_p")
    7. client = rospy.ServiceProxy(name="add_ints", service_class=AddInts)
    8. response = client.call(AddIntsRequest(10, 30))
    9. # response = client.call(10, 30)
    10. rospy.loginfo("响应的数据为:%d",response.sum)

     初始化ROS节点→创建客户端(不用回调函数,同时注意服务名称必须相同)→组织请求数据,并发布请求→控制台输出

    2.添加可执行权限+CMakeList.txt配置

    与之前方法相同

    chmod +x *.py
    1. catkin_install_python(PROGRAMS
    2. scripts/demo01_client_p.py
    3. DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
    4. )

    3.测试客户端

    rosrun server_client demo01_server_p.py 
    rosrun server_client demo01_client_p.py

    4.客户端优化

    修改的部分:

    1. import sys
    2. import logging
    3. logging.basicConfig()

    sys为system的库,通过这个能导入argv,与c++不同,此处没有argc,其中argc就为argv数组的长度,用过len(sys.argv)来使用。

    import logging
    logging.basicConfig()此处是一个为了rospy.logerr("提交参数个数有误")能正常输出,如果不加上这个库会报错:

    No handlers could be found for logger "rosout"

    这部分是判断输入参数的长度,其中第一个参数为文件名,第二个和第三个为请求的数值 ,当长度不等于3,返回警告。

    1. if len(sys.argv) != 3:
    2. rospy.logerr("提交参数个数有误")
    3. sys.exit(1)

     这部分注意system返回的输入值为字符串类型,需要强制转换为int类型,才能参与计算。

    1. req = AddIntsRequest()
    2. req.num1 = int(sys.argv[1])
    3. req.num2 = int(sys.argv[2])
    4. response = client.call(req.num1, req.num2)
    5. # response = client.call(AddIntsRequest(10, 30))

    修改后:

    1. #! /usr/bin/env python
    2. # -*- coding: UTF-8 -*-
    3. import rospy
    4. from server_client.srv import AddInts,AddIntsRequest,AddIntsResponse
    5. import sys
    6. import logging
    7. logging.basicConfig()
    8. if __name__ == "__main__":
    9. if len(sys.argv) != 3:
    10. rospy.logerr("提交参数个数有误")
    11. sys.exit(1)
    12. rospy.init_node("jiafa_client_p")
    13. client = rospy.ServiceProxy(name="add_ints", service_class=AddInts)
    14. req = AddIntsRequest()
    15. req.num1 = int(sys.argv[1])
    16. req.num2 = int(sys.argv[2])
    17. response = client.call(req.num1, req.num2)
    18. # response = client.call(AddIntsRequest(10, 30))
    19. rospy.loginfo("响应的数据为:%d",response.sum)

    测试:

    rosrun server_client demo01_server_p.py
    rosrun server_client demo01_client_p.py 10 20

    rosrun server_client demo01_client_p.py 10 20 30

  • 相关阅读:
    php设计模式重构篇
    JavaWeb整合Mybatis更新删除操作后查询返回数据相同的问题解决
    m4a转换成mp3,音频格式轻松转换
    Java基本数据类型
    mathlab 数据维度调换函数permute()
    [Geek Challenge 2022] crypto部分
    【字符串】重新格式化字符串
    1017 A除以B
    RUST持续学习 一点borrow问题的心得记录
    Vue笔记3(计算属性,监视属性,绑定样式)
  • 原文地址:https://blog.csdn.net/wzfafabga/article/details/127396059