Developing the Internet of Things: Parrot AR Drone
Drones are growing in popularity with both hobbyists and professionals as an innovative new storytelling mechanism because they provide an expanded range of movement, especially in live action-based scenes, that traditional cameras cannot achieve.
With Appmethod, it’s never been easier to build connected apps for the IoT and gadgets such as the Parrot AR.Drone 2.0 using a single app development platform and shared C++ codebase. Appmethod addresses the core challenges developers face in building and extending apps for IoT by providing tools for multiple form factors and operating systems. Using Appmethod, developers can now build natively compiled C++ apps that connect mobile and desktop devices with the latest IoT gadgets including the AR.Drone, devices, sensors, wearables and cloud services.
In this post, learn how to connect a touch interface and keyboard events to control the flight of a Parrot AR.Drone 2.0.
Meet the WASD Control App
What ASimple Drone Control App allows you to pilot the Parrot AR Drone 2.0 with either a touch interface running on an Android or iOS device or via a keyboard on Windows or OSX desktop. It also maps keyboard input to flight controls. Pairing a Bluetooth keyboard with your device of choice provides high fidelity control over the drone. PC Gamers out there will find this control scheme especially fun and accurate. With phone in pocket and Bluetooth keyboard in hand, you can take the drone for a walk!
WASD Control App Keybinds
Forward - w
Strafe Left - a
Reverse - s
Strafe Right - d
Spin Left - q
Spin Right - e
Rise - r
Lower - f
Take Off - z
Land - spacebar
Step One: Connecting to the Parrot AR Drone
The Parrot AR Drone accepts commands from any device that supports Wifi ad-hoc mode. Before issuing commands to the Parrot AR Drone the controlling device must connect to the access point within the drone. Please refer to the Parrot User Guide for more info. Controlling the drone is done by sending AT commands on UDP over port 5556. Appmethod uses a UDP component called TIdUDPClient to handle connecting and transmitting UDP data.
From the Tool Palette drag a TIdUDPClient component to the Form Designer. Ensure the UDP component is selected and in the Object Inspector set the following properties:
- Name -> UDP
- Port -> 5556
- Host -> 192.168.1.1
Step Two: Issuing Commands to the Parrot AR.Drone 2.0
The first function we will examine uses the TIdUDPClient component to send passed in commands to the Parrot AR Drone.
void __fastcall TForm2::SendCommand(AnsiString cmd, AnsiString args) { AnsiString full; if (!UDP->Active) { UDP->Connect(); } full = AnsiString().sprintf("%s=%d,%s\r", cmd.c_str(), fSeq++, args.c_str()); UDP->Send(full); }
This code is based of the great work Jim Mckeeth laid out in his blog post: Connecting to the Parrot AR.Drone 2.0 from Delphi XE5. If you want to know more about the inner workings of how commands are processed within the application you should check out Jim's post. Even though it is written with Delphi while the WASD Control App is C++ the underlying logic still applies.
Next lets examine the take off, land, and move functions used to control the flight of the drone.
void __fastcall TForm2::TakeOff() { SendCommand("AT*REF","290718208"); isFlying = true; isLanding = false; } void __fastcall TForm2::Land() { SendCommand("AT*REF", "290717696"); isLanding = true; }
The commands are formatted with an AT* prefix, and a series of arguments. For example, to take off, the command is AT*REF=1,290718208 where AT*REF is the command, 1 is the sequence number (always the first argument) and 290718208 is a bitmask that means take off.
isFlying and isLanding are Boolean flags used to control state within the application. The full source code will be posted soon.
void __fastcall TForm2::Move(float phi, float theta, float gaz, float yaw) { SendCommand("AT*PCMD",Format("1,%d,%d,%d,%d", ARRAYOFCONST((IEEEFloat(phi), IEEEFloat(theta), IEEEFloat(gaz), IEEEFloat(yaw))))); }
Phi, Theta, Gaz, and Yaw represent movement along forward and backwards, strafing left and right, rising and lowering in altitude, and spinning left and right.
void __fastcall TForm2::MoveForward() { Move( 0,-MOVEMENT_OFFSET,0,0 ); } void __fastcall TForm2::MoveReverse() { Move( 0,MOVEMENT_OFFSET,0,0 ); }
The MoveForward and MoveReverse function demonstrates that the theta parameter of Move is linked to moving the drone forwards and in reverse. MOVEMENT_OFFSET is a float set to 1.25 which is just a little bit higher than the baseline movement speed of 1.00.
Step Three: Set Up the WASD Control App User Interface
Each dimension of movement is mapped to a TButton event OnMouseDown and OnMouseUp. This allows controls to continually be sent to the drone while the button is either being clicked on or pressed on via touch.
Lets take a look at how the Take Off and Land buttons are created and function.
Drag a TButton from the Tool Palette to the Form Designer and in the Object Inspector set the Name property to TakeOffButton and Text to Take Off. Open the the Events tab (It's right next to the Properties tab in the Object Inspector) and double click on input box for OnMouseDown. This will open the code view for the OnMouseDown event handler.
void __fastcall TForm2::TakeOffButtonClick(TObject *Sender) { TakeOff(); }
Similarly create a Land button and set the OnMouseDown event code as such:
void __fastcall TForm2::LandButtonClick(TObject *Sender) { Land(); }
Next create a Forward button and set the OnMouseDown and OnMouseUp events as such:
void __fastcall TForm2::ForwardButtonMouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, float X, float Y) { movementDirection = FORWARD; } void __fastcall TForm2::ForwardButtonMouseUp(TObject *Sender, TMouseButton Button, TShiftState Shift, float X, float Y) { ClearDirection(); }
Step Four: WASD Control App State Management
There is a TTimer which is constantly examining the state of which buttons are being pressed and in turn issues commands to the drone.
void __fastcall TForm2::ClearDirection() { movementDirection = NODIRECTION; } void __fastcall TForm2::Timer1Timer(TObject *Sender) { //- only process commands if in flight if ( isLanding || !isFlying ) { return; } switch ( movementDirection ) { case NODIRECTION: //- no move command break; case FORWARD: MoveForward(); break; } }
Commands should not be sent unless the drone is in flight. Commands should also be ignored if the drone is in the process of landing.
This is a basic framework for controlling state and can be extended to handle the various dimensions of movement. Full source code will be released soon.
Step Five: Capturing WASD Key Press Events
In order for key events to be captured ensure that the root TForm has OnKeyDown and OnKeyUp functions defined.
void __fastcall TForm2::FormKeyUp(TObject *Sender, WORD &Key, System::WideChar &KeyChar, TShiftState Shift) { ClearDirection(); } void __fastcall TForm2::FormKeyDown(TObject *Sender, WORD &Key, System::WideChar &KeyChar, TShiftState Shift) { switch( KeyChar ) { case ' ': Land(); break; case 'z': TakeOff(); break; } }
A Few Notes on Parrot AR.Drone 2.0 Gotchas
Clearing the Emergency State
If the Parrot AR.Drone 2.0 flips over or takes an extreme angle off level then it will enter an emergency state. This will prevent movement commands from running on the drone. Normally, the application can clear this as the Parrot AR.Drone 2.0 will transmit its state over Wifi via UDP to your device. Currently the WASD Control App does not capture this information and so cannot clear the emergency state. In order to clear the state the battery connector can be disconnected for a few seconds and reconnected. After doing this you may need to reconnect to the drones Wifi access point.


Comments
-
Please login first in order for you to submit comments