美文网首页玩转树莓派物联网IOT创意开发树莓派
人工智能-树莓派小车(4)——通过语音玩转智能小车

人工智能-树莓派小车(4)——通过语音玩转智能小车

作者: IConquer | 来源:发表于2018-01-29 20:36 被阅读1033次

本文是基于百度的DuerOS Python SDK进行的,具体安装以及实现过程,可以看我的这篇教程:人工智能-树莓派小车(1)——DuerOS语音唤醒,要实现的功能有:

  1. 语音聊天:可以跟智能小车进行对话,询问现在的天气,播放想听的歌曲等等基本对话;
  2. 语音控制:可以通过语音的操作方式控制智能小车的前进后退、避障转弯等功能,进一步可以扩展到家里的台灯、空调、窗帘等等家具;
  3. 语音反馈:在你发出命令后,小车还会给出回应,与你互动,实现一个良好的反馈。

视频演示

实现了以上几个功能,做了一个演示,视频链接:通过语音玩转智能小车

核心代码

1. 命令读取

content = u'云端下发directive:%s' % (directive_content)

content里即为我们要读取的命令数据,是一种类JSON格式,所以有两种办法将数据读取出来。

  1. 采用JSON的字典格式
import json

with open('out.json','a') as f:
        f.write(json.loads(content).decode('unicode-escape').encode('utf-8'))
        f.close()
  1. 直接将数据保存为.txt格式
f = open("ord.txt",'a')
f.write(content)
logging.info(content)

2. 命令判断

读取到命令之后要对其进行检测,如果命令中包含一些特定的关键词,则做出相应的动作。

def recognize():

        file = '/home/pi/Rascar-DuerOS-Python-Client/ord.txt' # 读取文件
        f = open(file,'r')
        out = f.read()
        command = out.decode('unicode-escape').encode('utf-8')
        print command
        GPIO.output(LED_CTR, GPIO.LOW)
        ############################################
        ###############命令识别######################
        ############################################
        
        if command.find(u"开") !=-1 and command.find(u"大") !=-1 and command.find(u"灯") !=-1:
                print "打开前大灯"
                robot.Open_Flight()
                GPIO.output(LED_CTR, GPIO.HIGH)
                shutil.copy("/home/pi/Rascar-DuerOS-Python-Client/app/resources/turn_on_light.mp3","/home/pi/Rascar-DuerOS-Python-Client/temp.mp3")
                
        elif command.find(u"关") !=-1 and command.find(u"大") !=-1 and command.find(u"灯") !=-1:
                print "关闭前大灯"
                robot.Close_Flight()
                GPIO.output(LED_CTR, GPIO.HIGH)
                shutil.copy("/home/pi/Rascar-DuerOS-Python-Client/app/resources/turn_off_light.mp3","/home/pi/Rascar-DuerOS-Python-Client/temp.mp3")
                
        elif command.find(u"前") !=-1 and command.find(u"进") !=-1:
                print "前进"
                robot.Motor_Forward()
                time.sleep(2)
                robot.Motor_Stop()
                GPIO.output(LED_CTR, GPIO.HIGH)
                shutil.copy("/home/pi/Rascar-DuerOS-Python-Client/app/resources/forward.mp3","/home/pi/Rascar-DuerOS-Python-Client/temp.mp3")
                
        elif command.find(u"后") !=-1 and command.find(u"退") !=-1:
                print "后退"
                robot.Motor_Backward()
                time.sleep(2)
                robot.Motor_Stop()
                GPIO.output(LED_CTR, GPIO.HIGH)
                shutil.copy("/home/pi/Rascar-DuerOS-Python-Client/app/resources/backward.mp3","/home/pi/Rascar-DuerOS-Python-Client/temp.mp3")
                
        elif command.find(u"左") !=-1 and command.find(u"转") !=-1:
                print "左转"
                robot.Motor_TurnLeft()
                p = GPIO.PWM(11, 3)
                p.start(20)
                time.sleep(0.5)
                p.stop()
                robot.Motor_Stop()
                GPIO.output(11, GPIO.LOW)
                GPIO.output(LED_CTR, GPIO.HIGH)
                shutil.copy("/home/pi/Rascar-DuerOS-Python-Client/app/resources/turn_left.mp3","/home/pi/Rascar-DuerOS-Python-Client/temp.mp3")
                
        elif command.find(u"右") !=-1 and command.find(u"转") !=-1:
                print "右转"
                robot.Motor_TurnRight()
                p = GPIO.PWM(8, 3)
                p.start(20)
                time.sleep(0.5)
                p.stop()
                robot.Motor_Stop()
                GPIO.output(8, GPIO.LOW)
                GPIO.output(LED_CTR, GPIO.HIGH)
                shutil.copy("/home/pi/Rascar-DuerOS-Python-Client/app/resources/turn_right.mp3","/home/pi/Rascar-DuerOS-Python-Client/temp.mp3")
                
        elif command.find(u"黑") !=-1 and command.find(u"线") !=-1:
                print "黑线"
                robot.TrackLine()
        return 

