ROS2机器人操作系统

文章目录

  • ROS2机器人操作系统
  • 前言
  • 一、ROS通信接口
    • 语言无关
    • 标准接口
  • 二、接口案例
    • 1.服务接口的定义与使用
      • 接口定义
      • 程序调用
    • 2.话题接口的定义与使用
      • 接口定义
      • 接口命令行操作

前言

通信并不是一个人自言自语,而是两个甚至更多个人,你来我往的交流,交流的内容是什么呢?为了让大家都好理解,我们可以给传递的数据定义一个标准的结构,这就是通信接口。

一、ROS通信接口

接口可以让程序之间的依赖降低,便于我们使用别人的代码,也方便别人使用我们的代码,这就是ROS的核心目标,减少重复造轮子。

ROS有三种常用的通信机制,分别是话题、服务、动作,通过每一种通信种定义的接口,各种节点才能有机的联系到一起。

语言无关

为了保证每一个节点可以使用不同语言编程,ROS将这些接口的设计做成了和语言无关的,比如这里看到的int32表示32位的整型数,int64表示64位的整型数,bool表示布尔值,还可以定义数组、结构体,这些定义在编译过程中,会自动生成对应到C++、Python等语言里的数据结构。

话题通信接口的定义使用的是.msg文件,由于是单向传输,只需要描述传输的每一帧数据是什么就行,比如在这个定义里,会传输两个32位的整型数,x、y,我们可以用来传输二维坐标的数值。

服务通信接口的定义使用的是.srv文件,包含请求和应答两部分定义,通过中间的“—”区分,比如之前我们学习的加法求和功能,请求数据是两个64位整型数a和b,应答是求和的结果sum。

动作是另外一种通信机制,用来描述机器人的一个运动过程,使用.action文件定义,比如我们让小海龟转90度,一边转一边周期反馈当前的状态,此时接口的定义分成了三个部分,分别是动作的目标,比如是开始运动,运动的结果,最终旋转的90度是否完成,还有一个周期反馈,比如每隔1s反馈一下当前转到第10度、20度还是30度了,让我们知道运动的进度。

标准接口

大家可能好奇ROS系统到底给我们定义了哪些接口呢?我们可以在ROS安装路径中的share文件夹中找到,涵盖众多标准定义,大家可以打开几个看看。

二、接口案例

1.服务接口的定义与使用


有三个节点,第一个驱动相机发布图像话题,第二个是机器视觉识别节点,封装了一个服务的服务端对象,提供目标识别位置的查询服务,第三个节点在需要目标位置的时候,就可以发送请求,收到位置进行使用了。

接口定义

bool get      # 获取目标位置的指令
---
int32 x       # 目标的X坐标
int32 y       # 目标的Y坐标
用三横线来区分话题里面的请求数据和应答数据

定义中有两个部分,上边是获取目标位置的指令,get为true的话,就表示我们需要一次位置,服务端就会反馈这个x、y坐标了。

完成定义后,还需要在功能包的CMakeLists.txt中配置编译选项,让编译器在编译过程中,根据接口定义,自动生成不同语言的代码:


find_package(rosidl_default_generators REQUIRED)

rosidl_generate_interfaces(${PROJECT_NAME}
“srv/GetObjectPosition.srv”
)

功能包的package.xml文件中也需要添加代码生成的功能依赖:

…c
<build_depend>rosidl_default_generators</build_depend>
<exec_depend>rosidl_default_runtime</exec_depend>
<member_of_group>rosidl_interface_packages</member_of_group>

程序调用

客户端接口调用

import rclpy                                            # ROS2 Python接口库
from rclpy.node   import Node                           # ROS2 节点类
from learning_interface.srv import GetObjectPosition    # 自定义的服务接口class objectClient(Node):def __init__(self, name):super().__init__(name)                          # ROS2节点父类初始化self.client = self.create_client(GetObjectPosition, 'get_target_position')while not self.client.wait_for_service(timeout_sec=1.0):self.get_logger().info('service not available, waiting again...')self.request = GetObjectPosition.Request()def send_request(self):self.request.get = Trueself.future = self.client.call_async(self.request)def main(args=None):rclpy.init(args=args)                             # ROS2 Python接口初始化node = objectClient("service_object_client")      # 创建ROS2节点对象并进行初始化node.send_request()while rclpy.ok():rclpy.spin_once(node)if node.future.done():try:response = node.future.result()except Exception as e:node.get_logger().info('Service call failed %r' % (e,))else:node.get_logger().info('Result of object position:\n x: %d y: %d' %(response.x, response.y))breaknode.destroy_node()                              # 销毁节点对象rclpy.shutdown()                                 # 关闭ROS2 Python接口

服务端接口调用

