Voos autônomos. Como programar AR.Drone (Parte 1): ardrone-autonomy
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
- https://code.google.com/p/v8/
- http://www.ibm.com/developerworks/br/library/os-nodejs/
- https://github.com/felixge/node-ar-drone
- http://www2.decom.ufop.br/imobilis/?p=1642
- http://odesenvolvedor.andafter.org/publicacoes/como-instalar-o-nodejs-no-ubuntu-2.html
- https://npmjs.org/
- http://nodejs.org/api/index.html
- http://www.installion.co.uk/ubuntu/precise/universe/n/npm/pt/install.html
- http://nodebr.com/o-que-e-a-npm-do-nodejs/
- https://gist.github.com/isaacs/579814
- http://eschnou.github.io/ardrone-autonomy/
- https://github.com/eschnou/ardrone-autonomy
- http://diydrones.com/profiles/blogs/autonomous-flight-for-the-ardrone-implemented-in-javascript
- 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/
Muito bom este artigo. Obrigado por tê-lo escrito. Abraços.