自动跟随机器人教程(六)软件部分 树莓派 声源定位
接下来的部分比较有趣,是本项目提出的机器人和市场上大多数机器人不同的地方。它除了能够通过摄像头图像和超声波数据来做一些自动控制外,还使用了Respeaker的4通道麦克风阵列。使用这个模块的好处是,在摄像头所没有覆盖到的区域,可以通过对人声的测向来获取人员的大致位置。
声源测向的原理在好多地方有所应用,可以把这个模块看作一个简单的被动雷达。虽然目前的算法(互相关)比较简单,但是以后也可以扩展为高级的算法,所有的DSP操作都可以在树莓派上实现,而不是专用的DSP芯片,所以可塑性很强。
测向原理比较简单,基本上就是把4个麦克风中对角两个一组取出来。由于声波到达4个麦克风上的信号波形比较类似,只是幅度和时间上有一些变化。通过计算声波到达这些麦克风上的时间差,再把这个时间差与0度或者180度时所造成的时间差的最大值进行比较,经过一些三角运算就能测出发射源相对这2个麦克风的角度。再把发射源相对另一组2个麦克风的角度综合比较、换算一下,就能得到更为精确的角度。(理论上只有2个麦克风也能在0~180度范围内测向,同样就用这个respeaker 4mic模块就能实现,只是四通道时可以测0~360度的范围,并且精度更高。)
前面说了通过各麦克风上的几个信号之间的时间差可以测出声源位置,那么这个时间差时如何测出的呢?目前使用的是互相关算法,在通信领域无论是模拟信号还是数字信号都会经常用到,把两个信号经过换元和卷积以后就能得到互相关函数,互相关函数值最大时的坐标位置就是延迟大小了,这个计算一般用FFT变换到频域后用乘法代替,然后在做FFT逆变换得到。
上面这个算法可以说是本项目中理论难度最高的部分,可能业余爱好者比较难以理解,不过幸运的是Respeaker已经给出了4通道测向的例程,只需要把例子稍作修改,用测得的角度去控制最终的旋转方向和大小就行了。
另外本人还改掉了原例程中的几个小bug,比如互相关算法里有些时候归一化会有除以0的问题,还有把snowboy的语音识别去掉了,代之以声音强度识别(因为大多数时候语音识别不是很有效,还不如强度识别靠谱)。
树莓派主程序中调用测向算法的代码:
class doa_thread(threading.Thread):def __init__(self):threading.Thread.__init__(self)def run(self):src = Source(rate=16000, channels=4, frames_size=320)ch1 = ChannelPicker(channels=4, pick=1)doa = DOA(rate=16000)src.link(ch1)src.link(doa)src.recursive_start()self.running = Truewhile self.running:try:time.sleep(1)position, amplitute = doa.get_direction()if amplitute > 2000:pixels.wakeup(position)print amplitute,positionif position > 0 and position < 180:pivot_right()time.sleep(position/200)stop()elif position >= 180 and position < 360:pivot_left()position = 360 - positiontime.sleep(position/200)stop()time.sleep(3)else:pixels.speak()except:print sys.exc_info()src.recursive_stop()
测向算法的核心(互相关算法):
"""Estimate time delay using GCC-PHAT
"""import numpy as npdef gcc_phat(sig, refsig, fs=1, max_tau=None, interp=1):'''This function computes the offset between the signal sig and the reference signal refsigusing the Generalized Cross Correlation - Phase Transform (GCC-PHAT)method.'''# make sure the length for the FFT is larger or equal than len(sig) + len(refsig)n = sig.shape[0] + refsig.shape[0]# Generalized Cross Correlation Phase TransformSIG = np.fft.rfft(sig, n=n)REFSIG = np.fft.rfft(refsig, n=n)R = SIG * np.conj(REFSIG)if all(np.abs(R)) == True:cc = np.fft.irfft(R / np.abs(R), n=(interp * n))else:cc = np.fft.irfft(R, n =(interp * n))max_shift = int(interp * n / 2)if max_tau:max_shift = np.minimum(int(interp * fs * max_tau), max_shift)cc = np.concatenate((cc[-max_shift:], cc[:max_shift+1]))# find max cross correlation indexshift = np.argmax(np.abs(cc)) - max_shifttau = shift / float(interp * fs)return tau, ccdef main():refsig = np.linspace(1, 10, 10)for i in range(0, 10):sig = np.concatenate((np.linspace(0, 0, i), refsig, np.linspace(0, 0, 10 - i)))offset, _ = gcc_phat(sig, refsig)print(offset)if __name__ == "__main__":main()
把互相关算法得到的延迟结果转化为角度数据并返回给我主程序的代码:
# -*- coding: utf-8 -*-"""
Time Difference of Arrival for ReSpeaker 4 Mic Array
"""import numpy as np
import collections
from .gcc_phat import gcc_phat
from .element import ElementSOUND_SPEED = 340.0MIC_DISTANCE_4 = 0.081
MAX_TDOA_4 = MIC_DISTANCE_4 / float(SOUND_SPEED)class DOA(Element):def __init__(self, rate=16000, chunks=10):super(DOA, self).__init__()self.queue = collections.deque(maxlen=chunks)self.sample_rate = rateself.pair = [[0, 2], [1, 3]]def put(self, data):self.queue.append(data)super(DOA, self).put(data)def get_direction(self):tau = [0, 0]theta = [0, 0]buf = b''.join(self.queue)buf = np.fromstring(buf, dtype='int16')for i, v in enumerate(self.pair):tau[i], _ = gcc_phat(buf[v[0]::4], buf[v[1]::4], fs=self.sample_rate, max_tau=MAX_TDOA_4, interp=1)theta[i] = np.arcsin(tau[i] / MAX_TDOA_4) * 180 / np.piif np.abs(theta[0]) < np.abs(theta[1]):if theta[1] > 0:best_guess = (theta[0] + 360) % 360else:best_guess = (180 - theta[0])else:if theta[0] < 0:best_guess = (theta[1] + 360) % 360else:best_guess = (180 - theta[1])best_guess = (best_guess + 270) % 360best_guess = (-best_guess + 120) % 360return best_guess
自动跟随机器人教程(六)软件部分 树莓派 声源定位相关推荐
- 自动跟随机器人教程(五)软件部分 树莓派+电脑 摄像头图像回传
既然你熟悉了Socket编程,也可以另外再写一个类似的简易服务器客户端程序.树莓派仍然作为服务器,电脑仍然作为客户端.只不过现在是树莓派发送,电脑接收.这时的数据不再是控制指令,而是树莓派USB摄像头 ...
- 自动跟随机器人教程(四)软件部分 树莓派+电脑 控制小车移动
接下来可以说是本教程的核心内容了,不可能在一篇文章中讲完,首先讲一个比较初级的程序.树莓派可以接收同一个局域网上电脑的连接,并且电脑键盘上发出的前后左右的控制信号通过网络发向树莓派后,树莓派再经过串口 ...
- 自动跟随机器人:一种简易的自动跟随方案,自动跟随小车、自动跟随平衡小车、STM32、基于超声波的自动跟随小车
目的:一种廉价的跟随方案,让大家都能够参与进来,技术难度不大,一些人也能够DIY一些属于自己的"跟随"机器人!并不是要做工业应用什么的.只是做出来玩玩~ / 1 / 介绍 先看视频 ...
- 树莓派自动跟随机器人
YetiBorg v2 - 示例 - 跟我来 由ModMyPi LTD 在Build,YetiBorg撰写 - 建 于2017年10月25日. 与你的YetiBorg v2一起追逐 机器人可以制作非常 ...
- 【论文】ROS系统的无人小车自动跟随方案研究
这个专栏是专注于入了职场之后,对写论文能力要求和技巧经验的一些总结. 在职场不同于在学习等科研院所,更多要求的是发出论文,而不是发高水平论文. 文章列表: [程序员读论文]为什么要读论文? [程序员读 ...
- ccd视觉定位教程_什么是CCD视觉定位自动焊锡机器人?
全方位CCD视觉定位自动焊锡机器人,可迅速自动找到焊点,节省单点定位编程时间. 全景视觉焊锡机系统,可监控整个焊接过程. 支持三色光源自动调节,能够满足各种类型PCB板焊接. 激光光斑大小可自动调节, ...
- 一款可以适应于拼多多淘宝等店铺虚拟商品自动核销百度网盘自动发货机器人软件助手
前言: 看到很多开虚拟店的小伙伴找不到合适的网盘自动发货机器人软件助手,我也开发了一款,功能很多,先截个图: 1.可以对好友增加\删除\发送消息等操作. 2.可以对群组增加成员\删除成员\发送消息\创 ...
- WPF教程六:布局之Grid面板(转)
WPF教程六:布局之Grid面板 Grid:网格面板 Grid顾名思义就是"网格",以表格形式布局元素,对于整个面板上的元素进行布局,它的子控件被放在一个一个事先定义好的小格子里面 ...
- 【STM32】标准库与HAL库对照学习教程十三--软件IIC控制AT24C02
[STM32]标准库与HAL库对照学习教程十三--软件IIC控制AT24C02 一.前言 二.准备工作 三.AT24C02(EEPROM)介绍 1.AT24C02简介 2.引脚功能 3.设备地址 四. ...
最新文章
- 【Ionic+AngularJS 开发】之『个人日常管理』App(二)
- 计算机专业英语怎么翻译,计算机专业英语翻译(附件).pdf
- 4.数据库的连接(编目)-远程连接
- github客户端的使用方法教程
- java 二叉树运用场景_java二叉树有什么作用?有哪些实际应用?
- java-net-php-python-jsp音像店租赁录像计算机毕业设计程序
- java中订单流水号_订单流水号的生成
- 生意宝,淘宝,唯品会,58同城,去哪儿背后的赚钱生意经(转)
- 【数据结构】一张图让你读懂:树的高度、深度、层的区别
- Java TreeMap排序
- gsyVideoPlayer直播短视频回放,集成腾讯播放器(2)
- 用python爬取链家的租房信息
- JS 数字,金额 用逗号 隔开(数字格式化)
- TS在前端发展的当前形式(愚见)
- 【超详细】MySQL零基础入门实战
- VMware16安装苹果OS及如何unlock(亲测有效)
- Java开发之路—Java反射机制
- React全家桶写一个CNode社区,奉上心得与源码
- excel服务器okr系统,OKR工具能帮企业落地OKR吗?从飞书OKR看专业工具的价值
- USB服务器赋能美团数字化建设
热门文章
- codeforces 332B B. Maximum Absurdity(rmq)
- 没有期刊申请清华博士_清华大学官方:“博士生无须发表论文”理解有误!
- Linux和UNIX
- 计算之魂算法复杂度的相关概念
- C++循环结构实例:估算e值:计算e=1+(1/1!)+(1/2!)+…的近似值,1/n!小于10^(-7)时停止计算
- 什么是OTG,手机OTG的用途
- Coursera半价优惠
- 软件测试用例设计方法(一)
- weblogic 启动问题
- Dubbo入门基础与实例讲解