美文网首页玩转树莓派物联网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