无人机劫持控制Github开源项目

最后编辑时间: 2017-04-12

ar-drone是Parrot ARDrone 2.0使用协议的实现方式,同时也兼容1.0版本。

通过Github安装最新版本:

npm install git://github.com/felixge/node-ar-drone.git

或者,用户不需要一些前沿的功能,也可以使用以下命令进行安装:

npm install ar-drone

简介

AR Drone是一种价格实惠、功能完善的四轴飞行器,使用一种专有的固件,使用户可以通过官方的FreeFlight手机应用借助WIFI进行控制。

不同于固件,它的客户端协议是开源的,Parrot发布了一款包含大量文档和C代码的SDK。他们的目标用户是移动开发人员,使他们可以使用该SDK开发可以无线控制的游戏和应用。同时,该协议也可用于接收视频和传感器数据,使开发人员可以编写自动化程序,应对即将到来的“机器人革命”。

状态

该协议仍处于开发过程中,所以可能会出现功能缺失。但是,已开发部分已通过测试,并且在大多数地区可以正常工作。

客户端

该部分提供了一个高级的客户端API,以便支持所有的无人机功能。

启动的最好方式使创建一个repl.js文件:

var arDrone =require('ar-drone');
var client  = arDrone.createClient();
client.createRepl();

使用REPL,其中包含一些功能:

$ node repl.js
// Make the drone takeoff
drone> takeoff()
true
// Wait for the drone to takeoff
drone> clockwise(0.5)
0.5
// Let the drone spin for a while
drone> land()
true
// Wait for the drone to land

下面,开发人员就可以编写自动化程序实现上述功能:

var arDrone = require('ar-drone');
var client  = arDrone.createClient();

client.takeoff();

client
  .after(5000, function(){
    this.clockwise(0.5);
  })
  .after(3000, function(){
    this.stop();
    this.land();
  });

然后,怎样实现无人机的交互?首先,需要查看传感器数据:

client.on('navdata', console.log);

这些并不都是通过客户端库处理的,但是至少,开发人员可以接收droneState 和demo数据。在首次尝试时,开发人员可以使用navdata.demo.altitudeMeters功能升到一定的高度。成功后,可以进行下一步尝试:查看摄像头照片。PngBuffers函数可以帮助实现该功能(要求$PATH变量中包含最近版本的ffmpeg):

var pngStream = client.getPngStream();
pngStream.on('data', console.log);

首次尝试可能只是将这些Png图像暴露为http节点服务器。然后,就可以将他们注入到opencv模块。

客户端API

arDrone.createClient([options])

返回一个新的Client对象,其中的options包含:

ip:无人机的IP,默认为“192.168.1.1”

frameRate:PngEncoder的帧速率,默认为5

imageSize:PngEncoder生成的图像大小,默认为NULL

client.createREPL():启动交互式界面,其中包含在有效范围内可用的所有客户端方法。另外,client解析为client实例。

client.getPngStream():返回PngEncoder对象,以data事件的形式发出独立的png图像缓冲区。多个调用返回相同的对象。Connection的声明周期由客户端管理。

client.getVideoStream():返回TcpVideoStream对象,以data事件的形式发出原始TCP数据包。多个调用返回相同的对象。Connection的声明周期由客户端管理。

client.takeoff(callback):将内部fly状态设为true,当无人机报告为盘旋状态时,调用callback。

client.land(callback):将内部fly状态设为true,当无人机报告为着陆状态时,调用callback。

client.up(speed) / client.down(speed):控制无人机增加或降低高度,speed值在0至1之间。

client.clockwise(speed) /client.counterClockwise(speed):使无人机旋转,speed值在0至1之间。

client.front(speed) / client.back(speed):控制定位,以摄像头为参考点的水平运动,speed值在0至1之间。

client.left(speed) / client.right(speed):控制转动,以摄像头为参考点的水平运动,speed值在0至1之间。

client.stop():将无人机所有的运动命令设置为0,使其在适当的位置盘旋。

client.calibrate(device_num):要求无人机校准设备,当前AR.Drone固件只支持一个设备校准:设备号为0的磁传感器。该磁传感器只有在无人机飞行时才能被校准,并且会使无人机360度偏航。

client.config(key, value, callback):向无人机发送配置命令,用户需要下载SDK,来获取ARDrone_Developer_Guide.pdf中完整的命令列表。

例如,以下命令会要求无人机发送完整的导航数据:

