Uma implementação dos protocolos de rede usados pelo Parrot AR Drone 2.0. Parece que 1,0 drones também são compatíveis.
Instale via Github para obter a versão mais recente :
npm install git://github.com/felixge/node-ar-drone.git
Ou, se você estiver bem com a falta de algumas coisas de ponta, vá para o NPM:
npm install ar-drone
O AR Drone é um quadcopter acessível, mas surpreendentemente capaz. O próprio drone executa um firmware proprietário que pode ser controlado via WiFi usando o aplicativo móvel oficial Freeflight (disponível para iOS e Android).
Ao contrário do firmware, o protocolo do cliente está aberto e o Parrot publica um SDK (inscrição necessária para baixar), incluindo uma boa quantidade de documentação e código C. Seu público -alvo parece ser desenvolvedores móveis que podem usar este SDK para criar jogos e outros aplicativos para que as pessoas se divirtam mais com seus drones.
No entanto, o protocolo também pode ser usado para receber dados de vídeo e sensor, permitindo que os desenvolvedores escrevam programas autônomos para a próxima revolução do robô.
Este módulo ainda está sob desenvolvimento pesado; portanto, não se surpreenda se encontrar alguma funcionalidade ausente ou sem documentos.
No entanto, as peças documentadas são testadas e devem funcionar bem na maioria das partes.
Este módulo expõe uma API de cliente de alto nível que tenta suportar todos os recursos do drone, e facilitando o uso.
A melhor maneira de começar é criar um arquivo repl.js
como este:
var arDrone = require ( 'ar-drone' ) ;
var client = arDrone . createClient ( ) ;
client . createRepl ( ) ;
Usando este REPL, você deve se divertir:
$ 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
Agora você pode escrever um programa autônomo que faça o mesmo:
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 ( ) ;
} ) ;
Ok, mas e se você quiser fazer seu drone interagir com alguma coisa? Bem, você pode começar olhando os dados do sensor:
client . on ( 'navdata' , console . log ) ;
Nem tudo isso é tratado pela biblioteca do cliente ainda, mas você deve pelo menos poder receber dados droneState
e demo
.
Um bom desafio inicial pode ser tentar voar para uma certa altitude com base na propriedade navdata.demo.altitudeMeters
.
Depois de conseguir isso, você pode tentar olhar para a imagem da câmera. Aqui está uma maneira simples de obter isso como pngbuffers (requer uma versão recente do FFMPEG encontrada no seu $PATH
):
var pngStream = client . getPngStream ( ) ;
pngStream . on ( 'data' , console . log ) ;
Seu primeiro desafio pode ser expor essas imagens PNG como um servidor web http nó. Depois de fazer isso, tente alimentá -los no módulo OpenCV.
Retorna um novo objeto Client
. options
incluem:
ip
: O IP do drone. Padrões para '192.168.1.1'
.frameRate
: a taxa de quadros do pngencoder. Padrões para 5
.imageSize
: o tamanho da imagem produzido pelo pngencoder. Padrões para null
. Inicia uma interface interativa com todos os métodos de cliente disponíveis no escopo ativo. Além disso, client
resolve para a própria instância client
.
Retorna um objeto PngEncoder
que emite buffers de imagem PNG individuais como eventos 'data'
. Várias chamadas para esse método retornam o mesmo objeto. Ciclo de vida da conexão (por exemplo, reconectamento no erro) é gerenciado pelo cliente.
Retorna um objeto TcpVideoStream
que emite pacotes TCP brutos como eventos 'data'
. Várias chamadas para esse método retornam o mesmo objeto. Ciclo de vida da conexão (por exemplo, reconectamento no erro) é gerenciado pelo cliente.
Define o estado fly
interna como true
, callback
é invocado depois que o drone relata que está pairando.
Define o estado fly
interna como false
, callback
é invocado depois que o drone relata que ele chegou.
Faz o ganho do drone ou reduzir a altitude. speed
pode ser um valor de 0
a 1
.
Faz com que o drone gire. speed
pode ser um valor de 0
a 1
.
Controla o tom, que um movimento horizontal usando a câmera como ponto de referência. speed
pode ser um valor de 0
a 1
.
Controla o rolo, que é um movimento horizontal usando a câmera como ponto de referência. speed
pode ser um valor de 0
a 1
.
Define todos os comandos do movimento de drones como 0
, tornando -o efetivamente pairando no lugar.
Pede ao drone para calibrar um dispositivo. Embora o firmware AR.Drone suporta apenas um dispositivo que pode ser calibrado. Esta função também inclui FTRIM.
O magnetômetro
Dispositivo: 0
O magnetômetro só pode ser calibrado enquanto o drone está voando, e a rotina de calibração faz com que o drone a guinasse no lugar 360 graus.
Ftrim
Dispositivo: 1
O FTRIM redefine essencialmente a guinada, a inclinação e o rolo para 0. Seja muito cauteloso ao usar essa função e apenas calibre enquanto na superfície plana. Nunca use enquanto voa.
Envia um comando de configuração para o drone. Você precisará fazer o download do Drone SDK para encontrar uma lista completa de comandos no ARDrone_Developer_Guide.pdf
.
Por exemplo, este comando pode ser usado para instruir o drone a enviar todos os dados do NAV.
client . config ( 'general:navdata_demo' , 'FALSE' ) ;
callback
é chamado depois que o drone reconhece a solicitação de configuração ou se ocorrer um tempo limite.
Como alternativa, você pode passar um objeto de opções que contém o seguinte:
key
: a tecla de configuração a ser definida.value
: o valor de configuração a ser definido.timeout
: o tempo, em milissegundos, para esperar por um ACK do drone.Por exemplo:
var callback = function(err) { if (err) console.log(err); };
client.config({ key: 'general:navdata_demo', value: 'FALSE', timeout: 1000 }, callback);
Executa uma sequência de vôo pré-programada por uma determinada duration
(em MS). animation
pode ser um dos seguintes:
[ 'phiM30Deg' , 'phi30Deg' , 'thetaM30Deg' , 'theta30Deg' , 'theta20degYaw200deg' ,
'theta20degYawM200deg' , 'turnaround' , 'turnaroundGodown' , 'yawShake' ,
'yawDance' , 'phiDance' , 'thetaDance' , 'vzDance' , 'wave' , 'phiThetaMixed' ,
'doublePhiThetaMixed' , 'flipAhead' , 'flipBehind' , 'flipLeft' , 'flipRight' ]
Exemplo:
client . animate ( 'flipLeft' , 1000 ) ;
Observe que o drone precisará de uma boa quantidade de altitude e espaço para realizar um flip. Portanto, tenha cuidado!
Executa uma sequência de LED pré-programada na frequência e duration
hz
(em segundo!). animation
pode ser um dos seguintes:
[ 'blinkGreenRed' , 'blinkGreen' , 'blinkRed' , 'blinkOrange' , 'snakeGreenRed' ,
'fire' , 'standard' , 'red' , 'green' , 'redSnake' , 'blank' , 'rightMissile' ,
'leftMissile' , 'doubleMissile' , 'frontLeftGreenOthersRed' ,
'frontRightGreenOthersRed' , 'rearRightGreenOthersRed' ,
'rearLeftGreenOthersRed' , 'leftGreenRightRed' , 'leftRedRightGreen' ,
'blinkStandard' ]
Exemplo:
client . animateLeds ( 'blinkRed' , 5 , 2 )
Faz com que o bit de referência de emergência seja definido como 1 até que navdata.droneState.emergencyLanding
terreno da emergência seja 0. Isso recupera um drone que virou e está mostrando que as luzes vermelhas são voadoras novamente e mostram luzes verdes. Também é feito implicitamente ao criar um novo cliente de alto nível.
Um cliente emitirá os eventos desembarcados, pairando, voando, aterrissando, bateria e altitudechange, desde que a Demo Navdata estivesse ativada.
Para ativar a demonstração de uso de Navdata
client . config ( 'general:navdata_demo' , 'FALSE' ) ;
Veja documentação para o objeto navadata
Esta é uma API de baixo nível. Se você preferir algo mais simples, consulte os documentos do cliente.
O drone é controlado enviando pacotes UDP na porta 5556. Como o UDP não garante pedidos ou entrega de mensagens, os clientes devem enviar repetidamente suas instruções e incluir um número de sequência de incremento com cada comando.
Por exemplo, o comando usado para decolagem/aterrissagem (ref), com um número de sequência de 1, e um parâmetro de 512 (decolagem) se parece com o seguinte:
AT*REF=1,512r
Para facilitar a criação e o envio desses pacotes, este módulo expõe uma classe UdpControl
lidando com essa tarefa. Por exemplo, o programa a seguir fará com que seu drone decolgue e passe o mouse no lugar.
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 ) ;
Agora que você está no ar, você pode voar passando um argumento para o método pcmd()
:
control . pcmd ( {
front : 0.5 , // fly forward with 50% speed
up : 0.3 , // and also fly up with 30% speed
} ) ;
É isso! Uma lista completa de todas as opções pcmd()
pode ser encontrada nos documentos da API abaixo.
Com o que você aprendeu até agora, você pode criar um programa simples como este:
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 ) ;
Cria uma nova instância do UDPControl, onde options
podem incluir:
ip
: O endereço IP do drone, padrão para '192.168.1.1'
.port
: a porta para usar, padrão para 5556
. Enquina um comando bruto AT*
. Isso é útil se você deseja controle total.
Por exemplo, instruções de decolagem são enviadas assim:
udpControl . raw ( 'REF' , ( 1 << 9 ) ) ;
Enquina um comando AT*REF
, as opções são:
fly
: Defina isso como true
para decolagem / permanecendo no ar, ou false
para iniciar pouso / permanecer no chão. Padrões para false
.emergency
: defina isso como true
para definir o bit de emergência ou false
para não defini -lo. Detalhes sobre isso podem ser encontrados no guia oficial do SDK. Padrões para false
. Enquina um comando AT*PCMD
(Progressive), as opções são:
front
ou back
: Voe em direção ou para longe da direção da câmera frontal.left
ou/ right
: voe em direção à esquerda ou à direita da câmera frontal.up
ou down
: ganha ou reduza a altitude.clockwise
ou counterClockwise
: gire ao redor do eixo central. Os valores para cada opção são a velocidade a ser usada para a operação e podem variar de 0 a 1. Você também pode usar valores negativos como {front: -0.5}
, que é o mesmo que {back: 0.5}
.
Envia todos os comandos envolvidos como um pacote UDP para o drone.
@Todo documente a API de vídeo de baixo nível.
@Todo documente a API NAVDATA de baixo nível.
Você pode acessar a câmera da cabeça e a câmera inferior, basta alterar a configuração:
// access the head camera
client . config ( 'video:video_channel' , 0 ) ;
// access the bottom camera
client . config ( 'video:video_channel' , 3 ) ;