树莓派声控小车
一、实验方案设计
声控小车的实现方案由三部分组成:①语音识别指令;②控制小车;③语音识别指令直接控制小车。
1.语音识别指令
识别声音利用百度AI开放平台的语音识别功能。由于搭配的麦克风和可识别音频的采样率不同,需要用特定python库进行语音采样率转换。设定识别声音的响度阈值,实现声音识别的伪中断。对于识别的结果,需要进行错误处理。
2.控制小车
选择微雪电子的AlphaBot智能小车。依据需要实现的功能修改小车运行示例程序。小车的电源配置需要考虑。小车上的树莓派需要连接无线网络。同时,实现与小车的通信十分重要,可以大大降低修改代码时间。
3.语音指令直接控制小车
在示例程序的基本小车类中添加控制函数,利用该函数接受语音指令转化的字符串,控制小车移动。
二、实验器材
3B+树莓派
SSPD3303x可编程直流电源
微雪电子树莓派3代B+小车
8v可充电电池
时尚部落带声卡USB电脑麦克风话筒
三、实验步骤
1.语音识别部分
在百度AI开放平台注册账号后,创建新的语音识别应用,并记录应用的API key和Secret Key。下载Github上百度提供的示例程序和示例音频[1],填入项目的API key和Secret Key。程序参数的设置:DEV_PID设为1536,使用用搜索模型,适合于短语识别,没有逗号。运行示例程序,得到识别结果:“北京科技馆”,样例识别成功。
将USB麦克风连接到树莓派上。首先安装调用麦克风的pyaudio库[3]。利用pyaudio和wave库,将声道数调整为1,采样率调整为48000,实现麦克风的录音功能。程序中写入循环,每次录音之后保存成一个wav文件。
由于百度AI语音识别的采样率固定为16000,因此需要修改采样率。转换采样率的python库有3个:sox,librosa,ffmpeg。经尝试,sox和librosa不能和树莓派的兼容。使用ffmpeg转换采样率方法有二:
① 安装ffmpeg库[4]。
ffmpeg.input(INITIAL_FILENAME).output(“OUTPUT_FILENAME”,ar=16000).overwrite_output().run()
②apt-get install ffmpeg,安装ffmpeg包。
注:apt-get
install 和 pip3 install 安装的内容是不同的。
os.system(“ffmpeg -y -i " +OUTPUT_FILENAME+” -ar 16000 "+INITIAL_FILENAME)
然后调用语音识别函数,得到返回结果例如:
{“corpus_no”:“6433214037620997779”,“err_msg”:“success.”,“err_no”:0,“result”:[“北京科技馆,”],“sn”:“371191073711497849365”}
截取结果中“[”和“]”中的汉字字符打印输出。若未得到“[”、“]”,则识别失败,继续循环识别。
注:语音识别受7网速,采样率转换和百度AI反应时间的影响,整个流程需要5s左右,需要优化。
实际应用时需要对外界噪声进行过滤,并实现类似中断的语音识别。小车持续不断接受外界声音信号,当声音音量超过某个响度阈值时,设为开始录音。参考[8]博客内容。循环开始时读取2000个样本,并将样本的音量转化为一维数组,计算数组中的最大值和超过阈值的样本数。满足边界条件(超过阈值样本数大于20,最大值超过4000)后开始录音。具体参数的选择由实验确定。由于采样速率快,2000个样本的录音不会影响命令的识别。重复命令更可保证录音的完整性。这样就完成了伪中断的语音识别。
2.控制小车
首先从微雪电子AlphaBot介绍网页[5]下载示例代码。结合样例程序中的基本AlphaBot类内部函数: forward(), stop(), backward(), left(), right(),理解管脚对应的前后左右关系:IN1对应右后,IN2对应右前,IN3对应IN左前,IN4对应左后。示例代码中的左右是反的,需要修正。并且示例代码中的left(),right()功能为持续旋转,不符合语音对小车的控制。
将forward( )修改为前进3秒,backward( )退后3秒,left( ), right( )完成左右的90度旋转后就停止,并且添加加速和减速的功能。加速减速通过修改车轮转速控制,在转速:20~70范围内,每次加速(减速),转速增加(减少)8。最低转速保证小车还能运动,过低转速提供的牵引力不能克服摩擦力。过高转速导致小车轮子掉落。
left( ), right( )完成90度旋转后就停止,为此需要设计旋转时间和小车速度的匹配函数。设计函数为:
turn_time * PWM = 16
其中turn_time为旋转时间,PWM为小车左右轮转速。
初步设计完小车的运动程序后,需要解决小车通信问题。注意需要首先在树莓派的configuration界面进行如下配置。通信方法有两种:Serial和SSH。
图1、树莓派configuration配置界面
① UART串口通信
UART用有线串口与小车进行通信。可在微雪电子AlphaBot介绍网页[5]下载串口通信程序PUTTY。用数据线分别连接小车的UART接口和电脑USB接口,然后选择Serial,波特率设为115200,Serial line由USB在电脑接口位置确定,可查看控制面板(control panel)确定。完成之后即可通过命令行访问树莓派。但是命令行中修改代码只能用vim,较为不便。
图2、用Putty进行Serial通信
语音识别需要连接无线网络。简便的方法可以在树莓派用户图形界面中直接连接无线网络,树莓派会存储下网络信息,将芯片移入小车中后可以自动连接。或者通过命令行连接[6]。在wpa_supplicant.conf文件中添加网络信息:
network={
ssid=“testing”
psk=“testingPassword”
}
添加后用wpa_cli -i wlan0 reconfigure命令即可连接。
② SSH通信
SSH连接可以用无线方式访问树莓派,不需要有线串口,故更加方便。首先将笔记本连接网线并打开热点,树莓派连接热点后可以在笔记本上获得该设备的ip地址。同样利用PUTTY,如图进行操作。完成后即可远程访问树莓派命令行。
图3,putty连接SSH
进一步,利用VNC可以访问树莓派用户图形界面,更加方便。下载VNC viewer,输入树莓派的ip地址后即可连接树莓派的桌面。
附:如果遇到树莓派密码不正确的情况,可在桌面的configuration处修改密码。或通过命令$ sudo -s, $ passwd
pi 即可修改。
需要寻找合适的电源为小车提供电能:
① 可编程直流电源
在调试小车时可使用可编程直流电源。将电源设为8v,2A,接在小车电池槽对应位置即可。
图4、直流电源为小车供电
② 可充电电池
用可充电电池为小车供电。电池槽旁边有两个管脚,充电电池可通过杜邦线为小车供电。
图5、可充电电池为小车车供电
3.语音指令直接控制小车
首先在AlphaBot类中编写小车控制函数,将识别完成的命令字符串转化为小车的运动。经实验发现语音转换对“前进”有时会识别成“陈静”,为了解决这类问题。将汉字转换为拼音。安装pypinyin库[7]实现该功能。这样“jin”,“jing”,“qian”都可认为是前进。
由于语音识别+采样率转换过程需要时间较长(5s左右),语音操控者需要知道语音识别进行到什么阶段,否则就会在识别或者转采样率过程中说出语音,导致命令失败。想法是小车可以对语音识别状态进行反馈。最终方案是调取小车的红外避障模块所搭配的LED绿灯。
小车的左右尾部各有一个红外避障模块。当探测到后方有障碍时绿灯熄灭,无障碍时绿灯亮起。由GPIO控制。在程序中将GPIO.input( )转为GPIO.output( ), 就可直接控制LED绿灯。录音进行中绿灯亮,识别和转采样过程中绿灯闪烁。待语音输入时绿灯熄灭,这样语音控制者就可以知道小车处在什么状态了。
注:经老师提醒,这样直接的输出到输入转换会导致避障模块内高电平直接接低电平,导致元件短路,模块损坏。正确的做法是将避障模块拆下,GPIO管脚接LED灯。
图6、小车尾部避障模块绿灯
四、实验不足与展望
-
转采样率可以通过在树莓派上设置声卡文件实现。这种方法应该可以节省转采样率时间。
-
语音识别可以尝试百度语音识别的极速版,或者用自训练模型对某些指令的识别进行强化。
-
由于硬件原因,在小车的左右轮转速相同时左右轮的实际运动速度不同。应该设计反馈系统,在每次程序运行之前进行左右轮动力校准。例如用摄像头跟踪地板边沿黑线,直行时利用摄像头跟踪的误差进行左右轮转速调节。
-
不应该直接将避障模块的输入转成输出,造成器件短路烧坏。正确做法为将避障模块拆卸,LED灯接GPIO管脚进行显示操作。
五、参考资料
语音识别示例程序,Github,link
百度语音识别文档,百度AI平台, link
树莓派下安装pyaudio与使用 ,CSDN博客,link
Python 调用 FFmpeg 提示 module ‘ffmpeg’ has no attribute ‘input’ 的解决方法,老唐博客 link
AlphaBot文档,微雪百科, link
树莓派3从命令行连接wifi, 简书,link
利用python实现汉字转拼音的2种方法,脚本之家,link
python +百度语音识别+图灵对话,蜗牛咕叽咕叽博客link
小车成品