Voos autônomos. Como programar AR.Drone (Parte 1): ardrone-autonomy

On 4 de fevereiro de 2014 by Fernando Fernandes

parrot_02

Introdução programar AR.Drone

programar AR.Drone: Desde que foi lançado e passou a ser adotado como plataforma de pesquisa por grupos em universidades ou por entusiastas de tecnologia e veículos aéreos não tripulados (VANTs), inúmeros trabalhos têm sido reportados. Muitos deles open source e com o intuito de tornar o Parrot AR.Drone capaz de realizar voos autônomos. Autônomo aqui significa realizar voos sem qualquer intervenção humana.

A primeira parte do que pretende ser um conjunto de posts sobre o tema, vem mostrar como fazer uso de um ambiente para desenvolvimento de aplicações de rede escaláveis e bibliotecas desenvolvidas nesse ambiente, para  programar  AR.Drone, elaborar e executar missões de voo autônomas.

Node.js

O Node.js é uma plataforma construída sobre a engine JavaScript do Google Chrome (V8 JavaScript), para o desenvolvimento mais rápido e fácil de aplicações de rede escaláveis, indicadas para aplicações de tempo real. Esse framework tem como paradigma a programação orientada a eventos e não permite bloqueio em chamadas de E/S (leia mais em O que é exatamente o Node.js? Um servidor pronto para codificar).

Como o Node.js é um projeto open source, encontram-se disponíveis para download no site oficial, tanto o código-fonte para estudo e utilização, quanto os binários para Windows, Linux e Mac.

A biblioteca node-ar-drone

A biblioteca node-ar-drone é a implementação de um cliente Node.js para  programar AR.Drone 2.0. Basicamente, é uma implementação do protoloco de comunicação usado pelo Parrot AR.Drone 2.0. O post AR.Drone: Comunicação dá uma introdução sobre esse protocolo, descrevendo como o AR.Drone e um dispositivo de controle se comunicam.

A instalação mencionada aqui pressupõe o uso do Ubuntu 12.04 e que o Node.js já tenha sido instalado. Se houver problemas para instalar o Node.js, a sugestão é dar uma boa lida numa descrição disponível em Como Instalar o Node.js no Ubuntu. Ainda é pressuposto que gerenciador de pacotes do Node.js, o Node Package Manager, também já tenha sido instalado.

A maneira mais simples de instalar o Node.js e o gerenciador de pacotes NPM se encontra neste link.

Neste outro link, também se encontra um bom passo-a-passo para a instalação do NPM no Ubuntu 12.04 LTS. Atendidas essas condições, basta proceder a um dos seguintes passos, digitando na linha de comando de um terminal, para instalar o módulo ‘ar-drone’:

[sourcecode language=”powershell”]
fsaf@ubuntu:~$ npm install git://github.com/felixge/node-ar-drone.git
[/sourcecode]

Ou

[sourcecode language=”powershell”]
fsaf@ubuntu:~$ npm install ar-drone
[/sourcecode]

Leia mais sobre o NPM em O que é a npm do Node.js. Diferentes maneiras de instalar o Node.js e o NPM estão descritas em isaacs/node-and-npm-in-30-seconds.sh.

Agora que já temos o ambiente pronto, vamos falar um pouco sobre as API disponíveis no pacote node-ar-drone.

A API Client é um módulo em mais alto nível de node-ar-drone, que tenta dar suporte a todas as características do AR.Drone, deixando o seu uso mais fácil.

Para testar um exemplo simples de implementação, utilizando essa API, podemos criar um arquivo JavaScript, chamado repl.js e digitar o seguinte código:

[sourcecode language=”javascript”]
var arDrone = require(‘ar-drone’);
var client  = arDrone.createClient();

client.createRepl();
[/sourcecode]

Rodando esta aplicação simples, teremos um cliente capaz de se comunicar e enviar comando ao AR.Drone via pacotes UDP, na porta 5556:

[sourcecode language=”powershell”]
fsaf@ubuntu:~$ node repl.js
[/sourcecode]