client.config(‘general:navdata_demo’,'FALSE’);

当无人机接收该配置请求或时间超时时,会调用callback。

或者,也可以传递一个包含以下成员的选项对象:

key:配置键

value:配置值

timeout:等待无人机ACK响应的时间,以毫秒为单位

例如:

var callback = function(err){ if (err) console.log(err); };
client.config({ key: 'general:navdata_demo', value: 'FALSE', timeout: 1000 }, callback);

client.animate(animation,duration)

根据给定的duration(毫秒为单位)执行预定的飞行序列,animation可以为以下值:

['phiM30Deg', 'phi30Deg', 'thetaM30Deg', 'theta30Deg', 'theta20degYaw200deg',
'theta20degYawM200deg', 'turnaround', 'turnaroundGodown', 'yawShake',
'yawDance', 'phiDance', 'thetaDance', 'vzDance', 'wave', 'phiThetaMixed',
'doublePhiThetaMixed', 'flipAhead', 'flipBehind', 'flipLeft', 'flipRight']

例如:

client.animate('flipLeft', 1000);

注:无人机需要比较大的高度和空间执行空翻。

client.animateLeds(animation, hz, duration)

根据给定的hz条件和duration(以秒为单位)执行预定的引导序列,animation可以为以下值:

['blinkGreenRed', 'blinkGreen', 'blinkRed', 'blinkOrange', 'snakeGreenRed',
'fire', 'standard', 'red', 'green', 'redSnake', 'blank', 'rightMissile',
'leftMissile', 'doubleMissile', 'frontLeftGreenOthersRed',
'frontRightGreenOthersRed', 'rearRightGreenOthersRed',
'rearLeftGreenOthersRed', 'leftGreenRightRed', 'leftRedRightGreen',
'blinkStandard']

例如:

client.animateLeds('blinkRed', 5, 2)

client.disableEmergency()

当navdata.droneState.emergencyLanding为0时,将emergencyREF位设成1,可以恢复失去控制的无人机,将红灯更改为绿灯,使其可以重新飞行。当创建更高一级的客户端时,该过程会隐式地完成。

使用以下函数启用演示导航数据:

client.config('general:navdata_demo', 'FALSE');

UdpControl

UdpControl是一个低级API。如果开发人员更倾向于简单的实现,可以参考客户端文档。

可以通过向5556端口发送UDP数据包控制无人机。由于UDP不能保证数据报的顺序和交付,客户端需要重复发送指令,并在每一条指令中包含递增的序列号。

例如,用于takeoff/landing(REF)的命令,序列化为1,参数值为512:

AT*REF=1,512\r

为了减缓这些数据包的创建和发送,该模块使用UdpControl类处理该任务。例如,以下进程可以使无人机起飞并原地盘旋:

var arDrone = require('ar-drone');
var control = arDrone.createUdpControl();

setInterval(function(){
  // The emergency: true option recovers your drone from emergency mode that can
  // be caused by flipping it upside down or the drone crashing into something.
  // In a real program you probably only want to send emergency: true for one
  // second in the beginning, otherwise your drone may attempt to takeoff again
  // after a crash.
  control.ref({fly: true, emergency: true});
  // This command makes sure your drone hovers in place and does not drift.
  control.pcmd();
  // This causes the actual udp message to be send (multiple commands are
  // combined into one message)
  control.flush();
}, 30);

如果要降落,可以向pcmd()方法传递一个参数:

control.pcmd({
  front: 0.5, // fly forward with 50% speed
  up: 0.3, // and also fly up with 30% speed
});

根据以上内容,就可以创建一个简单的程序:

var arDrone = require('ar-drone');
var control = arDrone.createUdpControl();
var start   = Date.now();

var ref  = {};
var pcmd = {};

console.log('Recovering from emergency mode if there was one ...');
ref.emergency = true;
setTimeout(function(){
  console.log('Takeoff ...');

  ref.emergency = false;
  ref.fly       = true;

}, 1000);

setTimeout(function(){
  console.log('Turning clockwise ...');

  pcmd.clockwise = 0.5;
}, 6000);

setTimeout(function(){
  console.log('Landing ...');

  ref.fly = false;
  pcmd = {};
}, 8000);


setInterval(function(){
  control.ref(ref);
  control.pcmd(pcmd);
  control.flush();
}, 30);

UdpControl API

arDrone.createUdpControl([options]) / newarDrone.UdpControl([options])

创建新的包含options的UdpControl实例:

ip:无人机的IP地址,默认为192.168.1.1

port:使用的端口,默认为5556

udpControl.raw(command, [arg1, arg2, ...])

入队原始的AT*命令,如果用户想要完全控制权,这是很有必要的。

例如,起飞指令可以下列形式发送:

udpControl.raw('REF', (1 << 9));

udpControl.ref([options])

入队AT*REF命令,选项为:

fly:设置为true可以起飞或暂停;设置为false可以开始降落或停止,默认为false

emergency: true为设置emergency位,false不设置,默认为false。详情请参考SDK官方指南

udpControl.pcmd([options])

入队AT*PCMD命令,选项为:

front或back:以前置摄像头的方向为参考,前进或后退

left或right:以前置摄像头的方向为参考,向左或向右

up或down:增加或减少高度

clockwise或counterClockwise:绕中心轴旋转

每个选项的值都为速度,值在0至1之间,也可以使用负值,例如,{front: -0.5}等同于{back: 0.5}。

udpControl.flush()

将已入队的命令以UDP数据包的形式发送给无人机。

环境变量

DEFAULT_DRONE_IP

摄像头使用

用户可以使用顶部摄像头和底部摄像头,需要更改配置:

//使用顶部摄像头
client.config('video:video_channel', 0);

//使用底部摄像头
client.config('video:video_channel', 3);

请在下方留下您的评论.加入TG吹水群