立即注册 找回密码

微雪课堂

搜索
微雪课堂 机器人操作系统(ROS) 查看内容

ROS基础系列教程5:常规通讯模式

2020-9-17 14:04| 发布者: waveshare_yf| 查看: 5787| 评论: 0|原作者: waveshare|来自: waveshare

摘要: 这一章的内容我们不讲ROS,讲通讯模式。在之前C++和Python的案例当中,都是有一个订阅节点和发布节点之间进行chatter或者是cmd_vel的消息进行通讯,ROS是一个功能箱,各个节点之间的通讯原理,就是ROS的核心技术点之 ...
  • 这一章的内容我们不讲ROS,讲通讯模式。在之前C++和Python的案例当中,都是有一个订阅节点和发布节点之间进行chatter或者是cmd_vel的消息进行通讯,ROS是一个功能箱,各个节点之间的通讯原理,就是ROS的核心技术点之一。
  • 通讯模式的种类很多,比如我们上位机和下位机之间的串口通讯,有的直接发数据,有的则是Modbus协议等等;再比如我们应用层次的通讯,有B/S、C/S架构,请求应答机制,还有最新的MQTT物联网等等,这些都是通讯。
  • 只要是通讯,那么他们之间必然是存在共性的,这一章的主要讲解的就是“通讯”。

    单片机与单片机之间的通讯

  • 大家既然是和机器人打交道的,那么单片机对于大家来说必然是不可缺少的一个部分。我们可以通过对单片机的编程来控制物理装置,然后我们的机器人动起来。那么单片机和单片机之间、单片机和通讯型传感器之间的通讯原理,必然是需要掌握的。

    串口通讯

  • 大家最经常用到的就是串口通讯,通讯TxD和RxD两条线,两边的波特率相同、数据位相同,即可实现数据的收发。那么什么是串口通讯呢?波特率、数据位又是什么?“软串口通讯”又是什么呢?别急,大家继续看下去。




  • TxD是发送端口,RxD是接收端口。在MCU1向MCU2发送字符‘A’的过程中, MCU1的数据“按位”在TxD发送引脚进行高低电平的一个跳动,而另一个MCU2的RxD处于接收状态,检测高低电平的跳动进行翻译。
  • 在TxD的高低变换和RxD的读取过程当中,跳动频率慢的话,传输数据的时间长,为了保持高速的传输数据,我们将两边的跳动频率在单片机上面设置成相同,这就是波特率。当然,波特率的单位是bps,意味Bit Per Second,位每秒。我们常用的波特率为9600,那么也就是每秒有9600bit的数据到达了接收端,那么9600Bit数据的发送,TxD要跳动多少下 呢?这个问题留给大家来计算。
  • 在串口通讯当中,我们做出如下规定。3.3V以上为高电平1,1.2V以下为地电平0,通讯的数据格式默认是8位数据位、1位停止位、无校验(也就是常说的8N1模式)。

    IIC/TWI通讯

  • IIC通讯大家也是比较熟悉的,我们在ROS里面使用到的陀螺仪模块,基本上都是IIC通 讯。IIC通讯是由一条数据线SDA(Sign Data,数据信号)和一条时钟线(Sign Clock,时钟信号)组成,时钟线跳动提供实践频率,然后数据线的高低变化来传输数据。IIC通讯属于总线型,两条线上面可以挂载多个设备,每个设备都有一个固有的地址,我们通过地址以 及对应的寄存器就可以进行我们想要的操作。如果有同学 用过HX711压力变送模块的话,那么一定对于这样的模式不会陌生!




SPI通讯

  • 相比串口通信和IIC通讯,SPI的通讯方式显得更加的快速。SPI通讯由四条线组成, MOSI(master output slave input,主机输出从机输入,也叫做SDO)、 MISO(master input slave output,主机输入从机输出,也叫做SDI)、SCLK(Sign Clock,也就是SCL,为了区分IIC,我们叫做SCLK)、SS(Sign Select,信号选择)。
  • MOSI和MISO负责传输数据,而SCLK提供一个稳定的时钟。相比于IIC通讯,SPI通讯没有设备地址一说,但是却增加了SS信号选择端。当我们由多个从机设备的时候,我们就 可以将从机的SS引脚接在我们的主机上面,通过控制SS信号选择端的电位高低,从而确定是否使用该从机设备。(我更喜欢叫它使能信号,事实正是如此)