Um prompty é exibido e podemos digitar os comandos decolagem, aterrissagem, giro no sentido horário ou anti-horário, entre outros comandos disponíveis:

[sourcecode language=”powershell”]
drone>

drone> takeoff()
true

drone> clockwise(0.5)
0.5

drone> land()
true

[/sourcecode]

Ao invés de usarmos uma aplicação cliente para enviar comandos via terminal, podemos programar códigos capazes de enviar a mesma sequencia de comandos digitados no terminal:

[sourcecode language=”javascript”]
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();
});
[/sourcecode]

A API Client:

Segue uma breve descrição dos principais métodos da API Client:

* arDrone.createClient([options]): retorna uma nova instância de objeto do tipo Client. As opções incluem: o endereço IP do drone (que por padrão é ‘192.168.1.1’); a frameRate: que corresponde à taxa com que as imagens da câmera são tomadas (relativa ao PngEncoder,  o valor padrão é 5); o imageSize: que é o tamanho da imagem produzida por Encoder (o padrão é null). Não vamos detalhar essas opções aqui, mas se você tiver interesse, consulte a documentação em …

* client.createREPL(): carrega uma interface interativa (o prompty mencionado anteriormente!) com todos os métodos cliente disponíveis. A partir desse prompty, você pode enviar commandos ao drone (ex.: takeoff(), land(), clockwise(0.5), etc.).

* client.takeoff(callback): Define o estado interno de voo para TRUE, fazendo o AR.Drone decolar e pairar.

* client.land(callback): Define o estado interno de voo para FALSE, fazendo o AR.Drone aterrissar.

* client.up(speed) / client.down(speed): Faz o drone ganhar ou perder altitude. O parâmetro speed pode ser um valor entre 0 e 1 e corresponde à velocidade com que o drone ganha ou perde altitude.

* client.clockwise(speed) / client.counterClockwise(speed): Faz com que o drone gire em torno do próprio eixo, no sentido horário ou no sentido anti-horário. O parâmetro speed é similar ao do item anterior.

* client.front(speed) / client.back(speed): Controla o ângulo pitch, que permite o movimento horizontal para frente ou para trás usando a camera frontal como ponto de referência.

* client.left(speed) / client.right(speed): Controla o ângulo roll, que permite o movimento horizontal para direita ou para esquerda usando a câmera frontal como ponto de referência.

* client.stop(): Define todos os comandos de movimento para zero, fazendo com que o drone fique parado, pairando num mesmo lugar.

A biblioteca ardrone-autonomy

A biblioteca ardrone-autonomy é baseada no módulo node-ar-drone. Inteiramente desenvolvida em JavaScript com intuito de permitir a realização de vôos autônomos e  programar AR.Drone, essa biblioteca implementa algoritmos de controle (PID controller), de auxílio à navegação (Extended Kalman Filter, Tag detection) e planejamento de missões autônomas. Segundo o autor, seu objetivo foi oferecer uma plataforma fácil para a aprendizagem em robótica probabilística e visão computacional.

Vejamos como instalá-la:

O primeiro passo é fazer com que o gerenciador de pacotes procure e registre o endereço do repositório do pacote. Em seguida, usamos o NPM para instalar o pacote.

[sourcecode language=”powershell”]
fsaf@ubuntu:~$ npm search ardrone-autonomy
fsaf@ubuntu:~$ npm install ardrone-autonomy
[/sourcecode]

O código a seguir (‘ardrone-autonomy/examples/square.js’) é exemplo de uma missão simples usando a biblioteca ardrone-autonomy:

[sourcecode language=”javascript”]
var autonomy = require(‘ardrone-autonomy’);
var mission  = autonomy.createMission();

mission.takeoff()
.zero()       // Sets the current state as the reference
.altitude(1)  // Climb to altitude = 1 meter
.forward(2)
.right(2)
.backward(2)
.left(2)
.hover(1000)  // Hover in place for 1 second
.land();

mission.run(function (err, result) {
if (err) {
console.trace("Oops, something bad happened: %s", err.message);
mission.client().stop();
mission.client().land();
} else {
console.log("Mission success!");
process.exit(0);
}
});
[/sourcecode]