其中GPIO接口的设置以及初始化,见人工智能-树莓派小车-GPIO控制小车
最后要养成良好习惯,用完GPIO接口记得清理GPIO口

GPIO.cleanup()

3. 命令文件清空

为避免命令文件堆积,每次识别命令结束后,进行命令文件的清理,代码很简单。

f = open("ord.txt",'w')
f.truncate()
f.close()

4. 命令反馈

这部分集成到了第二部分命令判断中,判断完立即进行反馈。

完整代码

所有的代码都上传到了我的GitHub上
Rascar-DuerOS — a Raspberry intelligent car based on the DuerOS

系列教程

人工智能-树莓派小车(1)——DuerOS语音唤醒
人工智能-树莓派小车(2)——GPIO接口介绍
人工智能-树莓派小车(3)——GPIO控制小车
人工智能-树莓派小车(4)——通过语音玩转智能小车
人工智能-树莓派小车(5)——用微信控制智能小车

相关文章

网友评论

  • 赵小生:请问需要设置 自定义控制指令 么。我每次获得的云端下发结果是这样的
    { 云端下发directive:{u'header': {u'dialogRequestId': u'e5077fe6aa064899a87528c7b03decb1', u'namespace': u'ai.dueros.device_interface.screen', u'name': u'RenderVoiceInputText', u'messageId': u'7fbfef4efea04e2d8f2410cd6f15475e'}, u'payload': {u'text': u'啦啦啦我是卖报的', u'type': u'INTERMEDIATE'}} }{ 云端下发directive:{u'header': {u'dialogRequestId': u'e5077fe6aa064899a87528c7b03decb1', u'namespace': u'ai.dueros.device_interface.screen', u'name': u'RenderVoiceInputText', u'messageId': u'd860826a783a41c2acb9da800e84ad95'}, u'payload': {u'text': u'啦啦啦我是卖报的小', u'type': u'INTERMEDIATE'}} }{ 云端下发directive:{u'header': {u'dialogRequestId': u'e5077fe6aa064899a87528c7b03decb1', u'namespace': u'ai.dueros.device_interface.screen', u'name': u'RenderVoiceInputText', u'messageId': u'7bb97e2c2f664caa872a84119a394edd'}, u'payload': {u'text': u'啦啦啦我是卖报的小行', u'type': u'INTERMEDIATE'}} }{ 云端下发directive:{u'header': {u'dialogRequestId': u'e5077fe6aa064899a87528c7b03decb1', u'namespace': u'ai.dueros.device_interface.voice_input', u'name': u'StopListen', u'messageId': u'99cf6aa1c7a04a4f9d2844d711bd86b1'}, u'payload': {}} }{ 云端下发directive:{u'header': {u'dialogRequestId': u'e5077fe6aa064899a87528c7b03decb1', u'namespace': u'ai.dueros.device_interface.screen', u'name': u'RenderVoiceInputText', u'messageId': u'ce103733ee974a4c9100edd58252e14c'}, u'payload': {u'text': u'啦啦啦我是卖报的小行家', u'type': u'FINAL'}} }{ 云端下发directive:{u'header': {u'dialogRequestId': u'e5077fe6aa064899a87528c7b03decb1', u'namespace': u'ai.dueros.device_interface.voice_output', u'name': u'Speak', u'messageId': u'NWJhZjk3Y2VhOTUxYTY5'}, u'payload': {u'url': u'cid:140626', u'token': u'eyJib3RfaWQiOiJ1cyIsInJlc3VsdF90b2tlbiI6ImI2NzU4NGE1LTU5MTYtNGQwMy04ZGUyLWQ4Y2VhNjkzOGVmMyIsImJvdF90b2tlbiI6Im51bGwifQ==', u'format': u'AUDIO_MPEG'}} }

    前面的都是text,只有最后一个有url,最后小度就会播放“对不起,我不明白你说什么,换一个试试”之类的默认回复。
    IConquer:你看一下我的文章,更新了你说的这一部分
    赵小生:怎么样让小度不播放默认回复呢?
  • flyingtiger:老师,我用您bithub上的代码做一个语音控制LED,接在GPIO07(26PIN)上,向小车发“打开前大灯”之类的语音命令,LED没反应,小度有语音回答。ord.TXT上的内容如下:(其他几个读者也遇到此问题,您的回复,我没看懂。)

    云端下发directive:{u'header': {u'dialogRequestId'
    : u'c6d036a46c8443759df81a3a11cae2fe', u'namespace': u'ai.dueros.device_interface.voice_input', u'name': u'StopListen', u'messageId': u'0081a22be3a3471fbce65ade8f3315e6'}, u'payload': {}}云端下发directive:{u'header': {u'dialogRequestId': u'c6d036a46c8443759df81a3a11cae2fe', u'namespace': u'ai.dueros.device_interface.screen', u'name': u'HtmlView', u'messageId': u'NWI3ZDA1MjY1ZTdjMDg5MTg='}, u'payload': {u'url': u'http://xiaodu.baidu.com/saiya/dcsview?id=56b9743c86f520340ef446bd00883320&;appid=dm31C92BFAB7449A6B', u'token': u'eyJib3RfaWQiOiJ1cyIsInJlc3VsdF90b2tlbiI6IjJjMTE5MmQwLTY2MGItNGM5Zi05N2IyLTA0ZDkxOGU2ZTdhYyIsImJvdF90b2tlbiI6Im51bGwifQ=='}}云端下发directive:{u'header': {u'dialogRequestId': u'c6d036a46c8443759df81a3a11cae2fe', u'namespace': u'ai.dueros.device_interface.voice_output', u'name': u'Speak', u'messageId': u'NWI3ZDA1MjY1ZTgwMTY5MDI='}, u'payload': {u'url': u'cid:242407', u'token': u'eyJib3RfaWQiOiJ1cyIsInJlc3VsdF90b2tlbiI6IjJjMTE5MmQwLTY2MGItNGM5Zi05N2IyLTA0ZDkxOGU2ZTdhYyIsImJvdF90b2tlbiI6Im51bGwifQ==', u'format': u'AUDIO_MPEG'}}
    IConquer:@李世兴_0205 我最近在弄别的东西,跟你说一下大概思路,首先提取返回的数据中的网址,然后解析网址内容,获取返回的命令
    flyingtiger:@IConquer 老师,要怎么弄,有代码吗。谢谢您的回复。
    IConquer:@李世兴_0205 就是百度改了一下下发格式,我这种方法不行了,需要再加一个解析网页的步骤
  • Feezhen:楼主,请问你在树莓派上运行的还是wakeup的py文件吧,其他的py文件应该是作为模块来用吧
    IConquer:@Feezhen只做一条大咸鱼 对的
  • 58429271df39:楼主,我刚刚在CSDN上不能评论你了,所以在你的简书上来评论了,还是那个问题,我语音为"打开大灯 ",然后云端下发的指令如下。能不能给个联系方式?:sob:
    58429271df39:@IConquer 你现在还能获取嘛?我感觉百度已经改掉了云端下发的数据?是不是都强迫我们去使用他的智能家居槽:joy:
    58429271df39:@IConquer 我就想做一个智能小车来着的 通过语音控制:smile:
    IConquer:你用的是新版的DuerOS吗?你再获取一个然后马上发给我试试,看起来像是百度那边改了数据结构,你是想做什么东西?我看看有没有别的解决方案
  • 58429271df39:云端下发directive:{u'header': {u'dialogRequestId': u'72de1599802b4027b4928239c92eb0e5', u'namespace': u'ai.dueros.device_interface.voice_input', u'name': u'StopListen', u'messageId': u'213ef87d1a2f4d66bcaad766d061dc05'}, u'payload': {}}云端下发directive:{u'header': {u'dialogRequestId': u'72de1599802b4027b4928239c92eb0e5', u'namespace': u'ai.dueros.device_interface.screen', u'name': u'HtmlView', u'messageId': u'NWIwNGNhZGQ4YjYzNzM1NTU='}, u'payload': {u'url': u'http://xiaodu.baidu.com/saiya/dcsview?id=172ee634c5e7b73ece285266fae2763e&appid=dm31C92BFAB7449A6B', u'token': u'eyJib3RfaWQiOiJ1cyIsInJlc3VsdF90b2tlbiI6IjIyMjM5OTBhLTMwMWMtNGU0ZS04ZWJlLWEwZDgwYWNhOGVmMCIsImJvdF90b2tlbiI6Im51bGwifQ=='}}云端下发directive:{u'header': {u'dialogRequestId': u'72de1599802b4027b4928239c92eb0e5', u'namespace': u'ai.dueros.device_interface.voice_output', u'name': u'Speak', u'messageId': u'NWIwNGNhZGQ4YjY3Nzc1Mzg='}, u'payload': {u'url': u'cid:71689', u'token': u'eyJib3RfaWQiOiJ1cyIsInJlc3VsdF90b2tlbiI6IjIyMjM5OTBhLTMwMWMtNGU0ZS04ZWJlLWEwZDgwYWNhOGVmMCIsImJvdF90b2tlbiI6Im51bGwifQ==', u'format': u'AUDIO_MPEG'}}
    flyingtiger:@IConquer 如何获取前面的数据,没看懂。我也遇到这个问题,
    IConquer:@Mr_Wen666 我又看了一下,数据结构没有改,应该是你的获取问题,你只获取到了最后一条,要把前面的也获取到
  • 奔IV程序猿:现在云端下发内容里有 识别到得用户指令内容 了?年前我记得还没有呢。 当时觉得这就一鸡肋, 想本地做些事情都不行。
    IConquer:@奔IV程序猿 有啊,在wakeup_trigger_main.py里面有一个云端下发 content里面,没有显性结果,需要自己提取,而且是多次下发,需要多次获取,不能只获取最后一个,最后有一个文件尾,没有数据
    奔IV程序猿:@IConquer 昨天跑了下小度的Python SDK,下发数据里还是没有识别结果啊。
    IConquer:@奔IV程序猿 嗯,有的,就是需要转一下编码格式
  • pinus_x:请问如何添加新的指令呢,让dueros有反应呢,你的对应的语音包是哪里获得的,谢谢
    pinus_x:@IConquer 谢谢
    IConquer:就仿照我的格式添加就行了,对应的语音模块可以参考我的人工智能-树莓派小车(5)——用微信控制智能小车,这个方式更加优雅易用,代码就在我的Github上
  • 泥_叔:很赞
    IConquer:@CallMe小凯 谢谢

本文标题:人工智能-树莓派小车(4)——通过语音玩转智能小车

本文链接:https://www.haomeiwen.com/subject/bvdzaxtx.html