RS232/RS485/CAN总线

  • 这些同样也属于通讯协议,要么是在信号的电压高低不同,要么是通讯的方式及校验。我自身是一名软件开发人员,这一类协议我并没有去深入的学习,而实通过“转”的一个概念来进行开发。
  • 比如RS485通讯,我一般会选择使用MAX485芯片或者模块,直接转为串口通讯来使用。还有CAN总线通讯,这个是我在工作当中用的比较多的,通常情况下我使用 TJA1050,如果由多个CAN总线设备的话,那么再增加一个MCP2512的CAN总线控制器即可转为SPI进行处理。至于RS232那就更多了。软得不够,硬的来凑,这一观念在快速开发产品原型有着巨大的潜能。

    单总线/私有协议

  • 在这里我把单总线和私有协议给放在了一起,在我看来,硬件层次的通讯,其实就是电位信号的高低跳动,只是这个跳动规律必须被双方所须知。我可以定义发送引脚跳动5次位 字符“1”,也可以规定信号引脚按照00110001(0x31,即char类型的1)的规律跳动表 示字符“1”。
  • 同样,我们在串口、IIC等没有,或者接口数量不足的时候,也可以通过控制引脚电位的高低变化,来实现一个模拟通讯,比如我们Arduino的SoftSerial库(软串口)。

    单片机和PC主机之间通讯

  • 单片机和PC主机之间最常用的通讯就是串口通讯,当然在工业级别应用的层次,RS232/485、CAN总线等等,应用也是十分广泛的。在我们的ROS机器人开发当中,下位机和PC主机之间的通讯是串口,通过使用CH340或者CP201X等芯片,进行了一个串口转 USB的方式进行数据传输。
  • 在ROS开发当中,PC主机(上位机)就相当于是大脑,负责数据的分析于处理,而我们的下位机也有很多种,在我看来可以分为具有执行和感知。执行机制负责获得PC主机的指令,通过单片机进行驱动,而感知机制负责甲肮获得数据上传至PC主机,PC主机进行分析。

PC主机之间的通讯

  • ROS的核心之一,就是通讯。多台机器人通讯、机器人自身的节点通讯,这些都属于是软件层次的一个通讯。既然都是通讯,那么他们之间是存在着一定的异同之处,我们可以通过对比学习,更快的掌握ROS通讯机制。
  • 在这里我会重点阐述B/S、C/S架构,socket套接字,请求/应答机制,MQTT这四部分内容,使用Python语言进行讲解(如果用C++,那么这一节的内容我自己都会看懵逼)。

    通讯服务架构B/S和C/S

  • 我们先来谈谈B/S架构,B/S,Browser/Server,浏览者/服务站。这个也是我们在日常生活当中经常用到一个服务架构模式,最常见的就是我们在浏览网站的时候,我们以Browser的身份向Server服务器发起访问,从而看到我们想看到的内容。我们可以同时多人 去访问查看同一个内容,前提是这个Server不会因为访问的人太多而死机。
  • 而C/S架构,Client/Server,客户端/服务端。这是一种“访问”模式,如果把B/S看作参观浏览的话,那么C/S就是Client和Server坐在一起面对面的交谈了。关于B/S和C/S的内容,我会在后面以代码的形式来向大家展现。如果你是一名非计算机专业的学习者,我建议 你去阅读一下《码农翻身》一书,它可以让你更加轻松的理解这些内容,在我们的底部也会提供此书的电子版。但还是希望大家去支持原版,创作不易。

    Socket套接字

  • 这是C/S架构的实现方式,主要是TCP/UDP通讯,在这里我们重点来讲TCP通讯。先贴 一张图。




这个TCP通讯的一个流程图。整体由Client客户端和Server服务端组成。

  • (1)我们的服务端先通过socket实例化出来一个TCP的对象(socket()),由于Client客户端是通过IP和端口号来找寻Server服务端的,所以在Server初始化之后就要绑定一个IP和端口(bind()),紧接着就是让我们的Server处于监听状态(listen()),当有Client想要向Server通讯的时候,Client会发起一个连接请求,如果server的通过了accept(),就可以开始通过read()读取信息,或者通过wrtie()发送信息。通讯结束以后,端口关闭,等待下一 个连接。
import socket#导入socket模块,用于TCP/IP通讯 

serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)#初始化一 个socket模块的对象 

