Project tutorial
Control a Parrot AR Drone with Linino

Control a Parrot AR Drone with Linino

Use a real joystick to control a Parrot AR Drone.

  • 6,313 views
  • 2 comments
  • 18 respects

Components and supplies

About this project

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 hasn’t a good sensitivity response. The idea was to use a real joystick instead of the Parrot application itself:

Warning: embedding parts within the project story has been deprecated. To edit, remove or add more parts, go to the "Hardware" tab. To remove this list from the story, click on it to trigger the context menu, then click the trash can button (this won't delete it from the "Hardware" tab).
Parrot AR.Drone
Ard yun
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, that include 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

https://github.com/felixge/node-ar-drone

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). ar-drone module comes with a detailed documentation from which I deduced that 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 write 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

The most used is the first one, but in this case, for the Joystick Shield, we need to use the second one which enables the pullup resistor in the Arduino board. See 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 execute the commands below in the linux shell :

$ 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 workspace page via web browser (http://linino.local:2424) (after the root login) and create new project called “drone”, inside that we write our code to pilot the ar.drone.

Before start coding, we need to install the ar-drone module. To do that 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:

Code

Warning: Embedding code files within the project story has been deprecated. To edit this file or add more files, go to the "Software" tab. To remove this file from the story, click on it to trigger the context menu, then click the trash can button (this won't delete it from the "Software" tab).

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

Your file should look like this:

Code

Warning: Embedding code files within the project story has been deprecated. To edit this file or add more files, go to the "Software" tab. To remove this file from the story, click on it to trigger the context menu, then click the trash can button (this won't delete it from the "Software" tab).

{
  "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 informations 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 npm command for you and will install the ar-drone module inside the project directory.

Finally, we are able to write the code to controls 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 linino = require('ideino-linino-lib'),
    board = new linino.Board();


Create variables that representing both the joystick buttons and controls, and board pins:

Code

Warning: Embedding code files within the project story has been deprecated. To edit this file or add more files, go to the "Software" tab. To remove this file from the story, click on it to trigger the context menu, then click the trash can button (this won't delete it from the "Software" tab).

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 };

Create variables for controlling the AR.Drone:

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


Connection to the Arduino Board:

Code

Warning: Embedding code files within the project story has been deprecated. To edit this file or add more files, go to the "Software" tab. To remove this file from the story, click on it to trigger the context menu, then click the trash can button (this won't delete it from the "Software" tab).

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 connect to the AR.Drone wifi hotspot, to do that connect to the luci administration panel of you Arduino Yun via web browser. Wait a few minute for the wifi reconfiguration, system restart and for autorun your Node.js file. When your file is started you will see a 1 second fast blink of the on board led (L13) of the Arduino Yun.

Go fly!

Code

code.txtJSON
{
  "name": "hello-world",
  "version": "0.0.1",
  "description": "Ideino example project",
  "author": {
  "name": "Ideino Team"
  }
}
code.txtJSON
{
  "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": "*"
  }
}
code.txtJavaScript
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 };
code.txtJavaScript
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();
        }         
    });

});
Github
https://github.com/felixge/node-ar-drone

Comments

Similar projects you might like

AR DRONE and 1SHEELD - Discover the world around your drone

Project tutorial by OMEGA D2

  • 32,853 views
  • 15 comments
  • 180 respects

Linino Christmas with Lifx

Project tutorial by Giando

  • 1,193 views
  • 0 comments
  • 1 respect

Mind Control Drone

Project tutorial by WesleyCMD

  • 49,528 views
  • 43 comments
  • 185 respects

Ask Wolfram and Linino Answers!

Project tutorial by Giando

  • 679 views
  • 1 comment
  • 1 respect

Home-made Nest Protect with Linino

Project tutorial by Giando

  • 1,227 views
  • 0 comments
  • 3 respects

Servo Control with TV Remote Control

Project showcase by eldo85

  • 11,159 views
  • 5 comments
  • 32 respects
Add projectSign up / Login