From 0c8412fe40ea247037b70dfcb46955dbef4db919 Mon Sep 17 00:00:00 2001 From: fabito Date: Wed, 28 May 2014 17:34:27 -0300 Subject: [PATCH 1/7] Sample robot integrating leap motion and Parrot ARDrone 2.0 through cylon --- examples/leap_ardrone/leap_ardrone.js | 255 ++++++++++++++++++++ examples/leap_ardrone/leap_ardrone.markdown | 37 +++ 2 files changed, 292 insertions(+) create mode 100644 examples/leap_ardrone/leap_ardrone.js create mode 100644 examples/leap_ardrone/leap_ardrone.markdown diff --git a/examples/leap_ardrone/leap_ardrone.js b/examples/leap_ardrone/leap_ardrone.js new file mode 100644 index 0000000..c7dfc17 --- /dev/null +++ b/examples/leap_ardrone/leap_ardrone.js @@ -0,0 +1,255 @@ +/* + * leap_ardrone.js + * + * Written by Giuliano Sposito and Fábio Uechi + * Copyright (c) 2013-2014 CI&T Software + * Licensed under the Apache 2.0 license. +*/ + +Cylon = require('cylon'); + +var lastS = 0; +var handStartPosition = []; +var handStartDirection = []; +var UP_CONTROL_THRESHOLD = 50; +var UP_SPEED_FACTOR = 0.01; +var SWIPE_THRESHOLD = 30; +var CIRCLE_THRESHOLD = 1.5; +var DIRECTION_THRESHOLD = 0.25; +var DIRECTION_SPEED_FACTOR = 0.05; +var TURN_SPEED = 0.5; +var TURN_TRESHOLD = 0.2; +var TURN_SPEED_FACTOR = 2.0; + +Cylon.robot({ + + connections: [ + { name: 'leapmotion', adaptor: 'leapmotion', port: '127.0.0.1:6437' }, + { name: 'ardrone', adaptor: 'ardrone', port: '192.168.1.1' }, + { name: 'keyboard', adaptor: 'keyboard' } + ], + + devices: [ + { name: 'drone', driver: 'ardrone', connection:'ardrone' }, + { name: 'leapmotion', driver: 'leapmotion', connection:'leapmotion' }, + { name: 'keyboard', driver: 'keyboard', connection:'keyboard'} + ], + + work: function(my) { + + //KEYBOARD + + my.keyboard.on('right', function(key) { + console.log("RIGHT"); + my.drone.rightFlip(); + }); + + my.keyboard.on('left', function(key) { + console.log("LEFT"); + my.drone.leftFlip(); + }); + + my.keyboard.on('up', function(key) { + console.log("UP"); + my.drone.frontFlip(); + }); + + my.keyboard.on('down', function(key) { + console.log("DOWN"); + my.drone.backFlip(); + }); + + my.keyboard.on('w', function(key) { + console.log("key(w): my.drone.wave()"); + my.drone.wave(); + }); + + // EMERGENCE KEYS + my.keyboard.on('s', function(key) { + console.log("key(S): my.drone.stop()"); + my.drone.stop(); + }); + + my.keyboard.on('l', function(key) { + console.log("key(L): my.drone.land()"); + my.drone.land(); + }); + + + + // HAND + my.leapmotion.on('hand', function(hand) { + + // detecta abertua de mão ==> ATIVA COMANDO DE MDAnielOVIMENTO + if (hand.s>1.5 && lastS<=1.5) { + console.log('Direction Motion Control'); + handStartPosition = hand.palmPosition; + handStartDirection = hand.direction; + console.log(); + }; + + //console.log(hand); + + // TURNS + if(hand.s>1.5 && Math.abs(handStartDirection[0]-hand.direction[0]) > TURN_TRESHOLD ) { + var signal = handStartDirection[0]-hand.direction[0]; + var value = (Math.abs(handStartDirection[0]-hand.direction[0])-TURN_TRESHOLD)*TURN_SPEED_FACTOR; + + if (signal>0){ + my.drone.counterClockwise(value); + console.log('turn left: CCW('+ value +')'); + } + + if (signal<0){ + my.drone.clockwise(value); + console.log('turn right: CW('+ value +')'); + } + + } + + // UP and DOWN + if (hand.s>1.5 && Math.abs(hand.palmPosition[1]-handStartPosition[1]) > UP_CONTROL_THRESHOLD) { + + var signal = (hand.palmPosition[1]-handStartPosition[1]) >= 0 ? 1 : -1; + var value = Math.round(Math.abs((hand.palmPosition[1]-handStartPosition[1]))-UP_CONTROL_THRESHOLD) * UP_SPEED_FACTOR; + + if (signal>0) { + my.drone.up(value); + console.log('my.drone.up('+value+')'); + }; + + if (signal<0) { + my.drone.down(value); + console.log('my.drone.down('+value+')'); + } + + } + + // DIRECTION FRONT/BACK + if (hand.s>1.5 && (Math.abs(hand.palmNormal[2])>DIRECTION_THRESHOLD)) { + if (hand.palmNormal[2]>0) { + var value = Math.abs(Math.round( hand.palmNormal[2]*10 + DIRECTION_THRESHOLD )*DIRECTION_SPEED_FACTOR); + my.drone.forward( value ); + console.log ('my.drone.forward(' + value + ')'); + }; + + if (hand.palmNormal[2]<0) { + var value = Math.abs(Math.round( hand.palmNormal[2]*10 - DIRECTION_THRESHOLD )*DIRECTION_SPEED_FACTOR); + my.drone.back( value ); + console.log ('my.drone.back(' + value + ')'); + }; + } + + // DIRECTION LEFT/RIGHT + if (hand.s>1.5 && (Math.abs(hand.palmNormal[0])>DIRECTION_THRESHOLD)) { + if (hand.palmNormal[0]>0) { + var value = Math.abs(Math.round( hand.palmNormal[0]*10 + DIRECTION_THRESHOLD )*DIRECTION_SPEED_FACTOR); + my.drone.left( value ); + console.log ('my.drone.left(' + value + ')'); + }; + + if (hand.palmNormal[0]<0) { + var value = Math.abs(Math.round( hand.palmNormal[0]*10 - DIRECTION_THRESHOLD )*DIRECTION_SPEED_FACTOR); + my.drone.right( value ); + console.log ('my.drone.right(' + value + ')'); + }; + } + + // AUTO FREEZE + if ( hand.s>1.5 && // mão aberta + (Math.abs(hand.palmNormal[0]) 1.5) { // mão fechada + console.log("my.drone.stop() !!!"); + my.drone.stop(); + } + + lastS = hand.s; + + }); + + // GESTOS + my.leapmotion.on('gesture', function(gesture) { + + if (gesture.type=='swipe' && gesture.state=='stop'){ + + deltaX = gesture.position[0]-gesture.startPosition[0]; + deltaY = gesture.position[1]-gesture.startPosition[1]; + deltaZ = gesture.position[2]-gesture.startPosition[2]; + + var amplitude = Math.abs(Math.max(Math.max(deltaX, deltaY),deltaZ)); + + if (amplitude>SWIPE_THRESHOLD) { + + if (Math.abs(deltaX) > Math.abs(deltaY) && Math.abs(deltaX) > Math.abs(deltaZ)) { + //console.log('swipe X: ' + deltaX); // drone flip left/right + if (deltaX>0){ + my.drone.clockwise(TURN_SPEED); + console.log('swipe right: my.drone.clockwise('+TURN_SPEED+')'); + //my.drone.animate('flipRight',1000); + //my.drone.rightFlip(); + }; + + if (deltaX<0){ + my.drone.counterClockwise(TURN_SPEED); + console.log('swipe left: my.drone.counterClockwise('+TURN_SPEED+')'); + //my.drone.animate('flipLeft',1000); + //my.drone.leftFlip(); + } + } + + if (Math.abs(deltaY) > Math.abs(deltaX) && Math.abs(deltaY) > Math.abs(deltaZ)) { + console.log('swipe Y: ' + deltaY); // drone takeoff/land + if (deltaY>0) { + console.log('swipe up: no command'); + //my.drone.takeoff(); + }; + + if (deltaY<0) { + console.log('swipe down: no command'); + //my.drone.land(); + }; + } + + if (Math.abs(deltaZ) > Math.abs(deltaX) && Math.abs(deltaZ) > Math.abs(deltaY)) + console.log('swipe Z: ' + deltaZ); // null + } else { + console.log("Swipe skipped (" + Math.round(amplitude) + ")"); + } + + } else { + if (gesture.type=='circle' && gesture.state=='stop' && gesture.progress > CIRCLE_THRESHOLD ){ + + if (gesture.normal[2] < 0) { + //console.log("Turn CW: " + (gesture.progress - CIRCLE_THRESHOLD) ); + console.log('circle-cw: my.drone.takeoff()'); + my.drone.takeoff(); + }; + + if (gesture.normal[2] > 0) { + //console.log("Turn CCW: " + (gesture.progress - CIRCLE_THRESHOLD) ); + console.log('circle-ccw: my.drone.land()'); + my.drone.land(); + after((5).seconds(), my.drone.stop); + } + } + } + + // EMERGENCE STOP + if (gesture.type=='keyTap' || gesture.type=='screenTap') { + console.log('tap: my.drone.stop()'); + my.drone.stop(); + }; + }); + + + } +}).start(); diff --git a/examples/leap_ardrone/leap_ardrone.markdown b/examples/leap_ardrone/leap_ardrone.markdown new file mode 100644 index 0000000..ec0352e --- /dev/null +++ b/examples/leap_ardrone/leap_ardrone.markdown @@ -0,0 +1,37 @@ +# Leapmotion Ardrone 2.0 + +First, let's import Cylon: + + var Cylon = require('../..'); + +Now that we have Cylon imported, we can start defining our robot + + Cylon.robot({ + +Let's define the connections and devices: + + connections: [ + { name: 'leapmotion', adaptor: 'leapmotion', port: '127.0.0.1:6437' }, + { name: 'ardrone', adaptor: 'ardrone', port: '192.168.1.1' }, + { name: 'keyboard', adaptor: 'keyboard' } + ], + + devices: [ + { name: 'drone', driver: 'ardrone', connection:'ardrone' }, + { name: 'leapmotion', driver: 'leapmotion', connection:'leapmotion' }, + { name: 'keyboard', driver: 'keyboard', connection:'keyboard'} + ], + +Now that Cylon knows about the necessary hardware we're going to be using, we'll +tell it what work we want to do: + + work: function(my) { + my.leapmotion.on('frame', function(frame) { + frame.hands.length > 0 ? my.led.turnOn() : my.led.turnOff(); + }); + } + +Now that our robot knows what work to do, and the work it will be doing that +hardware with, we can start it: + + }).start(); From cef5a85310870cb34cbc1e47dfcb1898ef46c13b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A1bio=20Franco=20Uechi?= Date: Wed, 28 May 2014 17:47:32 -0300 Subject: [PATCH 2/7] Update leap_ardrone.markdown --- examples/leap_ardrone/leap_ardrone.markdown | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/examples/leap_ardrone/leap_ardrone.markdown b/examples/leap_ardrone/leap_ardrone.markdown index ec0352e..29122e7 100644 --- a/examples/leap_ardrone/leap_ardrone.markdown +++ b/examples/leap_ardrone/leap_ardrone.markdown @@ -10,6 +10,7 @@ Now that we have Cylon imported, we can start defining our robot Let's define the connections and devices: +``` connections: [ { name: 'leapmotion', adaptor: 'leapmotion', port: '127.0.0.1:6437' }, { name: 'ardrone', adaptor: 'ardrone', port: '192.168.1.1' }, @@ -21,14 +22,14 @@ Let's define the connections and devices: { name: 'leapmotion', driver: 'leapmotion', connection:'leapmotion' }, { name: 'keyboard', driver: 'keyboard', connection:'keyboard'} ], +``` Now that Cylon knows about the necessary hardware we're going to be using, we'll tell it what work we want to do: work: function(my) { - my.leapmotion.on('frame', function(frame) { - frame.hands.length > 0 ? my.led.turnOn() : my.led.turnOff(); - }); + // TODO + } Now that our robot knows what work to do, and the work it will be doing that From 52211db1af7efe7bbefa4c9234fd1799ef87cd62 Mon Sep 17 00:00:00 2001 From: fabito Date: Sun, 1 Jun 2014 11:11:29 -0300 Subject: [PATCH 3/7] cleaning up code --- examples/leap_ardrone/leap_ardrone.js | 262 +++++++++----------------- 1 file changed, 88 insertions(+), 174 deletions(-) diff --git a/examples/leap_ardrone/leap_ardrone.js b/examples/leap_ardrone/leap_ardrone.js index c7dfc17..90d446c 100644 --- a/examples/leap_ardrone/leap_ardrone.js +++ b/examples/leap_ardrone/leap_ardrone.js @@ -8,18 +8,18 @@ Cylon = require('cylon'); -var lastS = 0; -var handStartPosition = []; -var handStartDirection = []; -var UP_CONTROL_THRESHOLD = 50; -var UP_SPEED_FACTOR = 0.01; -var SWIPE_THRESHOLD = 30; -var CIRCLE_THRESHOLD = 1.5; -var DIRECTION_THRESHOLD = 0.25; -var DIRECTION_SPEED_FACTOR = 0.05; -var TURN_SPEED = 0.5; -var TURN_TRESHOLD = 0.2; -var TURN_SPEED_FACTOR = 2.0; +// constants +var lastS = 0, + handStartPosition = [], + handStartDirection = [], + UP_CONTROL_THRESHOLD = 50, + UP_SPEED_FACTOR = 0.01, + CIRCLE_THRESHOLD = 1.5, + DIRECTION_THRESHOLD = 0.25, + DIRECTION_SPEED_FACTOR = 0.05, + TURN_SPEED = 0.5, + TURN_TRESHOLD = 0.2, + TURN_SPEED_FACTOR = 2.0; Cylon.robot({ @@ -37,219 +37,133 @@ Cylon.robot({ work: function(my) { - //KEYBOARD - - my.keyboard.on('right', function(key) { - console.log("RIGHT"); - my.drone.rightFlip(); - }); - - my.keyboard.on('left', function(key) { - console.log("LEFT"); - my.drone.leftFlip(); - }); - - my.keyboard.on('up', function(key) { - console.log("UP"); - my.drone.frontFlip(); - }); - - my.keyboard.on('down', function(key) { - console.log("DOWN"); - my.drone.backFlip(); - }); - - my.keyboard.on('w', function(key) { - console.log("key(w): my.drone.wave()"); - my.drone.wave(); - }); - - // EMERGENCE KEYS - my.keyboard.on('s', function(key) { - console.log("key(S): my.drone.stop()"); - my.drone.stop(); - }); - - my.keyboard.on('l', function(key) { - console.log("key(L): my.drone.land()"); - my.drone.land(); - }); - - - // HAND my.leapmotion.on('hand', function(hand) { - // detecta abertua de mão ==> ATIVA COMANDO DE MDAnielOVIMENTO + // detects open hand ==> reset if (hand.s>1.5 && lastS<=1.5) { - console.log('Direction Motion Control'); handStartPosition = hand.palmPosition; handStartDirection = hand.direction; - console.log(); }; - //console.log(hand); + // TURNS + if(hand.s>1.5 && Math.abs(handStartDirection[0]-hand.direction[0]) > TURN_TRESHOLD ) { + var signal = handStartDirection[0]-hand.direction[0]; + var value = (Math.abs(handStartDirection[0]-hand.direction[0])-TURN_TRESHOLD)*TURN_SPEED_FACTOR; + if (signal>0){ + my.drone.counterClockwise(value); + } - // TURNS - if(hand.s>1.5 && Math.abs(handStartDirection[0]-hand.direction[0]) > TURN_TRESHOLD ) { - var signal = handStartDirection[0]-hand.direction[0]; - var value = (Math.abs(handStartDirection[0]-hand.direction[0])-TURN_TRESHOLD)*TURN_SPEED_FACTOR; - - if (signal>0){ - my.drone.counterClockwise(value); - console.log('turn left: CCW('+ value +')'); + if (signal<0){ + my.drone.clockwise(value); + } } - - if (signal<0){ - my.drone.clockwise(value); - console.log('turn right: CW('+ value +')'); - } - - } // UP and DOWN - if (hand.s>1.5 && Math.abs(hand.palmPosition[1]-handStartPosition[1]) > UP_CONTROL_THRESHOLD) { - + if (hand.s>1.5 && Math.abs(hand.palmPosition[1]-handStartPosition[1]) > UP_CONTROL_THRESHOLD) { var signal = (hand.palmPosition[1]-handStartPosition[1]) >= 0 ? 1 : -1; var value = Math.round(Math.abs((hand.palmPosition[1]-handStartPosition[1]))-UP_CONTROL_THRESHOLD) * UP_SPEED_FACTOR; if (signal>0) { my.drone.up(value); - console.log('my.drone.up('+value+')'); }; if (signal<0) { my.drone.down(value); - console.log('my.drone.down('+value+')'); } - } // DIRECTION FRONT/BACK if (hand.s>1.5 && (Math.abs(hand.palmNormal[2])>DIRECTION_THRESHOLD)) { - if (hand.palmNormal[2]>0) { - var value = Math.abs(Math.round( hand.palmNormal[2]*10 + DIRECTION_THRESHOLD )*DIRECTION_SPEED_FACTOR); - my.drone.forward( value ); - console.log ('my.drone.forward(' + value + ')'); - }; - - if (hand.palmNormal[2]<0) { - var value = Math.abs(Math.round( hand.palmNormal[2]*10 - DIRECTION_THRESHOLD )*DIRECTION_SPEED_FACTOR); - my.drone.back( value ); - console.log ('my.drone.back(' + value + ')'); - }; + if (hand.palmNormal[2]>0) { + var value = Math.abs(Math.round( hand.palmNormal[2]*10 + DIRECTION_THRESHOLD )*DIRECTION_SPEED_FACTOR); + my.drone.forward( value ); + }; + + if (hand.palmNormal[2]<0) { + var value = Math.abs(Math.round( hand.palmNormal[2]*10 - DIRECTION_THRESHOLD )*DIRECTION_SPEED_FACTOR); + my.drone.back( value ); + }; } // DIRECTION LEFT/RIGHT if (hand.s>1.5 && (Math.abs(hand.palmNormal[0])>DIRECTION_THRESHOLD)) { - if (hand.palmNormal[0]>0) { - var value = Math.abs(Math.round( hand.palmNormal[0]*10 + DIRECTION_THRESHOLD )*DIRECTION_SPEED_FACTOR); - my.drone.left( value ); - console.log ('my.drone.left(' + value + ')'); - }; - - if (hand.palmNormal[0]<0) { - var value = Math.abs(Math.round( hand.palmNormal[0]*10 - DIRECTION_THRESHOLD )*DIRECTION_SPEED_FACTOR); - my.drone.right( value ); - console.log ('my.drone.right(' + value + ')'); - }; + if (hand.palmNormal[0]>0) { + var value = Math.abs(Math.round( hand.palmNormal[0]*10 + DIRECTION_THRESHOLD )*DIRECTION_SPEED_FACTOR); + my.drone.left( value ); + }; + + if (hand.palmNormal[0]<0) { + var value = Math.abs(Math.round( hand.palmNormal[0]*10 - DIRECTION_THRESHOLD )*DIRECTION_SPEED_FACTOR); + my.drone.right( value ); + }; } // AUTO FREEZE - if ( hand.s>1.5 && // mão aberta - (Math.abs(hand.palmNormal[0])1.5 && // open hand + (Math.abs(hand.palmNormal[0]) 1.5) { // mão fechada - console.log("my.drone.stop() !!!"); + if (hand.s<=1.5 && lastS > 1.5) { // closed hand my.drone.stop(); } lastS = hand.s; - - }); - // GESTOS + });// end hand + + // Gestures my.leapmotion.on('gesture', function(gesture) { - - if (gesture.type=='swipe' && gesture.state=='stop'){ + if (gesture.type=='circle' && gesture.state=='stop' && gesture.progress > CIRCLE_THRESHOLD ){ + if (gesture.normal[2] < 0) { + my.drone.takeoff(); + }; - deltaX = gesture.position[0]-gesture.startPosition[0]; - deltaY = gesture.position[1]-gesture.startPosition[1]; - deltaZ = gesture.position[2]-gesture.startPosition[2]; - - var amplitude = Math.abs(Math.max(Math.max(deltaX, deltaY),deltaZ)); - - if (amplitude>SWIPE_THRESHOLD) { - - if (Math.abs(deltaX) > Math.abs(deltaY) && Math.abs(deltaX) > Math.abs(deltaZ)) { - //console.log('swipe X: ' + deltaX); // drone flip left/right - if (deltaX>0){ - my.drone.clockwise(TURN_SPEED); - console.log('swipe right: my.drone.clockwise('+TURN_SPEED+')'); - //my.drone.animate('flipRight',1000); - //my.drone.rightFlip(); - }; - - if (deltaX<0){ - my.drone.counterClockwise(TURN_SPEED); - console.log('swipe left: my.drone.counterClockwise('+TURN_SPEED+')'); - //my.drone.animate('flipLeft',1000); - //my.drone.leftFlip(); - } - } - - if (Math.abs(deltaY) > Math.abs(deltaX) && Math.abs(deltaY) > Math.abs(deltaZ)) { - console.log('swipe Y: ' + deltaY); // drone takeoff/land - if (deltaY>0) { - console.log('swipe up: no command'); - //my.drone.takeoff(); - }; - - if (deltaY<0) { - console.log('swipe down: no command'); - //my.drone.land(); - }; - } - - if (Math.abs(deltaZ) > Math.abs(deltaX) && Math.abs(deltaZ) > Math.abs(deltaY)) - console.log('swipe Z: ' + deltaZ); // null - } else { - console.log("Swipe skipped (" + Math.round(amplitude) + ")"); - } - - } else { - if (gesture.type=='circle' && gesture.state=='stop' && gesture.progress > CIRCLE_THRESHOLD ){ - - if (gesture.normal[2] < 0) { - //console.log("Turn CW: " + (gesture.progress - CIRCLE_THRESHOLD) ); - console.log('circle-cw: my.drone.takeoff()'); - my.drone.takeoff(); - }; - - if (gesture.normal[2] > 0) { - //console.log("Turn CCW: " + (gesture.progress - CIRCLE_THRESHOLD) ); - console.log('circle-ccw: my.drone.land()'); - my.drone.land(); - after((5).seconds(), my.drone.stop); - } + if (gesture.normal[2] > 0) { + my.drone.land(); } } // EMERGENCE STOP if (gesture.type=='keyTap' || gesture.type=='screenTap') { - console.log('tap: my.drone.stop()'); my.drone.stop(); }; - }); + }); // end gesture + //KEYBOARD + my.keyboard.on('right', function(key) { + my.drone.rightFlip(); + }); - } -}).start(); + my.keyboard.on('left', function(key) { + my.drone.leftFlip(); + }); + + my.keyboard.on('up', function(key) { + my.drone.frontFlip(); + }); + + my.keyboard.on('down', function(key) { + my.drone.backFlip(); + }); + + my.keyboard.on('w', function(key) { + my.drone.wave(); + }); + + my.keyboard.on('s', function(key) { + my.drone.stop(); + }); + + my.keyboard.on('l', function(key) { + my.drone.land(); + }); + + } // end work +}).start(); \ No newline at end of file From 8afe35b4c90f8468fa4ba0f47963f6496e12dea6 Mon Sep 17 00:00:00 2001 From: fabito Date: Sun, 1 Jun 2014 11:51:42 -0300 Subject: [PATCH 4/7] started code explanation in markdown --- examples/leap_ardrone/leap_ardrone.markdown | 92 ++++++++++++++++++++- 1 file changed, 90 insertions(+), 2 deletions(-) diff --git a/examples/leap_ardrone/leap_ardrone.markdown b/examples/leap_ardrone/leap_ardrone.markdown index 29122e7..7093057 100644 --- a/examples/leap_ardrone/leap_ardrone.markdown +++ b/examples/leap_ardrone/leap_ardrone.markdown @@ -28,9 +28,97 @@ Now that Cylon knows about the necessary hardware we're going to be using, we'll tell it what work we want to do: work: function(my) { - // TODO - + +Lets use the circle gesture to take off and land : two rounds clockwise will trigger the takeoff() and counter clockwise will tell the drone to land: + +``` + my.leapmotion.on('gesture', function(gesture) { + if (gesture.type=='circle' && gesture.state=='stop' && gesture.progress > CIRCLE_THRESHOLD ){ + if (gesture.normal[2] < 0) { + my.drone.takeoff(); + }; + + if (gesture.normal[2] > 0) { + my.drone.land(); + } } + }); +``` + +Whenever we get a 'hand' gesture event from Leap Motion we need to tell ARDrone what to do. + + my.leapmotion.on('hand', function(hand) { + +In case we turn our hand to the right or left we want the drone to rotate clockwise or counter clockwise respectively: + +``` + if(hand.s>1.5 && Math.abs(handStartDirection[0]-hand.direction[0]) > TURN_TRESHOLD ) { + var signal = handStartDirection[0]-hand.direction[0]; + var value = (Math.abs(handStartDirection[0]-hand.direction[0])-TURN_TRESHOLD) * TURN_SPEED_FACTOR; + if (signal>0){ + my.drone.counterClockwise(value); + } + + if (signal<0){ + my.drone.clockwise(value); + } + } +``` + +In case we raise our hand up or lower it down we tell the drone to got up or down respectively: + +``` + if (hand.s>1.5 && Math.abs(hand.palmPosition[1]-handStartPosition[1]) > UP_CONTROL_THRESHOLD) { + var signal = (hand.palmPosition[1]-handStartPosition[1]) >= 0 ? 1 : -1; + var value = Math.round(Math.abs((hand.palmPosition[1]-handStartPosition[1]))-UP_CONTROL_THRESHOLD) * UP_SPEED_FACTOR; + + if (signal>0) { + my.drone.up(value); + }; + + if (signal<0) { + my.drone.down(value); + } + } +``` +In order to move the drone forward, backward, directly left or right we detect the hand inclination - so that we just need to lean it in the direction we want to move. + +``` + if (hand.s>1.5 && (Math.abs(hand.palmNormal[2])>DIRECTION_THRESHOLD)) { + if (hand.palmNormal[2]>0) { + var value = Math.abs(Math.round( hand.palmNormal[2] * 10 + DIRECTION_THRESHOLD ) * DIRECTION_SPEED_FACTOR); + my.drone.forward( value ); + }; + + if (hand.palmNormal[2]<0) { + var value = Math.abs(Math.round( hand.palmNormal[2] * 10 - DIRECTION_THRESHOLD ) * DIRECTION_SPEED_FACTOR); + my.drone.back( value ); + }; + } + + if (hand.s>1.5 && (Math.abs(hand.palmNormal[0])>DIRECTION_THRESHOLD)) { + if (hand.palmNormal[0]>0) { + var value = Math.abs(Math.round( hand.palmNormal[0] * 10 + DIRECTION_THRESHOLD ) * DIRECTION_SPEED_FACTOR); + my.drone.left( value ); + }; + + if (hand.palmNormal[0]<0) { + var value = Math.abs(Math.round( hand.palmNormal[0] * 10 - DIRECTION_THRESHOLD ) * DIRECTION_SPEED_FACTOR); + my.drone.right( value ); + }; + } +``` +Whenever we close our hand we tell the drone no stop: + +``` + if (hand.s<=1.5 && lastS > 1.5) { // closed hand + my.drone.stop(); + } +``` + + + + } //end work Now that our robot knows what work to do, and the work it will be doing that hardware with, we can start it: From 930b182275f20bc29896effb696883049b9787ce Mon Sep 17 00:00:00 2001 From: fabito Date: Sun, 1 Jun 2014 12:00:19 -0300 Subject: [PATCH 5/7] finished markdown documentation --- examples/leap_ardrone/leap_ardrone.markdown | 28 ++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/examples/leap_ardrone/leap_ardrone.markdown b/examples/leap_ardrone/leap_ardrone.markdown index 7093057..cc574c3 100644 --- a/examples/leap_ardrone/leap_ardrone.markdown +++ b/examples/leap_ardrone/leap_ardrone.markdown @@ -1,5 +1,7 @@ # Leapmotion Ardrone 2.0 +This example illustrates how to use Leap Motion and the keyboard to control an ARDrone. We basically use one hand to drive the drone (takeoff, land, up, down, etc) and the arrow keys to perform some cool stunts (flips). + First, let's import Cylon: var Cylon = require('../..'); @@ -65,7 +67,7 @@ In case we turn our hand to the right or left we want the drone to rotate clockw } ``` -In case we raise our hand up or lower it down we tell the drone to got up or down respectively: +In case we raise our hand up or lower it down we tell the drone to go up or down respectively: ``` if (hand.s>1.5 && Math.abs(hand.palmPosition[1]-handStartPosition[1]) > UP_CONTROL_THRESHOLD) { @@ -114,13 +116,33 @@ Whenever we close our hand we tell the drone no stop: if (hand.s<=1.5 && lastS > 1.5) { // closed hand my.drone.stop(); } + + });// end hand ``` +And finally lets use the arrow keys to tell the drone to do some cool stunts: +``` + my.keyboard.on('right', function(key) { + my.drone.rightFlip(); + }); - } //end work + my.keyboard.on('left', function(key) { + my.drone.leftFlip(); + }); + + my.keyboard.on('up', function(key) { + my.drone.frontFlip(); + }); + + my.keyboard.on('down', function(key) { + my.drone.backFlip(); + }); +``` + + } //end work Now that our robot knows what work to do, and the work it will be doing that hardware with, we can start it: - }).start(); +}).start(); From 31635b19400a8eed4e4e7e608821ce6b2c499134 Mon Sep 17 00:00:00 2001 From: fabito Date: Sun, 1 Jun 2014 12:01:30 -0300 Subject: [PATCH 6/7] finished markdown documentation --- examples/leap_ardrone/leap_ardrone.markdown | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/examples/leap_ardrone/leap_ardrone.markdown b/examples/leap_ardrone/leap_ardrone.markdown index cc574c3..7498694 100644 --- a/examples/leap_ardrone/leap_ardrone.markdown +++ b/examples/leap_ardrone/leap_ardrone.markdown @@ -138,11 +138,13 @@ And finally lets use the arrow keys to tell the drone to do some cool stunts: my.keyboard.on('down', function(key) { my.drone.backFlip(); }); -``` - } //end work +} //end work +``` Now that our robot knows what work to do, and the work it will be doing that hardware with, we can start it: +``` }).start(); +``` \ No newline at end of file From 0302a78294c3f63e8963dc3eb850450f7cd37805 Mon Sep 17 00:00:00 2001 From: fabito Date: Sun, 1 Jun 2014 17:38:00 -0300 Subject: [PATCH 7/7] finished markdown documentation --- examples/leap_ardrone/leap_ardrone.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/leap_ardrone/leap_ardrone.markdown b/examples/leap_ardrone/leap_ardrone.markdown index 7498694..72f2eb7 100644 --- a/examples/leap_ardrone/leap_ardrone.markdown +++ b/examples/leap_ardrone/leap_ardrone.markdown @@ -83,7 +83,7 @@ In case we raise our hand up or lower it down we tell the drone to go up or down } } ``` -In order to move the drone forward, backward, directly left or right we detect the hand inclination - so that we just need to lean it in the direction we want to move. +In order to move the drone forward, backward, left or right we need to detect the hand inclination. Imagine your hand is the drone and lean it towards the direction we want it to move. ``` if (hand.s>1.5 && (Math.abs(hand.palmNormal[2])>DIRECTION_THRESHOLD)) {