serversocket.bind(('127.0.0.1', 55555))#绑定服务器的IP地址,以及通讯端口
serversocket.listen(5)#设置监听,在这里面的参数(int类型)控制连接当前服务器的 最大设备数量 

while True: 
    # 建立客户端连接

    conn,addr = serversocket.accept() 
    print("连接地址: %s" % str(addr)) 

    rec = conn.recv(1024) 
    print (rec.decode('utf‐8')) 

    msg = input()
    conn.send(msg.encode('utf‐8')) 

connsocket.close()
  • (2)当Server服务端处于等待状态以后,我们的的Client客户端就可以随时来连接。当然,我们的客户端也是需要通过socket来实例化出来一个TCP对象(socket()),然后通过指定的IP地址和端口号发起连接请求(connect()),连接成功以后就可以通过read()读取信息,或者通过write()发送信息。通讯结束以后,端口关闭。
import socket,sys,time

clientsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)#初始化一 个socket模块的对象
clientsocket.connect(('127.0.0.1', 55555))#建立客户端与服务端的连接 56 while True: 7 #发送数据 
ms = input() 
clientsocket.send(ms.encode('utf‐8')) 
#接收数据 
rev = clientsocket.recv(1024)#接收小于1024字节的数据 
easygui.msgbox(msg = rev.decode('utf‐8'))
print(rev.decode('utf‐8')) 
if ms == 'Q!': 
    break 
clientsocket.close()

大家可以来自行体验一下,记得安装socket哦,还有注意Python3和Python2的缩减和 print问题。此代码用python3。

请求/应答机制

  • 刚刚说完了C/S架构的实现,现在我们来聊聊B/S架构。大家在生活当中经常会去是要浏览器,在浏览器位置输入一个网址按下回车,即可达到我们想去的页面。那么这个网址到底是什么呢?我们按下回车的瞬间发生了什么呢?
  • 大家在是要浏览器的时候,经常会碰到因为网络不流畅导致页面一直处在正在加载中。我们在是要浏览器的时候,实际上是一个远程访问服务器的过程,我们向服务发起一个访问请求,后面跟着我们想要访问的内容,当服务器接收到这个请求之后,它会给你反馈一个应答,同时也把你想访问的内容给你回馈回来。我们在输入网址按下回车的同时,就是一组请求提交给服务器。 在这里,我使用Server酱的接口给大家做一个Python的请求/应答机制例程。Server酱官网:http://sc.ftqq.com/3.version




  • 我们在这里注册号之后,绑定微信,我们进入发生消息界面,就可以来发起请求向你的 微信推送消息。

https://sc.ftqq.com/SCU51176Tfa047ea8f37a0eaeffbe3b0750b5b6db5e42b1423ceb e.send?text=主人服务器又挂掉啦~

  • 可以看到,前面是网站地址,然后是你的密钥,最后是你要发送的内容。我们可以复制链接在浏览器试一下。这个时候我们的请求就已经发送出去了。




这个位置看到了{“errno”:0,”errmsg”:”success”,”dataset”:”done”},这个就是应答数据。与此同时,你的微信也会收到如下的一条信息。





  • 也就是说,我们在浏览器输入链接按下回车的过程,我们的请求就已经提交了。服务器在收到这个请求之后,执行了两件事。第一,向你的微信推送了一条信息;第二,向作为请求者的你反馈了发送成功的“标示”,也就是服务器收到了你的请求。我们可以通过解析反馈内容,从而得知请求是否发送成功。
#coding:utf‐8 #定义编码格式为UTF‐8 

import requests #导入网络请求功能包 
import time #导入时间功能包 

#通过时间函数,获得今天是周几 
def week(): 
    localtime = time.localtime(time.time())
    return localtime[6] 

#向Server酱油发起网络请求 
def push(result): 
    title = "WaveShare提示您:注意天气变化保持健康心情\n"

    content = 'text='+title+'desp='+result
    url="https://sc.ftqq.com/SCU51176Tfa047ea8f37a0eaeffbe3b0750b5b6db5e42b 1423cebe.send?%s" % content 
    r = requests.get(url) #发起请求
    r.close() 