import rclpy                                           # ROS2 Python接口库
from rclpy.node import Node                            # ROS2 节点类
from sensor_msgs.msg import Image                      # 图像消息类型
import numpy as np                                     # Python数值计算库
from cv_bridge import CvBridge                         # ROS与OpenCV图像转换类
import cv2                                             # Opencv图像处理库
from learning_interface.srv import GetObjectPosition   # 自定义的服务接口lower_red = np.array([0, 90, 128])     # 红色的HSV阈值下限
upper_red = np.array([180, 255, 255])  # 红色的HSV阈值上限class ImageSubscriber(Node):def __init__(self, name):super().__init__(name)                              # ROS2节点父类初始化self.sub = self.create_subscription(Image, 'image_raw', self.listener_callback, 10) # 创建订阅者对象(消息类型、话题名、订阅者回调函数、队列长度)self.cv_bridge = CvBridge()                         # 创建一个图像转换对象,用于OpenCV图像与ROS的图像消息的互相转换self.srv = self.create_service(GetObjectPosition,   # 创建服务器对象(接口类型、服务名、服务器回调函数)'get_target_position',self.object_position_callback)    self.objectX = 0self.objectY = 0                              def object_detect(self, image):hsv_img = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)      # 图像从BGR颜色模型转换为HSV模型mask_red = cv2.inRange(hsv_img, lower_red, upper_red) # 图像二值化contours, hierarchy = cv2.findContours(mask_red, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)   # 图像中轮廓检测for cnt in contours:                                  # 去除一些轮廓面积太小的噪声if cnt.shape[0] < 150:continue(x, y, w, h) = cv2.boundingRect(cnt)              # 得到苹果所在轮廓的左上角xy像素坐标及轮廓范围的宽和高cv2.drawContours(image, [cnt], -1, (0, 255, 0), 2)# 将苹果的轮廓勾勒出来cv2.circle(image, (int(x+w/2), int(y+h/2)), 5,(0, 255, 0), -1)                       # 将苹果的图像中心点画出来self.objectX = int(x+w/2)self.objectY = int(y+h/2)cv2.imshow("object", image)                            # 使用OpenCV显示处理后的图像效果cv2.waitKey(50)def listener_callback(self, data):self.get_logger().info('Receiving video frame')        # 输出日志信息,提示已进入回调函数image = self.cv_bridge.imgmsg_to_cv2(data, 'bgr8')     # 将ROS的图像消息转化成OpenCV图像self.object_detect(image)                              # 苹果检测def object_position_callback(self, request, response):     # 创建回调函数,执行收到请求后对数据的处理if request.get == True:response.x = self.objectX                          # 目标物体的XY坐标response.y = self.objectYself.get_logger().info('Object position\nx: %d y: %d' %(response.x, response.y))   # 输出日志信息,提示已经反馈else:response.x = 0response.y = 0self.get_logger().info('Invalid command')          # 输出日志信息,提示已经反馈return responsedef main(args=None):                                 # ROS2节点主入口main函数rclpy.init(args=args)                            # ROS2 Python接口初始化node = ImageSubscriber("service_object_server")  # 创建ROS2节点对象并进行初始化rclpy.spin(node)                                 # 循环等待ROS2退出node.destroy_node()                              # 销毁节点对象rclpy.shutdown()                                 # 关闭ROS2 Python接口

2.话题接口的定义与使用

话题通信接口的定义也是类似的,继续从之前的机器视觉案例中来衍生,我们想把服务换成话题,周期发布目标识别的位置,不管有没有人需要。

运行效果
现在我们会运行三个节点:

第一个节点,将驱动相机并发布图像话题,此时的话题数据使用的是ROS中标准定义的Image图像消息;
第二个节点,会运行视觉识别功能,识别目标的位置,这个位置我们希望封装成话题消息,发布出去,谁需要使用谁就来订阅;
第三个节点,订阅位置话题,打印到终端中。

$ ros2 run usb_cam usb_cam_node_exe
$ ros2 run learning_topic interface_object_pub
$ ros2 run learning_topic interface_object_sub

接口定义

int32 x      # 表示目标的X坐标
int32 y      # 表示目标的Y坐标

话题消息的内容是一个位置,我们使用x、y坐标值进行描述。

接口命令行操作

ros2 interface list                    # 查看系统接口列表
ros2 interface show <interface_name>   # 查看某个接口的详细定义
ros2 interface package <package_name>  # 查看某个功能包中的接口定义

