极客DIY:制作一个可以面部、自主规划路径及语音识别的无人机

极客DIY:制作一个可以面部、自主规划路径及语音识别的无人机

引言

现在大部分无人机厂商都会为第三方开发者提供无人机API接口,让他们更容易地开发无人机飞行控制应用程序,让无人机想怎么玩就怎么玩。有的API接口可以帮助开发者开发基于Web版的APP、手机APP甚至是用Python编写的直接在无人机上运行的APP。经过我的研究和选择之后,我觉得选择Parrot AR.Drone2无人机,当然你可以购买全新的无人机,但这里考虑成本的问题,我觉得使用二手的无人机。Node.js是一个基于google v8+javascript的服务端编程框架。但是Node.js又不是js应用,应该说是js的运行平台。它采用事件驱动、异步编程,为网络服务而设。

在这里更是可以应用在控制方面(node-ar-drone)。另外一点值得注意的是,虽然无人机的声音还是比较大,但是稳定性可以说还是不错的,我在试验中无人机曾经摔到花盆、墙壁,但在这之后还是可以正常飞行,如果感觉电池不够用,可以购买两个备用电池加到上面,以此保证持续飞行时间,对于一些无人机用户可以通过JavaScript以及Arduino C/C++为无人机开发应用,而在一次我使用c语言来完成机器人应用开发时候,其中线程以及异常处理令人头疼,当然在开发过程中如果有现成的 Javascript包那就更好了。我觉得开始在笔记本电脑上构建逻辑运算,这样延迟比较低(相对底层硬件为树莓派无人机),同时使用云端机器学习平台。微软、谷歌、IBM和亚马逊都有很不错的平台,由于考虑面部识别功能,我决定使用微软的平台。

极客DIY:制作一个可以面部、自主规划路径及语音识别的无人机

开始

在默认设置情况,无人机可以通过无线网络与客户端连接,当想要尝试做一些事情时候,并连接其它网络则需要断开连接,这样很不方便。这里有一个脚本ardrone-wpa2,可以攻击测试无人机并保证网络连接,下面命令即通过计算机连接无人机。

% script/connect "The Optics Lab" -p "particleorwave" -a 192.168.0.1 -d 192.168.7.43

% telnet 192.168.7.43

安装相关文件( node library),就可以创建一个简单的,交互式的编程环境( node.js REPL(读取评估和演示打印循环))来控制无人机。

var arDrone = require('ar-drone');
var client = arDrone.createClient({ip: '192.168.7.43'});
client.createRepl();
drone> takeoff()
true
drone> client.animate(‘yawDance, 1.0)

在实验的过程中很容易出现摔落的危险,之前我在飞机上安装了保护装置,但在摔落之后,保护装置也曾出现诸多问题,而现在使用的这一款无人机没有自带安全壳,所以你可以参考建议自行加装安全装置。可以参考下面很容易建立一个基于web界面的无人机,利用express.js框架也很容易的建立一个web服务器。

var express = require('express');
app.get('/', function (req, res) {
res.sendFile(path.join(__dirname + '/index.html'));
});
app.get('/land', function(req, res) {
client.land();
});
app.get('/takeoff', function(req, res) {
client.takeoff();
});
app.listen(3000, function () {
});

我通过设置点击button触发并发送AJAX请求

<html>
<script language='javascript'>
function call(name) {
var xhr = new XMLHttpRequest();
xhr.open('GET', name, true);
xhr.send();
}
</script>
<body>
<a onclick="call('takeoff');">Takeoff</a>
<a onclick="call('land');">Land</a>
</body>
</html>

视频

我发现使用无人机上面相机最好的方式就是建立一个连接,然后在服务器到页面之间创建一个PNG数据流,然后无人机( AR drone library)摄像头与服务器之间就可以不断传输数据。

var pngStream = client.getPngStream();
pngStream
.on('error', console.log)
.on('data', function(pngBuffer) {
sendPng(pngBuffer);
}
function sendPng(buffer) {
res.write('--daboundary\nContent-Type: image/png\nContent-length: ' + buff
er.length + '\n\n');
res.write(buffer);
});

面部识别

脸部识别API,Azure接口功能很强大,你可以上传一些人物照片,而它会识别它们,并猜测年龄,我发现这个准确率还是很高的。整个过程延时时间大约是200毫秒,成本约1.50美元/ 1000张,下面的程序就是发送图片并做出识别。在这个过程中我使用ImageMagick库来处理面部识别的图片(PNG),而在这一方面还有很多扩展,比如如何识别面部感情情况。