#根据周几,选择不同的发送内容 
def SendData(): 
    if week() == 0:
        data = "今天是星期一。\n您的课程有:\n软件工程 曹允斌老师 小多媒体501\njava 语言高级 马泽秀老师 信息机房1\nASP.net 李娇老师 信息机房1\n请注意按时上课,再忙都 不要忘记陪对象哟!" 
    elif week() == 1: 
        data = "今天是星期二。\n您的课程有:\n英语 付玲老师 大多媒体506\nJavaScript 马泽秀老师 信息机房1\n自习课\n请注意按时上课,再忙都不要忘记陪对象哟!" 
    elif week() == 2: 
        data = "今天是星期三。\n您的课程有:\nPython 李秋雨老师 小多媒体102\n创新创 业(双周) 赵海玲老师 大多媒体202\n自习课\n请注意按时上课,再忙都不要忘记陪对象 哟!" 
    elif week() == 3: 
        data = "今天是星期四。\n您的课程有:\nASP.net 李娇老师 小多媒体301\njava语言 高级 马泽秀老师 小多媒体501\n软件工程 曹允斌老师 信息机房1\n请注意按时上课,再忙都 不要忘记陪对象哟!" 
    elif week() == 4: 
        data = "今天是星期五。\n您的课程有:\nJavaScript 马泽秀老师 小多媒体502\n体 育 卢军锋老师 体育场\nPython 李秋雨老师 机房\n请注意按时上课,再忙都不要忘记陪对象 哟!" 
    elif week() == 5: 
        data = "今天是星期六。\n该加班了,再忙都不要忘记陪对象哟!" 
    elif week() == 6: 
        data = "今天是星期日。\n该加班了,再忙都不要忘记陪对象哟!" 

    if(data!='0'): 
        print(data) 
        push(data) #发送数据 
        else:
        print('GET Data Fail') 

if __name__ == '__main__':
    while True: 
        localtime = time.localtime(time.time()) 
        if localtime[3] == 7: #判断当前小时是不是7,也就是早上七点多发到我的微信 
        SendData()

        time.sleep(3600) #延时3600秒,也就是1小时,每小时查询下当前时间是不是早上七 点
  • 这个是我在大学时候做的一个课程表,早上看课表实在是太麻烦了。每天早上七点多自动发个课表到微信,哪怕中间忘了有什么课,一目了然。前提是你得有一台联网的电脑一直在运行着这个程序,没错,就是云服务器!不过我当时使用的是ESP8266开发板, MicroPython编程,除了给我发个课表,还每个三个小时给我发送个天气预报,怎么样,是不是突然发现“懒”才是科技进步的第一动力!

MQTT

  • MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议),是一种基于发布/订阅(publish/subscribe)模式的”轻量级”通讯协议,该协议构建于TCP/IP协 议上。MQTT最大优点在于,可以以极少的代码和有限的带宽,为连接远程设备提供实时可靠的消息服务。作为一种低开销、低带宽占用的即时通讯协议,使其在物联网、小型设备、 移动应用等方面有较广泛的应用。




  • 实现MQTT协议需要客户端和服务器端通讯完成,在通讯过程中,MQTT协议中有三种身份:发布者(Publish)、代理(Broker)(服务器)、订阅者(Subscribe)。其中,消息的发布者和订阅者都是客户端,消息代理是服务器,消息发布者可以同时是订阅者。 MQTT传输的消息分为:主题(Topic)和负载(payload)两部分:
    • (1)Topic,可以理解为消息的类型,订阅者订阅(Subscribe)后,就会收到该主题 的消息内容(payload);
    • (2)payload,可以理解为消息的内容,是指订阅者具体要使用的内容。
  • MQTT在使用的过程当中需要搭建MQTT服务器,有兴趣的小伙伴可以自行查阅资料 (配置MQTT服务器实在是太太太太繁琐了。基础教程自动跳过)。
  • 而MQTT的模式是不是很像我们的ROS呢?发布,订阅,还有节点管理器。关于MQTT的内容,大家可参考菜鸟教程。链接如下。 MQTT菜鸟教程:https://www.runoob.com/w3cnote/mqtt-intro.html
  • 关于常规通讯模式的介绍到这里就结束了,在下一讲当中,我们会针对ROS的话题通讯、服务通讯、动作机制三方面做出学习,可以类比这一节的内容哟!

98

顶一下

刚表态过的朋友 (98 人)

最新评论

微雪官网|产品资料|手机版|小黑屋|微雪课堂. ( 粤ICP备05067009号 )

GMT+8, 2024-4-20 13:25 , Processed in 0.017375 second(s), 16 queries .

返回顶部