ROS2——通信接口(十)相关推荐

  1. 【STC32G12K128开发板】——STC32G12K128开发板介绍

    版权声明:本文为博主原创文章,转载请附上原文出处链接. 文章目录 前言 一.STC32G12K128系列单片机介绍 二.STC32G12K128开发板概述 三.STC32G12K128开发板硬件框图 ...

  2. 系统规划与管理备考整理

    @ 一.信息系统综合知识 1.1 信息的定义和属性 1.信息是客观事物状态和运动特征的一种普遍相识,客观世界中大量存在.产生和传递着以这些方式表示出各种各样的信息 (1)信息的定性描述 控制论的创始人 ...

  3. ROS2学习(十二).ROS概念 - RQt工具的使用

    RQt工具的概述和使用 概述 系统设置 Debian安装包 源码编译安装 RQt组件结构 RQt框架优势 扩展阅读 概述 RQt是一个图形用户界面框架,它以插件的形式实现了各种工具和人机界面接口.我们 ...

  4. 单片机小白学步系列(十八) 单片机/计算机系统概述:通信接口与协议

    前面说了信息与数据的概念,这里要说的是与之关系密切的问题--通信. 通信 何为通信?在英文中,通信用Communication表示,这个词也有交流的意思.实际上,通信和交流确实是一样的意思.不过在汉语 ...

  5. 无人驾驶汽车系统入门(三十二)——ROS2概述和实践入门(一)

    ROS可以说是目前机器人相关开源社区最流行的项目之一,它是一个易用且完备的机器人开发框架.生态乃至社区,海量的机器人开源项目(涵盖感知.规划.控制.定位.SLAM和建图.可视化等几乎所有机器人领域)均 ...

  6. ROS2学习笔记(十)-- ROS2 launch启动文件

    简介:接触过ROS1的同学对launch肯定不陌生,在ROS1中,我们常用launch实现node和master同时启动.多节点同时启动配置等功能,ROS2中的launch也是用于多节点启动.配置功能 ...

  7. ROS2——Rviz:三维可视化显示平台(十八)

    ROS2机器人操作系统 文章目录 ROS2机器人操作系统 前言 一.启动rviz 二.使用步骤 1.图像数据可视化 2.相机点云数据可视化 3.雷达点云数据可视化 总结 前言 一句话说明Rviz的功能 ...

  8. ROS2学习(十六).ROS概念 - 构建系统

    关于ROS 2的构建系统 `ament_package`包 **package.xml** **ament package** `ament_cmake`代码库 `ament_lint`代码库 构建工 ...

  9. ROS2学习(十).ROS概念 - 主题的统计

    主题统计 概述 如何计算统计数据 统计数据种类 行为 同ROS 1的比较 支持 参考 概述 ROS 2为任何订阅所接收的消息提供综合统计功能.这允许用户收集订阅统计信息,同时可以更好地描述系统的性能或 ...

  10. 十大机器智能新型芯片:华为抢占一席,Google占比最多

    (图片付费下载自视觉中国) 整理 | 胡巍巍 来源 | CSDN(ID:CSDNnews) 当年,阿基米德爷爷说出"给我一个支点,我就能撬动地球"这句话时,估计没少遭受嘲讽. 然而 ...

最新文章

  1. 【转】 LINUX中IPTABLES和TC对端口的带宽限制 端口限速
  2. FBEC2021暨第六届金陀螺奖颁奖典礼盛大开幕
  3. vmware安装渗透系统 Linux Kail最新版
  4. Salesforce 中获取数据表字段的 picklist 的值
  5. 06Matplotlib数据可视化--6.2散点图
  6. ODOO v10.0 自动生成财务凭证的科目设置
  7. Windows Server 2008R2 Web服务器
  8. kotlin 泛型约束
  9. UGUI的image
  10. 模拟处理机作业调度---短作业优先调度算法
  11. 5.docker 命令
  12. TreeSet与TreeMap
  13. c语言 鼠标指针图标,WIN7系统鼠标图案DIY!自己动手,美不胜收!-win7鼠标指针...
  14. V5Shop网店系统更新 版本V8.30.0606 RC1
  15. 内存映射文件原理探索
  16. 小米8可以刷鸿蒙os,鸿蒙 OS 2.0 来了!小米也能用么?
  17. python学习笔记(6)
  18. Python OpenCV 保存mp4视频
  19. 01 - Python 调用outlook发送邮件
  20. EfficientNet V1 V2总结

热门文章

  1. 网页中插入透明Flash的方法和技巧
  2. 802.11n无线网卡驱动linux,Ubuntu 无线网卡驱动安装教程
  3. 专业的笔记本测试软件,专业软件性能测试
  4. 网页右下角3秒自动弹出悬浮在线客服代码
  5. 三字代码html,【涨知识】原来三字代码是这样来的!四字代码是什么?
  6. java社交框架,java毕业设计_springboot框架的社交平台
  7. 小说网站源码_ptcms精美小说阅读网站源码(带采集规则)
  8. 网吧的监控系统和服务器如何连接,网吧监控系统安装解决方案
  9. 中望3D2022弹簧的设计
  10. 太阳高度角计算题_【难点突破】太阳高度角与正午太阳高度角区别(附例题解析)...