User Tools

Site Tools


Sidebar

Launch of Linino.org

wiki:parrot

Control a Parrot AR Drone with Linino

Performing the control of the AR.Drone with the iOS or Android apps is really difficult. The controls are very unstable because the app virtual joystick doesn't have a good sensitivity response. The idea wolud be to use a real joystick instead of the Parrot application itself :

Ingredients:

  • Parrot AR.Drone
  • Arduino Yun
  • Sparkfun Joystick Shield

So, to create an application to control the quadcopter, you need Linino with Node.js and the Ideino development environment on-board. Ideino includes a library for managing the pins of the board in Node.Js. For installing Node.Js and Ideino on the Yun, please refer to this guide: http://wiki.linino.org/doku.php?id=wiki:nodejscript.

After setting up Node.Js and Ideino, we looked around for a node module implementing all the necessary commands to pilot the AR.Drone. We found that the most used is ar-drone. The source code of the ar-drone module is available on GitHub (https://github.com/felixge/node-ar-drone). The ar-drone module comes with a detailed documentation and we have determined the main commands for controlling the AR.Drone :

  • take-off
  • land
  • stop
  • left / right
  • front / back
  • up /down
  • clockwise / counter clockwise

The following picture show how we associate the ar-drone commands with the joystick shield controls :

Note that the Take Off / Landing commands are performed by a single button switch, located under the two potentiometers of the joystick. To start writing the Node.js code in Ideino, we need to setup our environment. The First step is to setup the mcu with a sketch, generally to work with ideino and the ideino-linino-lib you need to load the firmata sketch that allows Linino to comunicate with the board. With ideino-linino-lib are distributed two .hex files :

  • firmata_spi.hex
  • firmata_spi_pullup_enabled.hex

We will use the first one more, but in this case, for the Joystick Shield, we need to use the second one which enables the pullup resistor in the Arduino Yun board. Please take a look at the product page for more details https://www.sparkfun.com/products/9760. To load the .hex file you need to open an ssh connection to your Arduino Yun and then follow the commands below :

ssh root@linino.local
...
cd /opt/ideino-linino/node_modules/ideino-linino-lib/ext/firmata/firmata_spi_pullup_enabled
run-avrdude firmata_spi_pullup_enabled.hex

Then go to the Ideino worspace page via web browser(http://linino.local:2424) (after the root login) and create new project called “drone”, inside which we will write our code to pilot the AR.Drone :

Before start coding, we need to install the ar-drone module. To do so, open the package.json file inside the drone project you have just created, and add the dependence of the ar-drone module. This is the default package.json file :

{
  "name": "hello-world",
  "version": "0.0.1",
  "description": "Ideino example project",
  "author": {
    "name": "Ideino Team"
  }
}

your file should look like this:

{
  "name": "Drone",
  "version": "0.0.1",
  "description": "Controlling Parrot AR.Drone with Linino on Arduino Yun and Joystick Shield",
  "author": {
    "name": "John Doe"
  },
  "dependencies": {
    "ar-drone": "*"
  }
}

you can also write other information like the name and description of the project. Finally, save the package.json file, press the right mouse button on it and click Install. Ideino will run the npm command for you and will install the ar-drone module inside the project directory.

Finally, we are able to write the code to control the drone : inside the “drone” project, create a new file and name it drone-joystick.js :

Import the ar-drone module and create drone object

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

Create a board object with the ideino-linino-lib

var board = require('ideino-linino-lib').Board;

Create the variables representing both the joystick button, controls, and board pins

var btnUP = { pin: board.pin.digital.D4, value : 0 },
    btnDOWN = { pin: board.pin.digital.D5, value : 0 },
    btnCTNCLKWISE = { pin: board.pin.digital.D3, value : 0 },
    btnCLKWISE = { pin: board.pin.digital.D6, value : 0 },
    btnFLY = { pin: board.pin.digital.D2, value : 0 },
    btnLEFTRIGHT = { pin: board.pin.analog.A0, value : 0 },
    btnBACKFRONT = { pin: board.pin.analog.A1, value : 0 },
    led = { pin: board.pin.digital.D13, value : 0 };
 

Finally create the variables for controlling the AR.Drone

var flying = false,
    LRValue = 0,
    BFValue = 0,
    S1 = 0.47,
    S2 = 0.52;

Connection to the Arduino Board

board.connect( function(){
 
//Setting the pins...
 board.pinMode(btnUP.pin, board.MODES.INPUT);
 board.pinMode(btnDOWN.pin, board.MODES.INPUT);
 board.pinMode(btnCTNCLKWISE.pin, board.MODES.INPUT);
 board.pinMode(btnCLKWISE.pin, board.MODES.INPUT);
 board.pinMode(btnFLY.pin, board.MODES.INPUT);
 board.pinMode(led.pin, board.MODES.OUTPUT);

The following analogRead functions have callback that trigger when the joystick is moved

    //LEFT and RIGHT
    board.analogRead(btnLEFTRIGHT.pin,function(data){
       LRValue = data.value / 1000;
 
       if(LRValue >= S1 && LRValue <= S2 ){
           drone.stop();
           board.digitalWrite(led.pin,board.LOW);
       }
       else{
           if(LRValue < S1 )
               drone.left( (S1 - LRValue).toFixed(2));
           else
               drone.right((LRValue - S2).toFixed(2));
 
            board.digitalWrite(led.pin,board.HIGH);      
       }
    });
 
    //BACK and FRONT
    board.analogRead(btnBACKFRONT.pin,function(data){
       BFValue = data.value / 1000;
 
       if(BFValue >= S1 && BFValue <= S2 ){
           drone.stop();
           board.digitalWrite(led.pin,board.LOW);
       }
       else{
           if(BFValue < S1 )
               drone.back((S1 - BFValue).toFixed(2));
           else
               drone.front((BFValue - S2).toFixed(2));
 
            board.digitalWrite(led.pin,board.HIGH);
       }
    });

The following digitalRead functions are associated with the shield Buttons switch

    //TAKE OFF and LANDING
    board.digitalRead(btnFLY.pin,function(data){
        try{
            if(data.value == 0 ){
                board.digitalWrite(led.pin,board.HIGH);
 
                //console.log('cmd');
                if(flying == false){
                    console.log("go take off");
                    drone.takeoff();
 
                }
                else{
                    console.log("go landing");
                    drone.stop();    
                    drone.land(); 
                }
                flying = !flying;
            }
            else
                board.digitalWrite(led.pin,board.LOW);
        }
        catch(err){
            console.log(err.message);
        }
    });
 
    //CLOCKWISE
    board.digitalRead(btnCLKWISE.pin,function(data){
        if(data.value == 0){
            board.digitalWrite(led.pin,board.HIGH);
            drone.clockwise(0.3);            
        }
        else{
            drone.stop();
            board.digitalWrite(led.pin,board.LOW);
        }
    });
 
    //COUNTER CLOCKWISE
    board.digitalRead(btnCTNCLKWISE.pin,function(data){
         if(data.value == 0){
             board.digitalWrite(led.pin,board.HIGH);
            drone.counterClockwise(0.3);
         }
        else{
            board.digitalWrite(led.pin,board.LOW);
            drone.stop();
        }         
    });
 
    //UP
    board.digitalRead(btnUP.pin,function(data){
        if(data.value == 0){
            board.digitalWrite(led.pin,board.HIGH);
            drone.up(0.3);
        }
        else{
            board.digitalWrite(led.pin,board.LOW);
            drone.stop();
        }        
    });
 
    //DOWN
    board.digitalRead(btnDOWN.pin,function(data){
         if(data.value == 0){
             board.digitalWrite(led.pin,board.HIGH);
            drone.down(0.3);
         }
        else{
            board.digitalWrite(led.pin,board.LOW);
            drone.stop();
        }         
    });
 
});

Now that the code is ready to run, you need to put the application in autorun mode, this means that the application will run automatically at the next startup/reboot of Linino. Right mouse click on drone-joystick.js and click “Autorun”.

Finally you need to “tell” your Arduino Yun to interact with the AR.Drone WiFi hotspot. To do that, please connect to the luci administration panel of your Arduino Yun via web browser. Wait a few minutes for the WiFi reconfiguration, system restart and for the autorun your Node.Js file as well. When your file is started you will see a 1 Hz blink of the L13 led (the red one) of the Arduino Yun board.

Go Flying !

/var/www/wiki.linino.org/data/pages/wiki/parrot.txt · Last modified: 2014/09/10 04:58 by arturo

2014 © dog hunter llc and the Linino Community. Linino.org is a dog hunter sponsored community project. Credits