var oxford = require('project-oxford'),
oxc = new oxford.Client(CLIENT_KEY);
loadFaces = function() {
chris_url = "https://media.licdn.com/mpr/mpr/shrinknp_400_400/AAEAAQAAAAAAAALyAAAAJGMyNmIzNWM0LTA5MTYtNDU4Mi05YjExLTgyMzVlMTZjYjEwYw.jpg";
lukas_url = "https://media.licdn.com/mpr/mpr/shrinknp_400_400/p/3/000/058/147/34969d0.jpg";
oxc.face.faceList.create('myFaces');
oxc.face.faceList.addFace('myFaces', {url => chris_url, name=> 'Chris'});
oxc.face.faceList.addFace('myFaces', {url => lukas_url, name=> 'Lukas'});
}
oxc.face.detect({
path: 'camera.png',
analyzesAge: true,
analyzesGender: true
}).then(function (response) {
if (response.length > 0) {
drawFaces(response, filename)
}
});

语音识别

语音识别最难的部分就是本身,通过采集音频信息,然后通过网页再到本地(Microsoft’s Speech API ),并最终实现解码。我可以通过单一频道来保存音频信息,并保证采样过程一切正常,初步估计成本在4美元/1000(请求数),当然你也可以使用一些发烧友的程序,这里面也有免费的。RecordRTC是一个基于WEB的在线录音,播放等功能的程序,还有一个很给力的库,下面可以通过在客户端添加代码来保存音频文件。

app.post('/audio', function(req, res) {
var form = new formidable.IncomingForm();
// specify that we want to allow the user to upload multiple files in a single request
form.multiples = true;
form.uploadDir = path.join(__dirname, '/uploads');
form.on('file', function(field, file) {
filename = "audio.wav"
fs.rename(file.path, path.join(form.uploadDir, filename));
});
// log any errors that occur
form.on('error', function(err) {
console.log('An error has occured: \n' + err);
});
// once all the files have been uploaded, send a response to the client
form.on('end', function() {
res.end('success');
});
// parse the incoming request containing the form data
form.parse(req)
speech.parseWav('uploads/audio.wav', function(text) {
console.log(text);
controlDrone(text);
});
});

通过使用FFmpeg(一个可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序)来采集音频信息,然后通过指定频道上传( Microsoft),我们在这个过程中会用到微软 text-to-speech API,所以可以和无人机进行互动。

exports.parseWav = function(wavPath, callback) {
var cmd = 'ffmpeg -i ' + wavPath + ' -ar 8000 -ac 1 -y tmp.wav';
exec(cmd, function(error, stdout, stderr) {
console.log(stderr); // command output is in stdout
});
postToOxford(callback);
});

我决定开始无人机自主规划路径(autonomy library)设计,当然在这个过程中发现地方大才是关键,在这个过程中出现很多次摔落情况,我觉得使用更有效的算法,来分辨我的朋友和敌人。

var autonomy = require('ardrone-autonomy');
var mission = autonomy.createMission({ip: '10.0.1.3', frameRate: 1, imageSize: '640:320'});
console.log("Here we go!")
mission.takeoff()
.zero() // Sets the current state as the reference
.altitude(1)
.taskSync(console.log("Checkpoint 1"))
.go({x: 0, y: 0, z: 1, yaw: 90})
.taskSync(console.log("Checkpoint 2"))
.hover(1000)
.go({x: 0, y: 0, z: 1, yaw: 180})
.taskSync(console.log("Checkpoint 3"))
.hover(1000)
.go({x: 0, y: 0, z: 1, yaw: 270})
.taskSync(console.log("Checkpoint 4"));
.hover(1000)
.go({x: 0, y: 0, z: 1, yaw: 0
.land()

一旦完成如上设置,相信无人机会给你带来更多乐趣,而更多的图像识别功能,相信也会带来不少乐趣,比如利用无人机测量墙壁完成粉刷任务,虽然多功能无人机的价格贵一些,但相信不远将来无人机价格会变得更低,在这个过程中,微软认知服务综合起来成本比较低,期初我担心无人机相机的死角以及螺旋桨声音会干扰图像及声音识别程序,但最后测试比预期想的要好的多,目前来看延迟并不是一个大问题,相信以后基于云端会出现更多的图像识别软件。

视频

上一篇:【BZOJ3262】陌上花开 (CDQ分治+树状数组+排序)


下一篇:lintcode:合并两个排序链表