DuerOS语音控制机械手实现过程
1040312385 发布于2018-12-13 15:37 浏览:296 回复:1
1
收藏

        接触DuerOS三个月来,通过查看官方教程和视频,以及逛论坛和慢慢尝试,总算实现了预期的效果,但不得不说花费了比预期多的时间和精力,所以把我还记得的开发过程进行分享。

1.实现功能

主要功能为利用小度音箱的语音识别功能和海天控制器的图像追踪功能进行物体识别和抓取,还具有语音控制机器人移动的功能,可以看下面地址的视频来查看效果

链接:https://pan.baidu.com/s/1n75NdVAWovrLuH_JOP30GA 密码:0m5

2.实现流程与思路

在百度云服务器搭建服务器监听端口信息,在技能的代码中建立一个客户端,在识别到所需的数据后,通过客户端写入函数,传递数据到云服务器。云服务器接收到数据后,立即传递到电脑本地客户端,电脑本地客户端将简化的命令数据写成txt文件,用Qt程序监视txt文件所在目录,得到新的txt文件后解析命令成控制器命令,从而控制机械手。

3.具体搭建步骤

3.1技能的设计

技能的设计和官方的个税例子很像,在此不做过多的赘述。

3.2百度云盘服务器的搭建

我用的云服务器操作系统为Windows Server2012,需要在上面安装node,及notepad++;云服务器代码如下:

// 1 引入模块
const net = require('net');
// 2 创建服务器
var clientArr = [];

const server = net.createServer();
// 3 绑定链接事件
server.on('connection',(person)=>{
console.log(clientArr.length);
// 记录链接的进程
person.id = clientArr.length;
clientArr.push(person);
person.setEncoding('utf8');
// 客户socket进程绑定事件
person.on('data',(chunk)=>{
console.log(chunk);
for (var i=0; i<clientArr.length; i++)
{
	clientArr[i].write(chunk);
}
})
person.on('close',(p1)=>{
clientArr[p1.id] = null;
} )
person.on('error',(p1)=>{
clientArr[p1.id] = null;
})
})
server.listen(3331);

3.3技能代码如下

/*
* 如果需要使用监控统计功能,请将PUBLIC KEY 复制到DuerOS DBP平台
* 文档参考:https://dueros.baidu.com/didp/doc/dueros-bot-platform/dbp-deploy/authentication_markdown

-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC4x5Es+JrQ6Sfqa9NojVgRRoGj
8xZTEnBDkN0ZJPZCYxZa7UCpeiVq3UcWHdGa8q5WW9RJc8tfbRzngzd35fSL49S+
fO6G7MjeIpd76rw/JmYiLP9e9Z41PiXfAcb5pbDhyZ4H3ovaWkAR42ROZt9HlzEJ
uF9YB3yNBtG4uZcccwIDAQAB
-----END PUBLIC KEY-----

*/
/**
 * @file   index.js 此文件是函数入口文件,用于接收函数请求调用
 * @author dueros
 */
const Bot = require('bot-sdk');
const privateKey = require('./rsaKeys.js').privateKey;
const readline = require('readline');
const net = require('net');

// 2 创建套接字和输入输出命令行
var rl = readline.createInterface({
    // 调用std接口
    input: process.stdin,
    output: process.stdout
})
var client = new net.Socket();


client.connect("你的服务器ip地址及端口号");

client.setEncoding('utf8');
client.on('data', (chunk) => {
    console.log('服务器说: ' + chunk);
})
client.on('test', (data) => {
    console.log('服务器说: ' + chunk);
})
client.on('error', (e) => {
    console.log(e.message);
})

let vol = 0;
const shapeTonumMap = {
    '圆形': 1,
    '三角形': 2,
    '长方形': 3,
    '椭圆形': 4,
};

class InquiryBot extends Bot {
    constructor(postData) {
        super(postData);

        this.addLaunchHandler(() => {
            this.waitAnswer();
            let card = new Bot.Card.TextCard('欢迎使用海天控制器!');
            return {
                card: card,
                outputSpeech: '欢迎使用海天控制器!'
            };
        });

        this.addSessionEndedHandler(() => {
            this.endSession();
            let card = new Bot.Card.TextCard('多谢使用,再见!');
            return {
                card: card
                // outputSpeech: '多谢使用,再见!'
            };
        });

        this.addIntentHandler('AIgrab', () => {
            this.waitAnswer();
            let shape = this.getSlot('shape');
            let num = shapeTonumMap[shape];
            vol = num;
            if (!shape) {
                this.nlu.ask('shape');
                let card = new Bot.Card.TextCard('请问你要抓取哪个物品??');
                // 可以返回异步 Promise
                return Promise.resolve({
                    card: card,
                    outputSpeech: '请问你要抓取哪个物品??'
                });
            }

            if (this.request.isDialogStateCompleted()) {
                let card = new Bot.Card.TextCard(`好的,正在抓取${shape}物品`);
                client.write(`${vol}`)
                return {
                    card: card,
                    outputSpeech: `好的,正在为你抓取${shape}`
                };
            }
        });

        this.addIntentHandler('teach', () => {
            this.waitAnswer();
            let obj = this.getSlot('axis');
            let len = this.getSlot('sys.unit-length');
            if (!obj) {
                this.nlu.ask('axis');
                let card = new Bot.Card.TextCard('你要控制哪个轴?');
                // 可以返回异步 Promise
                return Promise.resolve({
                    card: card,
                    outputSpeech: '你要控制哪个轴?'
                });
            }

            if (!len) {
                let card = new Bot.Card.TextCard('你要移动多少?');
                this.nlu.ask('sys.unit-length');
                return {
                    card: card,
                    outputSpeech: '你要移动多少?'
                };
            }

            if (this.request.isDialogStateCompleted()) {
                client.write(`${obj}+${len.substring(11, 18)}`);
                let card = new Bot.Card.TextCard(`好的,正在移动${obj}轴,${(len.substring(11, 18)) * 100}厘米`);
                return {
                    card: card,
                    outputSpeech: `好的,正在移动${obj}轴,${(len.substring(11, 18)) * 100}厘米`
                };
            }
        });



    }
}

exports.handler = function (event, context, callback) {
    try {
        let b = new InquiryBot(event);
        // 0: debug  1: online
        b.botMonitor.setEnvironmentInfo(privateKey, 0);
        b.botMonitor.setMonitorEnabled(true);
        b.run().then(function (result) {
            callback(null, result);
        }).catch(callback);
    }
    catch (e) {
        callback(e);
    }
};

 3.3电脑本地客户端的搭建

// 1 引入模块
const net = require('net');
const readline = require('readline');
var fs = require('fs');
// 2 创建套接字和输入输出命令行
var rl = readline.createInterface({
// 调用std接口
input:process.stdin,
output:process.stdout
})
var client = new net.Socket();
// 3 链接

client.connect("你的服务器IP地址及端口");

client.setEncoding('utf8');
client.on('data',(chunk)=>{
console.log('服务器说: ' + chunk);
//获取日期与时间
var myDate = new Date();
var time = myDate.toLocaleString();
console.log(time);
//整理文件名
time = time.replace("-","");
time = time.replace("-","");
time = time.replace(" ","");
time = time.replace(":","");
time = time.replace(":","");
name = time + '.txt';
//写入文件
fs.writeFile(name,chunk,'utf8',function(error){
    if(error){
        console.log(error);
        return false;
    }
    console.log('写入成功');
});
})
client.on('error',(e)=>{
console.log(e.message);
})
// 绑定输io流事件,获取输入输出字符
rl.on('line',(mes)=>{
client.write(mes);
})

通过以上三步就能实现,数据由技能到槽位到云服务器到本地服务器到txt的传递流程。后续的控制与公司控制器相关,就不在此进行展示了。

 

 

收藏
点赞
1
个赞
共1条回复 最后由DuerOS-河徒回复于2018-12-13 18:31
#2DuerOS-河徒回复于2018-12-13

厉害啦

0
TOP