A API Mission:

Segue uma breve descrição de cada método da API Mission. A combinação dos métodos permite que missões de voo mais elaborados possam ser testadas.

* mission.log(path): Faz um log dos dados da missão, no formato csv. É útil para debugar/plotar o estado e o comportamento do controlador.

* mission.run(callback): Executa a missão. A função de callback tem a forma function(err,result) e será chamada em caso de erro ou no fim da missão.

* mission.takeoff(): adiciona uma etapa de decolagem à missão.

* mission.forward/backward/left/right/up/down(distance): Adiciona um movimento à missão. O drone se moverá na direção dada pela distância (em metros), antes de proceder ao passo seguinte. O drone também tentará manter todos os outros graus de liberdade.

* mission.altitude(height): Adiciona uma etapa de altitude na missão. O drone vai subir até a altura dada, antes de seguir para o próximo passo.

* mission.cw/ccw(angle): Adiciona um passo de rotação à missão. O drone rotacionará pelo ângulo dado (em graus) antes de proceder ao próximo passo.

* mission.hover(delay): Adiciona um passo que diz para o drone pairar, por um tempo de atraso dado (em ms).

* mission.wait(delay): Adiciona um passo de espera. O tempo é dado em ms.

* mission.go(position): adiciona um movimento à missão. O drone irá para a posição dada antes do próximo passo. A posição é uma saída para o Controlador tal como {x: 0, y: 0, z: 1, yaw: 90}

* mission.task(function(callback){…}): adiciona uma tarefa à missão. executará a função chamada antes do próximo passo. Um argumento de callback é passado à função, que deveria ser chamada quando a tarefa é feita.

* mission.taskSync(function): adicionar uma tarefa à missão. Executará a função antes do próximo passo.

[sourcecode language=”javascript”]
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);
[/sourcecode]

* mission.zero(): adiciona uma referência de posição inicial à missão. Isto setará a posição e a orientação atuais como estado base para o Filtro de Kalman (isto é, {x: 0. y: 0, yaw: 0}). Se você não estiver usando uma etiqueta com sua posição base, é uma boa idéia chamar essa função após decolar.

Pronto! Se você conseguiu instalar e configurar o ambiente como descrito acima e tiver em mãos um AR.Drone 2.0 (tudo indica que essa ferramenta também é compatível com o modelo 1.0!), você já pode dar os primeiros passos para brincar com a ferramenta e criar seus próprios planos de voo.

O autor da biblioteca só sugere que os primeiros testes sejam realizados num ambiente indoor controlado, para fins de garantia da segurança das pessoas e integridade do drone.

Nos próximos posts, tentaremos mostrar outras ferramentas e projetos que já tiveram sucesso no desafio de tornar o AR.Drone autônomo e  programar AR.Drone.

Referências

  1. https://code.google.com/p/v8/
  2. http://www.ibm.com/developerworks/br/library/os-nodejs/
  3. https://github.com/felixge/node-ar-drone
  4. http://www2.decom.ufop.br/imobilis/?p=1642
  5. http://odesenvolvedor.andafter.org/publicacoes/como-instalar-o-nodejs-no-ubuntu-2.html
  6. https://npmjs.org/
  7. http://nodejs.org/api/index.html
  8. http://www.installion.co.uk/ubuntu/precise/universe/n/npm/pt/install.html
  9. http://nodebr.com/o-que-e-a-npm-do-nodejs/
  10. https://gist.github.com/isaacs/579814
  11. http://eschnou.github.io/ardrone-autonomy/
  12. https://github.com/eschnou/ardrone-autonomy
  13. http://diydrones.com/profiles/blogs/autonomous-flight-for-the-ardrone-implemented-in-javascript
  14. 14.   http://pt.wikipedia.org/wiki/Filtro_de_Kalman

Outros links relacionados:
http://diydrones.com/profiles/blogs/turning-the-parrot-ardrone
http://udgwebdev.com/nodejs/
http://nodebr.com/o-que-e-node-js/

One Response to “Voos autônomos. Como programar AR.Drone (Parte 1): ardrone-autonomy”

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *