├── controltower-android
├── lint.xml
├── ic_launcher-web.png
├── res
│ ├── values
│ │ ├── styles.xml
│ │ └── strings.xml
│ ├── drawable-hdpi
│ │ ├── ardron_icon.png
│ │ ├── ardrone_front.png
│ │ └── ic_action_search.png
│ ├── drawable-ldpi
│ │ ├── ardron_icon.png
│ │ └── ic_launcher.png
│ ├── drawable-mdpi
│ │ ├── ardron_icon.png
│ │ ├── ardrone_front.jpg
│ │ ├── ic_action_search.png
│ │ ├── sixaxis_controller_decription.jpg
│ │ ├── sixaxis_controller_decription_portrait.png
│ │ └── sixaxis_controller_decription_portrait_smal.png
│ ├── drawable-xhdpi
│ │ ├── ardron_icon.png
│ │ └── ic_action_search.png
│ ├── menu
│ │ └── activity_main.xml
│ ├── layout
│ │ ├── ps3_controller_help.xml
│ │ ├── seek_bar_preference.xml
│ │ └── activity_main.xml
│ └── xml
│ │ └── settings.xml
├── src
│ └── com
│ │ └── codeminders
│ │ └── ardrone
│ │ ├── PS3ControllerHelp.java
│ │ ├── SettingsPrefs.java
│ │ ├── controller
│ │ └── usbhost
│ │ │ ├── SonyPS3UsbHostController.java
│ │ │ ├── AfterGlowUsbHostController.java
│ │ │ └── UsbHostController.java
│ │ ├── ControlMap.java
│ │ └── AssignableControl.java
├── project.properties
├── proguard-project.txt
├── AndroidManifest.xml
└── pom.xml
├── lib
└── maven
│ └── com
│ └── twilight
│ └── h264-decoder
│ └── 1.0
│ ├── pom.xml.sha1
│ ├── h264-decoder-1.0.jar.sha1
│ ├── h264-decoder-1.0-javadoc.jar.sha1
│ ├── h264-decoder-1.0-sources.jar.sha1
│ ├── h264-decoder-1.0.jar
│ ├── h264-decoder-1.0-javadoc.jar
│ ├── h264-decoder-1.0-sources.jar
│ └── pom.xml
├── javadrone-api
├── src
│ └── main
│ │ └── java
│ │ ├── META-INF
│ │ └── MANIFEST.MF
│ │ └── com
│ │ └── codeminders
│ │ └── ardrone
│ │ ├── data
│ │ ├── navdata
│ │ │ ├── Mode.java
│ │ │ ├── ControlAlgorithm.java
│ │ │ ├── NavDataFormatException.java
│ │ │ ├── vision
│ │ │ │ ├── Point.java
│ │ │ │ ├── Dimension.java
│ │ │ │ └── VisionTag.java
│ │ │ ├── FlyingState.java
│ │ │ ├── CtrlState.java
│ │ │ └── NavDataTag.java
│ │ ├── logger
│ │ │ ├── DataLogger.java
│ │ │ ├── LogStreamWrapper.java
│ │ │ ├── ChannelDataChunk.java
│ │ │ └── ARDroneDataReaderAndLogWrapper.java
│ │ ├── ARDroneDataReader.java
│ │ ├── ChannelProcessor.java
│ │ ├── DataDecoder.java
│ │ ├── decoder
│ │ │ └── ardrone10
│ │ │ │ ├── video
│ │ │ │ ├── MacroBlock.java
│ │ │ │ └── ImageSlice.java
│ │ │ │ ├── ARDrone10VideoDataDecoder.java
│ │ │ │ └── ARDrone10NavDataDecoder.java
│ │ └── reader
│ │ │ ├── TCPDataRader.java
│ │ │ ├── LigthUDPDataReader.java
│ │ │ └── UDPDataReader.java
│ │ ├── NavDataListener.java
│ │ ├── commands
│ │ ├── HoverCommand.java
│ │ ├── EmergencyCommand.java
│ │ ├── QuitCommand.java
│ │ ├── FlatTrimCommand.java
│ │ ├── TakeOffCommand.java
│ │ ├── KeepAliveCommand.java
│ │ ├── LandCommand.java
│ │ ├── RefCommand.java
│ │ ├── ControlCommand.java
│ │ ├── ConfigureCommand.java
│ │ ├── PlayAnimationCommand.java
│ │ ├── MoveCommand.java
│ │ ├── PlayLEDCommand.java
│ │ ├── PCMDCommand.java
│ │ └── ATCommand.java
│ │ ├── DroneVideoListener.java
│ │ ├── version
│ │ ├── DroneVersionReader.java
│ │ └── ftp
│ │ │ └── DroneFTPversionReader.java
│ │ ├── DroneStatusChangeListener.java
│ │ ├── controllers
│ │ ├── decoders
│ │ │ ├── ControllerStateDecoder.java
│ │ │ ├── MotioninJoyVirtualStateDecoder.java
│ │ │ ├── AfterGlowControllerDecoder.java
│ │ │ └── SonyPS3ControllerStateDecoder.java
│ │ ├── ControllerData.java
│ │ └── Controller.java
│ │ ├── NavDataDecoder.java
│ │ ├── VideoDataDecoder.java
│ │ ├── examples
│ │ └── TakeOffAndLand.java
│ │ ├── DroneCommand.java
│ │ ├── CommandSender.java
│ │ ├── NavData.java
│ │ └── CommandQueue.java
├── project.properties
├── AndroidManifest.xml
├── proguard-project.txt
└── pom.xml
├── controltower
├── src
│ ├── resources
│ │ ├── com
│ │ │ └── codeminders
│ │ │ │ └── controltower
│ │ │ │ ├── sounds
│ │ │ │ ├── camera.aif
│ │ │ │ ├── rec_stop.aif
│ │ │ │ └── rec_start.aif
│ │ │ │ └── images
│ │ │ │ ├── drone_on.gif
│ │ │ │ ├── drone_off.gif
│ │ │ │ ├── instruments.gif
│ │ │ │ ├── keyboard_on.png
│ │ │ │ ├── objects_039.gif
│ │ │ │ ├── controller_on.png
│ │ │ │ ├── keyboard_off.png
│ │ │ │ ├── controller_off.png
│ │ │ │ └── gaugeback_bottom2.png
│ │ ├── log4j.properties
│ │ └── log.properties
│ └── main
│ │ ├── assembly
│ │ └── src.xml
│ │ └── java
│ │ └── com
│ │ └── codeminders
│ │ └── controltower
│ │ ├── VideoPanel.form
│ │ ├── config
│ │ └── AudioPlayer.java
│ │ ├── KeyboardControlConfig.java
│ │ ├── KeyboardControlConfig.form
│ │ ├── VideoPanel.java
│ │ └── DroneConfig.form
└── pom.xml
├── .hgignore
├── javadrone-utils
├── src
│ └── main
│ │ └── java
│ │ └── com
│ │ └── codeminders
│ │ └── ardrone
│ │ ├── logs
│ │ └── video
│ │ │ ├── PlayerFrame.java
│ │ │ └── VideoPlayer.java
│ │ ├── util
│ │ ├── RecordingSuccessCallback.java
│ │ ├── BufferedImageVideoListener.java
│ │ ├── ImageVideoRecorderBase.java
│ │ ├── FileImageRecorder.java
│ │ └── FileVideoRecorder.java
│ │ ├── decoder
│ │ └── FileDataReaderAndDecoder.java
│ │ ├── controllers
│ │ ├── hid
│ │ │ ├── manager
│ │ │ │ └── HIDControllerFinder.java
│ │ │ ├── HIDAPIMotioninJoyVirtualController.java
│ │ │ ├── HIDAPIAfterGlowController.java
│ │ │ ├── HIDAPISonyPS3Controller.java
│ │ │ └── HIDAPIController.java
│ │ └── KeyboardController.java
│ │ ├── tools
│ │ ├── ControllerTest.java
│ │ └── HIDAPITest.java
│ │ └── data
│ │ ├── logger
│ │ └── file
│ │ │ ├── SaveStreamToFile.java
│ │ │ ├── SaveToFile.java
│ │ │ └── AsyncFileChannelDataLogger.java
│ │ └── reader
│ │ └── FileDataReader.java
└── pom.xml
├── pom.xml
├── scripts
└── ar_drone_connect.py
└── README.md
/controltower-android/lint.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/lib/maven/com/twilight/h264-decoder/1.0/pom.xml.sha1:
--------------------------------------------------------------------------------
1 | 1325d32de093840cb4a18b1627cd9a82a3c008aa
--------------------------------------------------------------------------------
/javadrone-api/src/main/java/META-INF/MANIFEST.MF:
--------------------------------------------------------------------------------
1 | Manifest-Version: 1.0
2 | Class-Path:
3 |
4 |
--------------------------------------------------------------------------------
/lib/maven/com/twilight/h264-decoder/1.0/h264-decoder-1.0.jar.sha1:
--------------------------------------------------------------------------------
1 | f398216aafc69307862728bb6c0f101212394f16
--------------------------------------------------------------------------------
/lib/maven/com/twilight/h264-decoder/1.0/h264-decoder-1.0-javadoc.jar.sha1:
--------------------------------------------------------------------------------
1 | 5d3489e4ae7874dbb3485466b4b2e73eab4e18da
--------------------------------------------------------------------------------
/lib/maven/com/twilight/h264-decoder/1.0/h264-decoder-1.0-sources.jar.sha1:
--------------------------------------------------------------------------------
1 | 426bd1d5f4a606d72f0cb097fada3dde28abd533
--------------------------------------------------------------------------------
/controltower-android/ic_launcher-web.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codeminders/javadrone/HEAD/controltower-android/ic_launcher-web.png
--------------------------------------------------------------------------------
/controltower-android/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/controltower-android/res/drawable-hdpi/ardron_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codeminders/javadrone/HEAD/controltower-android/res/drawable-hdpi/ardron_icon.png
--------------------------------------------------------------------------------
/controltower-android/res/drawable-ldpi/ardron_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codeminders/javadrone/HEAD/controltower-android/res/drawable-ldpi/ardron_icon.png
--------------------------------------------------------------------------------
/controltower-android/res/drawable-ldpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codeminders/javadrone/HEAD/controltower-android/res/drawable-ldpi/ic_launcher.png
--------------------------------------------------------------------------------
/controltower-android/res/drawable-mdpi/ardron_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codeminders/javadrone/HEAD/controltower-android/res/drawable-mdpi/ardron_icon.png
--------------------------------------------------------------------------------
/controltower-android/res/drawable-xhdpi/ardron_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codeminders/javadrone/HEAD/controltower-android/res/drawable-xhdpi/ardron_icon.png
--------------------------------------------------------------------------------
/controltower-android/res/drawable-hdpi/ardrone_front.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codeminders/javadrone/HEAD/controltower-android/res/drawable-hdpi/ardrone_front.png
--------------------------------------------------------------------------------
/controltower-android/res/drawable-mdpi/ardrone_front.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codeminders/javadrone/HEAD/controltower-android/res/drawable-mdpi/ardrone_front.jpg
--------------------------------------------------------------------------------
/controltower-android/res/drawable-hdpi/ic_action_search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codeminders/javadrone/HEAD/controltower-android/res/drawable-hdpi/ic_action_search.png
--------------------------------------------------------------------------------
/controltower-android/res/drawable-mdpi/ic_action_search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codeminders/javadrone/HEAD/controltower-android/res/drawable-mdpi/ic_action_search.png
--------------------------------------------------------------------------------
/controltower-android/res/drawable-xhdpi/ic_action_search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codeminders/javadrone/HEAD/controltower-android/res/drawable-xhdpi/ic_action_search.png
--------------------------------------------------------------------------------
/lib/maven/com/twilight/h264-decoder/1.0/h264-decoder-1.0.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codeminders/javadrone/HEAD/lib/maven/com/twilight/h264-decoder/1.0/h264-decoder-1.0.jar
--------------------------------------------------------------------------------
/javadrone-api/src/main/java/com/codeminders/ardrone/data/navdata/Mode.java:
--------------------------------------------------------------------------------
1 | package com.codeminders.ardrone.data.navdata;
2 |
3 | public enum Mode
4 | {
5 | BOOTSTRAP, DEMO
6 | }
7 |
--------------------------------------------------------------------------------
/lib/maven/com/twilight/h264-decoder/1.0/h264-decoder-1.0-javadoc.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codeminders/javadrone/HEAD/lib/maven/com/twilight/h264-decoder/1.0/h264-decoder-1.0-javadoc.jar
--------------------------------------------------------------------------------
/lib/maven/com/twilight/h264-decoder/1.0/h264-decoder-1.0-sources.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codeminders/javadrone/HEAD/lib/maven/com/twilight/h264-decoder/1.0/h264-decoder-1.0-sources.jar
--------------------------------------------------------------------------------
/controltower-android/res/drawable-mdpi/sixaxis_controller_decription.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codeminders/javadrone/HEAD/controltower-android/res/drawable-mdpi/sixaxis_controller_decription.jpg
--------------------------------------------------------------------------------
/controltower/src/resources/com/codeminders/controltower/sounds/camera.aif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codeminders/javadrone/HEAD/controltower/src/resources/com/codeminders/controltower/sounds/camera.aif
--------------------------------------------------------------------------------
/controltower/src/resources/com/codeminders/controltower/images/drone_on.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codeminders/javadrone/HEAD/controltower/src/resources/com/codeminders/controltower/images/drone_on.gif
--------------------------------------------------------------------------------
/controltower/src/resources/com/codeminders/controltower/sounds/rec_stop.aif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codeminders/javadrone/HEAD/controltower/src/resources/com/codeminders/controltower/sounds/rec_stop.aif
--------------------------------------------------------------------------------
/controltower/src/resources/com/codeminders/controltower/images/drone_off.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codeminders/javadrone/HEAD/controltower/src/resources/com/codeminders/controltower/images/drone_off.gif
--------------------------------------------------------------------------------
/controltower/src/resources/com/codeminders/controltower/images/instruments.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codeminders/javadrone/HEAD/controltower/src/resources/com/codeminders/controltower/images/instruments.gif
--------------------------------------------------------------------------------
/controltower/src/resources/com/codeminders/controltower/images/keyboard_on.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codeminders/javadrone/HEAD/controltower/src/resources/com/codeminders/controltower/images/keyboard_on.png
--------------------------------------------------------------------------------
/controltower/src/resources/com/codeminders/controltower/images/objects_039.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codeminders/javadrone/HEAD/controltower/src/resources/com/codeminders/controltower/images/objects_039.gif
--------------------------------------------------------------------------------
/controltower/src/resources/com/codeminders/controltower/sounds/rec_start.aif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codeminders/javadrone/HEAD/controltower/src/resources/com/codeminders/controltower/sounds/rec_start.aif
--------------------------------------------------------------------------------
/javadrone-api/src/main/java/com/codeminders/ardrone/NavDataListener.java:
--------------------------------------------------------------------------------
1 |
2 | package com.codeminders.ardrone;
3 |
4 | public interface NavDataListener
5 | {
6 | void navDataReceived(NavData nd);
7 | }
8 |
--------------------------------------------------------------------------------
/controltower/src/resources/com/codeminders/controltower/images/controller_on.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codeminders/javadrone/HEAD/controltower/src/resources/com/codeminders/controltower/images/controller_on.png
--------------------------------------------------------------------------------
/controltower/src/resources/com/codeminders/controltower/images/keyboard_off.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codeminders/javadrone/HEAD/controltower/src/resources/com/codeminders/controltower/images/keyboard_off.png
--------------------------------------------------------------------------------
/controltower-android/res/drawable-mdpi/sixaxis_controller_decription_portrait.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codeminders/javadrone/HEAD/controltower-android/res/drawable-mdpi/sixaxis_controller_decription_portrait.png
--------------------------------------------------------------------------------
/controltower/src/resources/com/codeminders/controltower/images/controller_off.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codeminders/javadrone/HEAD/controltower/src/resources/com/codeminders/controltower/images/controller_off.png
--------------------------------------------------------------------------------
/controltower/src/resources/com/codeminders/controltower/images/gaugeback_bottom2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codeminders/javadrone/HEAD/controltower/src/resources/com/codeminders/controltower/images/gaugeback_bottom2.png
--------------------------------------------------------------------------------
/controltower-android/res/drawable-mdpi/sixaxis_controller_decription_portrait_smal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codeminders/javadrone/HEAD/controltower-android/res/drawable-mdpi/sixaxis_controller_decription_portrait_smal.png
--------------------------------------------------------------------------------
/javadrone-api/src/main/java/com/codeminders/ardrone/data/navdata/ControlAlgorithm.java:
--------------------------------------------------------------------------------
1 | package com.codeminders.ardrone.data.navdata;
2 |
3 | public enum ControlAlgorithm
4 | {
5 | EULER_ANGELS_CONTROL, ANGULAR_SPEED_CONTROL
6 | }
--------------------------------------------------------------------------------
/javadrone-api/src/main/java/com/codeminders/ardrone/commands/HoverCommand.java:
--------------------------------------------------------------------------------
1 | package com.codeminders.ardrone.commands;
2 |
3 | public class HoverCommand extends PCMDCommand
4 | {
5 | public HoverCommand()
6 | {
7 | super(true);
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/javadrone-api/src/main/java/com/codeminders/ardrone/DroneVideoListener.java:
--------------------------------------------------------------------------------
1 |
2 | package com.codeminders.ardrone;
3 |
4 | public interface DroneVideoListener
5 | {
6 | void frameReceived(int startX, int startY, int w, int h, int[] rgbArray, int offset, int scansize);
7 | }
8 |
--------------------------------------------------------------------------------
/javadrone-api/src/main/java/com/codeminders/ardrone/commands/EmergencyCommand.java:
--------------------------------------------------------------------------------
1 | package com.codeminders.ardrone.commands;
2 |
3 | public class EmergencyCommand extends RefCommand
4 | {
5 | public EmergencyCommand()
6 | {
7 | value |= (1<<8);
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/javadrone-api/src/main/java/com/codeminders/ardrone/version/DroneVersionReader.java:
--------------------------------------------------------------------------------
1 | package com.codeminders.ardrone.version;
2 |
3 | import java.io.IOException;
4 |
5 | public interface DroneVersionReader {
6 |
7 | String readDroneVersion() throws IOException;
8 |
9 | }
10 |
--------------------------------------------------------------------------------
/javadrone-api/src/main/java/com/codeminders/ardrone/data/logger/DataLogger.java:
--------------------------------------------------------------------------------
1 | package com.codeminders.ardrone.data.logger;
2 |
3 | public interface DataLogger {
4 |
5 | void log(ChannelDataChunk data);
6 |
7 | void logStreamContent(int data);
8 |
9 | public void finish();
10 | }
11 |
--------------------------------------------------------------------------------
/javadrone-api/src/main/java/com/codeminders/ardrone/commands/QuitCommand.java:
--------------------------------------------------------------------------------
1 | package com.codeminders.ardrone.commands;
2 |
3 | import com.codeminders.ardrone.DroneCommand;
4 |
5 | public class QuitCommand extends DroneCommand
6 | {
7 | @Override
8 | public int getPriority()
9 | {
10 | return MAX_PRIORITY;
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/javadrone-api/src/main/java/com/codeminders/ardrone/data/navdata/NavDataFormatException.java:
--------------------------------------------------------------------------------
1 |
2 | package com.codeminders.ardrone.data.navdata;
3 |
4 | @SuppressWarnings("serial")
5 | public class NavDataFormatException extends Exception
6 | {
7 |
8 | public NavDataFormatException(String why)
9 | {
10 | super(why);
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/controltower/src/resources/log4j.properties:
--------------------------------------------------------------------------------
1 | # Set root logger level to DEBUG and its only appender to A1.
2 | log4j.rootLogger=ALL, A1
3 |
4 | # A1 is set to be a ConsoleAppender.
5 | log4j.appender.A1=org.apache.log4j.ConsoleAppender
6 |
7 | # A1 uses PatternLayout.
8 | log4j.appender.A1.layout=org.apache.log4j.PatternLayout
9 | log4j.appender.A1.layout.ConversionPattern=%r [%t] %-5p %c{2} %x - %m%n
--------------------------------------------------------------------------------
/javadrone-api/src/main/java/com/codeminders/ardrone/DroneStatusChangeListener.java:
--------------------------------------------------------------------------------
1 |
2 | package com.codeminders.ardrone;
3 |
4 | public interface DroneStatusChangeListener
5 | {
6 |
7 | /**
8 | * This method is called whenever the drone changes from BOOTSTRAP or
9 | * ERROR modes to DEMO mode. Could be used for user-supplied initialization
10 | */
11 | void ready();
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/javadrone-api/src/main/java/com/codeminders/ardrone/commands/FlatTrimCommand.java:
--------------------------------------------------------------------------------
1 | package com.codeminders.ardrone.commands;
2 |
3 | public class FlatTrimCommand extends ATCommand
4 | {
5 | @Override
6 | protected String getID()
7 | {
8 | return "FTRIM";
9 | }
10 |
11 | @Override
12 | protected Object[] getParameters()
13 | {
14 | return new Object[] {};
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/controltower-android/src/com/codeminders/ardrone/PS3ControllerHelp.java:
--------------------------------------------------------------------------------
1 | package com.codeminders.ardrone;
2 |
3 | import android.app.Activity;
4 | import android.os.Bundle;
5 |
6 | public class PS3ControllerHelp extends Activity {
7 | @Override
8 | public void onCreate(Bundle savedInstanceState) {
9 | super.onCreate(savedInstanceState);
10 | setContentView(R.layout.ps3_controller_help);
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/controltower/src/main/assembly/src.xml:
--------------------------------------------------------------------------------
1 |
2 | dist
3 |
4 | jar
5 |
6 | false
7 |
8 |
9 | /
10 | true
11 | true
12 | runtime
13 |
14 |
15 |
--------------------------------------------------------------------------------
/controltower-android/src/com/codeminders/ardrone/SettingsPrefs.java:
--------------------------------------------------------------------------------
1 | package com.codeminders.ardrone;
2 |
3 | import android.os.Bundle;
4 | import android.preference.PreferenceActivity;
5 |
6 | public class SettingsPrefs extends PreferenceActivity {
7 |
8 |
9 | @Override
10 | protected void onCreate(Bundle savedInstanceState) {
11 | super.onCreate(savedInstanceState);
12 | addPreferencesFromResource(R.xml.settings);
13 | }
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/javadrone-api/src/main/java/com/codeminders/ardrone/commands/TakeOffCommand.java:
--------------------------------------------------------------------------------
1 | package com.codeminders.ardrone.commands;
2 |
3 | public class TakeOffCommand extends RefCommand
4 | {
5 | public TakeOffCommand()
6 | {
7 | value |= (1<<9);
8 | }
9 |
10 | public boolean isSticky()
11 | {
12 | return true;
13 | }
14 |
15 | public String getCategory()
16 | {
17 | return LAND_TAKEOFF_CATEGORY;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/javadrone-api/src/main/java/com/codeminders/ardrone/controllers/decoders/ControllerStateDecoder.java:
--------------------------------------------------------------------------------
1 | package com.codeminders.ardrone.controllers.decoders;
2 |
3 | import java.io.IOException;
4 |
5 | import com.codeminders.ardrone.controllers.GameControllerState;
6 | import com.codeminders.ardrone.controllers.ControllerData;
7 |
8 | public interface ControllerStateDecoder {
9 |
10 | public GameControllerState decodeState(ControllerData data) throws IOException;
11 | }
12 |
--------------------------------------------------------------------------------
/javadrone-api/src/main/java/com/codeminders/ardrone/NavDataDecoder.java:
--------------------------------------------------------------------------------
1 | package com.codeminders.ardrone;
2 |
3 | import com.codeminders.ardrone.data.DataDecoder;
4 |
5 | public abstract class NavDataDecoder extends DataDecoder {
6 |
7 | private ARDrone drone;
8 |
9 | public NavDataDecoder(ARDrone drone) {
10 | this.drone = drone;
11 | }
12 |
13 | public void notifyDroneWithDecodedNavdata(NavData navdata) {
14 | drone.navDataReceived(navdata);
15 | }
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/javadrone-api/src/main/java/com/codeminders/ardrone/data/navdata/vision/Point.java:
--------------------------------------------------------------------------------
1 |
2 | package com.codeminders.ardrone.data.navdata.vision;
3 |
4 | public class Point
5 | {
6 | private int x;
7 | private int y;
8 |
9 | public Point(int x, int y)
10 | {
11 | super();
12 | this.x = x;
13 | this.y = y;
14 | }
15 |
16 | public int getX()
17 | {
18 | return x;
19 | }
20 |
21 | public int getY()
22 | {
23 | return y;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/controltower-android/res/menu/activity_main.xml:
--------------------------------------------------------------------------------
1 |
12 |
--------------------------------------------------------------------------------
/javadrone-api/src/main/java/com/codeminders/ardrone/commands/KeepAliveCommand.java:
--------------------------------------------------------------------------------
1 | package com.codeminders.ardrone.commands;
2 |
3 | public class KeepAliveCommand extends ATCommand
4 | {
5 |
6 | @Override
7 | protected String getID()
8 | {
9 | return "COMWDG";
10 | }
11 |
12 | @Override
13 | protected Object[] getParameters()
14 | {
15 | return new Object[] {};
16 | }
17 |
18 | @Override
19 | public int getPriority()
20 | {
21 | return VERY_HIGH_PRIORITY;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/javadrone-api/src/main/java/com/codeminders/ardrone/data/navdata/vision/Dimension.java:
--------------------------------------------------------------------------------
1 |
2 | package com.codeminders.ardrone.data.navdata.vision;
3 |
4 | public class Dimension
5 | {
6 | private int width;
7 | private int height;
8 |
9 | public Dimension(int width, int height)
10 | {
11 | super();
12 | this.width = width;
13 | this.height = height;
14 | }
15 |
16 | public int getWidth()
17 | {
18 | return width;
19 | }
20 |
21 | public int getHeight()
22 | {
23 | return height;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/javadrone-api/src/main/java/com/codeminders/ardrone/commands/LandCommand.java:
--------------------------------------------------------------------------------
1 | package com.codeminders.ardrone.commands;
2 |
3 | public class LandCommand extends RefCommand
4 | {
5 | public LandCommand()
6 | {
7 | // 9th bit set to 0
8 | }
9 |
10 | @Override
11 | public int getPriority()
12 | {
13 | return HIGH_PRIORITY;
14 | }
15 |
16 | public boolean isSticky()
17 | {
18 | return true;
19 | }
20 |
21 | public String getCategory()
22 | {
23 | return LAND_TAKEOFF_CATEGORY;
24 | }
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/javadrone-api/src/main/java/com/codeminders/ardrone/commands/RefCommand.java:
--------------------------------------------------------------------------------
1 | package com.codeminders.ardrone.commands;
2 |
3 | public class RefCommand extends ATCommand
4 | {
5 | protected int value;
6 |
7 | protected RefCommand()
8 | {
9 | value |= (1 << 18) | (1 << 20) | (1 << 22) | (1 << 24) | (1 << 28) ;
10 | }
11 |
12 | @Override
13 | protected String getID()
14 | {
15 | return "REF";
16 | }
17 |
18 | @Override
19 | protected Object[] getParameters()
20 | {
21 | return new Object[] { value };
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/javadrone-api/src/main/java/com/codeminders/ardrone/VideoDataDecoder.java:
--------------------------------------------------------------------------------
1 | package com.codeminders.ardrone;
2 |
3 | import com.codeminders.ardrone.data.DataDecoder;
4 |
5 | public abstract class VideoDataDecoder extends DataDecoder {
6 |
7 | private ARDrone drone;
8 |
9 | public VideoDataDecoder(ARDrone drone) {
10 | this.drone = drone;
11 | }
12 |
13 | public void notifyDroneWithDecodedFrame(int startX, int startY, int width, int height, int[] rgbArray, int offset, int scansize) {
14 | drone.videoFrameReceived(startX, startY, width, height, rgbArray, offset, scansize);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/javadrone-api/src/main/java/com/codeminders/ardrone/commands/ControlCommand.java:
--------------------------------------------------------------------------------
1 | package com.codeminders.ardrone.commands;
2 |
3 | public class ControlCommand extends ATCommand
4 | {
5 | protected int arg1;
6 | protected int arg2;
7 |
8 | public ControlCommand(int arg1, int arg2)
9 | {
10 | this.arg1 = arg1;
11 | this.arg2 = arg2;
12 | }
13 |
14 | @Override
15 | protected String getID()
16 | {
17 | return "CTRL";
18 | }
19 |
20 | @Override
21 | protected Object[] getParameters()
22 | {
23 | return new Object[] { arg1, arg2 };
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/.hgignore:
--------------------------------------------------------------------------------
1 | syntax:glob
2 | *~
3 | controltower/.settings/*
4 | controltower/target/*
5 | controltower/.classpath
6 | controltower/.project
7 | controltower-android/.settings/*
8 | controltower-android/target/*
9 | controltower-android/bin/*
10 | controltower-android/gen/*
11 | controltower-android/.classpath
12 | controltower-android/.project
13 | javadrone-api/.settings/*
14 | javadrone-api/target/*
15 | javadrone-api/bin/*
16 | javadrone-api/gen/*
17 | javadrone-api/.classpath
18 | javadrone-api/.project
19 | javadrone-utils/.settings/*
20 | javadrone-utils/target/*
21 | javadrone-utils/.classpath
22 | javadrone-utils/.project
23 |
--------------------------------------------------------------------------------
/javadrone-utils/src/main/java/com/codeminders/ardrone/logs/video/PlayerFrame.java:
--------------------------------------------------------------------------------
1 | package com.codeminders.ardrone.logs.video;
2 |
3 | import java.awt.Graphics;
4 | import java.awt.Image;
5 |
6 | import javax.swing.JPanel;
7 |
8 | public class PlayerFrame extends JPanel {
9 |
10 | private static final long serialVersionUID = 5986493337737408886L;
11 |
12 | public Image lastFrame;
13 |
14 | public void paint(Graphics g) {
15 | Image img = lastFrame;
16 | if(img != null) {
17 | g.drawImage(lastFrame, 0, 0, img.getWidth(this), img.getHeight(this), this);
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/javadrone-api/src/main/java/com/codeminders/ardrone/commands/ConfigureCommand.java:
--------------------------------------------------------------------------------
1 | package com.codeminders.ardrone.commands;
2 |
3 | public class ConfigureCommand extends ATCommand
4 | {
5 | protected String name;
6 | protected String value;
7 |
8 | public ConfigureCommand(String name, String value)
9 | {
10 | this.name = name;
11 | this.value = value;
12 | }
13 |
14 | @Override
15 | protected String getID()
16 | {
17 | return "CONFIG";
18 | }
19 |
20 | @Override
21 | protected Object[] getParameters()
22 | {
23 | return new Object[] { name, value };
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/javadrone-api/src/main/java/com/codeminders/ardrone/controllers/ControllerData.java:
--------------------------------------------------------------------------------
1 | package com.codeminders.ardrone.controllers;
2 |
3 | public class ControllerData {
4 | private byte[] buf;
5 | int actualBufferDataLength;
6 |
7 | public ControllerData(byte[] buf, int actualBufferDataLength) {
8 | super();
9 | this.buf = buf;
10 | this.actualBufferDataLength = actualBufferDataLength;
11 | }
12 | public byte[] getBuffer() {
13 | return buf;
14 | }
15 | public int getActualBufferDataLength() {
16 | return actualBufferDataLength;
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/javadrone-api/project.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must be checked in Version Control Systems.
5 | #
6 | # To customize properties used by the Ant build system edit
7 | # "ant.properties", and override values to adapt the script to your
8 | # project structure.
9 | #
10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
12 |
13 | # Project target.
14 | target=android-8
15 | android.library=true
16 |
--------------------------------------------------------------------------------
/javadrone-api/src/main/java/com/codeminders/ardrone/data/ARDroneDataReader.java:
--------------------------------------------------------------------------------
1 | package com.codeminders.ardrone.data;
2 |
3 | import java.io.IOException;
4 | import java.io.InputStream;
5 |
6 | public interface ARDroneDataReader {
7 | /**
8 | * @param buf input data buffer to read;
9 | * @return length of data that is obtained from ardrone
10 | * @throws IOException
11 | */
12 | public int readDataBlock(byte[] buf) throws IOException;
13 |
14 | public InputStream getDataStream();
15 |
16 | public boolean isStreamSupported();
17 |
18 | public void reconnect() throws IOException;
19 |
20 | public void finish();
21 | }
22 |
--------------------------------------------------------------------------------
/javadrone-api/src/main/java/com/codeminders/ardrone/commands/PlayAnimationCommand.java:
--------------------------------------------------------------------------------
1 | package com.codeminders.ardrone.commands;
2 |
3 | public class PlayAnimationCommand extends ATCommand
4 | {
5 | protected int animation_no;
6 | protected int duration;
7 |
8 | public PlayAnimationCommand(int animation_no, int duration)
9 | {
10 | this.animation_no = animation_no;
11 | this.duration = duration;
12 | }
13 |
14 | @Override
15 | protected String getID()
16 | {
17 | return "ANIM";
18 | }
19 |
20 | @Override
21 | protected Object[] getParameters()
22 | {
23 | return new Object[] { animation_no, duration };
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/javadrone-api/src/main/java/com/codeminders/ardrone/data/logger/LogStreamWrapper.java:
--------------------------------------------------------------------------------
1 | package com.codeminders.ardrone.data.logger;
2 |
3 | import java.io.IOException;
4 | import java.io.InputStream;
5 |
6 | public class LogStreamWrapper extends InputStream {
7 |
8 | InputStream dataStream;
9 | DataLogger logger;
10 |
11 | public LogStreamWrapper(InputStream dataStream, DataLogger logger) {
12 | this.dataStream = dataStream;
13 | this.logger = logger;
14 | }
15 |
16 | @Override
17 | public int read() throws IOException {
18 | int data = dataStream.read();
19 | logger.logStreamContent(data);
20 | return data;
21 | }
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/controltower-android/project.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must be checked in Version Control Systems.
5 | #
6 | # To customize properties used by the Ant build system edit
7 | # "ant.properties", and override values to adapt the script to your
8 | # project structure.
9 | #
10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
12 |
13 | # Project target.
14 | target=android-8
15 | android.library=false
16 | android.library.reference.1=../javadrone-api
17 |
--------------------------------------------------------------------------------
/javadrone-api/src/main/java/com/codeminders/ardrone/data/navdata/FlyingState.java:
--------------------------------------------------------------------------------
1 | package com.codeminders.ardrone.data.navdata;
2 |
3 | public enum FlyingState
4 | {
5 | FLYING, TAKING_OFF, LANDING, LANDED;
6 |
7 | public static FlyingState fromControlState(CtrlState state)
8 | {
9 | switch(state)
10 | {
11 | case FLYING:
12 | case HOVERING:
13 | case TRANS_GOTOFIX:
14 | return FlyingState.FLYING;
15 |
16 | case TRANS_TAKEOFF:
17 | return FlyingState.TAKING_OFF;
18 |
19 | case TRANS_LANDING:
20 | return FlyingState.LANDING;
21 |
22 | default:
23 | return FlyingState.LANDED;
24 | }
25 | }
26 | }
--------------------------------------------------------------------------------
/controltower-android/res/layout/ps3_controller_help.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
15 |
16 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 | 4.0.0
5 | com.codeminders
6 | javadrone
7 | 1.3
8 | javadrone
9 | pom
10 | Java API and demo programs to control Parrot's AR.Drone
11 |
12 | javadrone-api
13 | javadrone-utils
14 | controltower
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/javadrone-api/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
15 |
16 |
--------------------------------------------------------------------------------
/javadrone-api/src/main/java/com/codeminders/ardrone/commands/MoveCommand.java:
--------------------------------------------------------------------------------
1 | package com.codeminders.ardrone.commands;
2 |
3 | public class MoveCommand extends PCMDCommand
4 | {
5 | public MoveCommand(boolean combined_yaw_enabled,
6 | float left_right_tilt,
7 | float front_back_tilt,
8 | float vertical_speed,
9 | float angular_speed)
10 | {
11 | super(false);
12 | this.combined_yaw_enabled = combined_yaw_enabled;
13 | this.left_right_tilt = left_right_tilt;
14 | this.front_back_tilt = front_back_tilt;
15 | this.vertical_speed = vertical_speed;
16 | this.angular_speed = angular_speed;
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/javadrone-api/src/main/java/com/codeminders/ardrone/commands/PlayLEDCommand.java:
--------------------------------------------------------------------------------
1 | package com.codeminders.ardrone.commands;
2 |
3 | public class PlayLEDCommand extends ATCommand
4 | {
5 | protected int animation_no;
6 | protected float frequency;
7 | protected int duration;
8 |
9 | public PlayLEDCommand(int animation_no, float frequency, int duration)
10 | {
11 | this.animation_no = animation_no;
12 | this.frequency = frequency;
13 | this.duration = duration;
14 | }
15 |
16 | @Override
17 | protected String getID()
18 | {
19 | return "LED";
20 | }
21 |
22 | @Override
23 | protected Object[] getParameters()
24 | {
25 | return new Object[] { animation_no, frequency, duration };
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/javadrone-utils/src/main/java/com/codeminders/ardrone/util/RecordingSuccessCallback.java:
--------------------------------------------------------------------------------
1 |
2 | package com.codeminders.ardrone.util;
3 |
4 | public interface RecordingSuccessCallback
5 | {
6 |
7 | /**
8 | * This method will be called if file was successfully recorded
9 | *
10 | * @param filename - full path to recorded file
11 | */
12 | public void recordingSuccess(String filename);
13 |
14 | /**
15 | * This method will be called if file recording failed
16 | *
17 | * @param filename - file name we attempted to record. Could be null.
18 | * @param err - error message. Could be null.
19 | * @param ex - throwable, which caused the error. Could be null.
20 | */
21 | public void recordingError(String filename, String err, Throwable ex);
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/javadrone-utils/src/main/java/com/codeminders/ardrone/decoder/FileDataReaderAndDecoder.java:
--------------------------------------------------------------------------------
1 | package com.codeminders.ardrone.decoder;
2 |
3 | import java.io.File;
4 | import java.io.FileNotFoundException;
5 | import java.nio.ByteBuffer;
6 |
7 | import com.codeminders.ardrone.data.DataDecoder;
8 | import com.codeminders.ardrone.data.reader.FileDataReader;
9 |
10 | public class FileDataReaderAndDecoder extends FileDataReader {
11 |
12 | DataDecoder dataDecoder;
13 |
14 | public FileDataReaderAndDecoder(File dataFile, DataDecoder dataDecoder) throws FileNotFoundException {
15 | super(dataFile);
16 | this.dataDecoder = dataDecoder;
17 | }
18 |
19 | @Override
20 | public void handleData(ByteBuffer inbuf, int len) throws Exception {
21 | // dataDecoder.decodeData(inbuf, len);
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/javadrone-api/proguard-project.txt:
--------------------------------------------------------------------------------
1 | # To enable ProGuard in your project, edit project.properties
2 | # to define the proguard.config property as described in that file.
3 | #
4 | # Add project specific ProGuard rules here.
5 | # By default, the flags in this file are appended to flags specified
6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt
7 | # You can edit the include path and order by changing the ProGuard
8 | # include property in project.properties.
9 | #
10 | # For more details, see
11 | # http://developer.android.com/guide/developing/tools/proguard.html
12 |
13 | # Add any project specific keep options here:
14 |
15 | # If your project uses WebView with JS, uncomment the following
16 | # and specify the fully qualified class name to the JavaScript interface
17 | # class:
18 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
19 | # public *;
20 | #}
21 |
--------------------------------------------------------------------------------
/controltower-android/proguard-project.txt:
--------------------------------------------------------------------------------
1 | # To enable ProGuard in your project, edit project.properties
2 | # to define the proguard.config property as described in that file.
3 | #
4 | # Add project specific ProGuard rules here.
5 | # By default, the flags in this file are appended to flags specified
6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt
7 | # You can edit the include path and order by changing the ProGuard
8 | # include property in project.properties.
9 | #
10 | # For more details, see
11 | # http://developer.android.com/guide/developing/tools/proguard.html
12 |
13 | # Add any project specific keep options here:
14 |
15 | # If your project uses WebView with JS, uncomment the following
16 | # and specify the fully qualified class name to the JavaScript interface
17 | # class:
18 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
19 | # public *;
20 | #}
21 |
--------------------------------------------------------------------------------
/javadrone-utils/src/main/java/com/codeminders/ardrone/util/BufferedImageVideoListener.java:
--------------------------------------------------------------------------------
1 |
2 | package com.codeminders.ardrone.util;
3 |
4 | import java.awt.image.BufferedImage;
5 |
6 | import com.codeminders.ardrone.DroneVideoListener;
7 |
8 | /**
9 | * This is convenience base class for DroneVideoListener implementors, which
10 | * presents video frames to user as instances of java.awt.image.BufferedImag
11 | *
12 | * @author lord
13 | */
14 | public abstract class BufferedImageVideoListener implements DroneVideoListener
15 | {
16 | @Override
17 | public void frameReceived(int startX, int startY, int w, int h, int[] rgbArray, int offset, int scansize)
18 | {
19 | BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
20 | image.setRGB(startX, startY, w, h, rgbArray, offset, scansize);
21 | imageReceived(image);
22 | }
23 |
24 | public abstract void imageReceived(BufferedImage image);
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/javadrone-api/src/main/java/com/codeminders/ardrone/data/navdata/CtrlState.java:
--------------------------------------------------------------------------------
1 | package com.codeminders.ardrone.data.navdata;
2 |
3 |
4 | public enum CtrlState
5 | {
6 | DEFAULT, INIT, LANDED, FLYING, HOVERING, TEST, TRANS_TAKEOFF, TRANS_GOTOFIX, TRANS_LANDING;
7 |
8 | public static CtrlState fromInt(int v) throws NavDataFormatException
9 | {
10 | switch(v)
11 | {
12 | case 0:
13 | return DEFAULT;
14 | case 1:
15 | return INIT;
16 | case 2:
17 | return LANDED;
18 | case 3:
19 | return FLYING;
20 | case 4:
21 | return HOVERING;
22 | case 5:
23 | return TEST;
24 | case 6:
25 | return TRANS_TAKEOFF;
26 | case 7:
27 | return TRANS_GOTOFIX;
28 | case 8:
29 | return TRANS_LANDING;
30 | default:
31 | throw new NavDataFormatException("Invalid control state " + v);
32 | }
33 | }
34 | }
--------------------------------------------------------------------------------
/javadrone-api/src/main/java/com/codeminders/ardrone/data/navdata/NavDataTag.java:
--------------------------------------------------------------------------------
1 | package com.codeminders.ardrone.data.navdata;
2 |
3 | public enum NavDataTag
4 | {
5 | NAVDATA_DEMO_TAG(0), NAVDATA_TIME_TAG(1), NAVDATA_RAW_MEASURES_TAG(2), NAVDATA_PHYS_MEASURES_TAG(3), NAVDATA_GYROS_OFFSETS_TAG(
6 | 4), NAVDATA_EULER_ANGLES_TAG(5), NAVDATA_REFERENCES_TAG(6), NAVDATA_TRIMS_TAG(7), NAVDATA_RC_REFERENCES_TAG(
7 | 8), NAVDATA_PWM_TAG(9), NAVDATA_ALTITUDE_TAG(10), NAVDATA_VISION_RAW_TAG(11), NAVDATA_VISION_OF_TAG(12), NAVDATA_VISION_TAG(
8 | 13), NAVDATA_VISION_PERF_TAG(14), NAVDATA_TRACKERS_SEND_TAG(15), NAVDATA_VISION_DETECT_TAG(16), NAVDATA_WATCHDOG_TAG(
9 | 17), NAVDATA_ADC_DATA_FRAME_TAG(18), NAVDATA_VIDEO_STREAM_TAG(19), NAVDATA_CKS_TAG(0xFFFF);
10 |
11 | private int value;
12 |
13 | private NavDataTag(int value)
14 | {
15 | this.value = value;
16 | }
17 |
18 | public int getValue()
19 | {
20 | return value;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/javadrone-api/src/main/java/com/codeminders/ardrone/commands/PCMDCommand.java:
--------------------------------------------------------------------------------
1 | package com.codeminders.ardrone.commands;
2 |
3 | public class PCMDCommand extends ATCommand
4 | {
5 | protected boolean hover;
6 | protected boolean combined_yaw_enabled;
7 | protected float left_right_tilt;
8 | protected float front_back_tilt;
9 | protected float vertical_speed;
10 | protected float angular_speed;
11 |
12 |
13 | protected PCMDCommand(boolean hover)
14 | {
15 | this.hover = hover;
16 | }
17 |
18 | @Override
19 | protected String getID()
20 | {
21 | return "PCMD";
22 | }
23 |
24 | @Override
25 | protected Object[] getParameters()
26 | {
27 | if(hover)
28 | return new Object[] { 0, 0f, 0f, 0f, 0f };
29 |
30 | // int mode = combined_yaw_enabled ? 1 : 0;
31 | int mode = 1;
32 | if(combined_yaw_enabled)
33 | mode |= (1<<1);
34 |
35 | return new Object[] { mode, left_right_tilt, front_back_tilt, vertical_speed, angular_speed };
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/javadrone-api/src/main/java/com/codeminders/ardrone/controllers/Controller.java:
--------------------------------------------------------------------------------
1 |
2 | package com.codeminders.ardrone.controllers;
3 |
4 | import java.io.IOException;
5 |
6 | /**
7 | * Base abstract class for supported controllers
8 | *
9 | * @author lord
10 | *
11 | */
12 | public abstract class Controller
13 | {
14 |
15 | public abstract void close() throws IOException;
16 |
17 | public abstract String getName();
18 |
19 | public abstract String getManufacturerString();
20 |
21 | public abstract String getProductString();
22 |
23 | public abstract GameControllerState read() throws IOException;
24 |
25 | @Override
26 | public String toString()
27 | {
28 | StringBuilder builder = new StringBuilder();
29 | builder.append(getName() + " [");
30 | builder.append("manufacturer=");
31 | builder.append(getManufacturerString());
32 | builder.append(", product=");
33 | builder.append(getProductString());
34 | builder.append("]");
35 | return builder.toString();
36 | }
37 |
38 | }
--------------------------------------------------------------------------------
/javadrone-api/src/main/java/com/codeminders/ardrone/data/logger/ChannelDataChunk.java:
--------------------------------------------------------------------------------
1 | package com.codeminders.ardrone.data.logger;
2 |
3 | import java.io.DataInputStream;
4 | import java.io.DataOutputStream;
5 | import java.io.IOException;
6 |
7 | public class ChannelDataChunk {
8 |
9 | byte[] data;
10 | long timemark;
11 |
12 | public ChannelDataChunk(byte[] data, long timemark) {
13 | super();
14 | this.data = data;
15 | this.timemark = timemark;
16 | }
17 |
18 | public byte[] getData() {
19 | return data;
20 | }
21 | public long getIoDelay() {
22 | return timemark;
23 | }
24 |
25 | public void writeToStream(DataOutputStream out) throws IOException {
26 | out.writeLong(timemark);
27 | out.writeInt(data.length);
28 | out.write(data, 0, data.length);
29 | }
30 |
31 | public static ChannelDataChunk readFromStream(DataInputStream in) throws IOException {
32 | long delay = in.readLong();
33 | byte[] dt = new byte[in.readInt()];
34 | in.readFully(dt);
35 |
36 | return new ChannelDataChunk(dt, delay);
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/controltower-android/src/com/codeminders/ardrone/controller/usbhost/SonyPS3UsbHostController.java:
--------------------------------------------------------------------------------
1 | package com.codeminders.ardrone.controller.usbhost;
2 |
3 | import java.io.IOException;
4 |
5 | import android.hardware.usb.UsbDevice;
6 | import android.hardware.usb.UsbManager;
7 |
8 | import com.codeminders.ardrone.controllers.decoders.ControllerStateDecoder;
9 | import com.codeminders.ardrone.controllers.decoders.SonyPS3ControllerStateDecoder;
10 |
11 | public class SonyPS3UsbHostController extends UsbHostController {
12 |
13 | private static final int VENDOR_ID = 1356;
14 | private static final int PRODUCT_ID = 616;
15 |
16 | static ControllerStateDecoder decoder = new SonyPS3ControllerStateDecoder();
17 |
18 | public SonyPS3UsbHostController(UsbDevice dev, UsbManager manager) throws IOException {
19 | super(dev, manager, decoder);
20 | }
21 |
22 | @Override
23 | public String getName() {
24 | return "SonyPS3Controller over usb host";
25 | }
26 |
27 | public static boolean isA(UsbDevice dev)
28 | {
29 | return(dev.getVendorId() == VENDOR_ID && dev.getProductId() == PRODUCT_ID);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/controltower-android/src/com/codeminders/ardrone/controller/usbhost/AfterGlowUsbHostController.java:
--------------------------------------------------------------------------------
1 | package com.codeminders.ardrone.controller.usbhost;
2 |
3 | import java.io.IOException;
4 |
5 | import android.annotation.SuppressLint;
6 | import android.hardware.usb.UsbDevice;
7 | import android.hardware.usb.UsbManager;
8 |
9 | import com.codeminders.ardrone.controllers.decoders.AfterGlowControllerDecoder;
10 | import com.codeminders.ardrone.controllers.decoders.ControllerStateDecoder;
11 |
12 | @SuppressLint("NewApi")
13 | public class AfterGlowUsbHostController extends UsbHostController {
14 |
15 | private static final int VENDOR_ID = 3695;
16 | private static final int PRODUCT_ID = 25346;
17 |
18 | static ControllerStateDecoder decoder = new AfterGlowControllerDecoder();
19 |
20 | public AfterGlowUsbHostController(UsbDevice dev, UsbManager manager) throws IOException {
21 | super(dev, manager, decoder);
22 | }
23 |
24 | @Override
25 | public String getName() {
26 | return "SonyPS3Controller over usb host";
27 | }
28 |
29 | public static boolean isA(UsbDevice dev)
30 | {
31 | return(dev.getVendorId() == VENDOR_ID && dev.getProductId() == PRODUCT_ID);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/javadrone-api/src/main/java/com/codeminders/ardrone/data/ChannelProcessor.java:
--------------------------------------------------------------------------------
1 | package com.codeminders.ardrone.data;
2 |
3 | import java.util.logging.Level;
4 | import java.util.logging.Logger;
5 |
6 |
7 | public class ChannelProcessor {
8 |
9 | private Logger log = Logger.getLogger(getClass().getName());
10 | ARDroneDataReader reader;
11 | DataDecoder decoder;
12 |
13 | private static int STOP_TIMEOUT = 3000; // 3 sec.
14 |
15 | public ChannelProcessor(ARDroneDataReader reader, DataDecoder decoder) {
16 | super();
17 | this.reader = reader;
18 | this.decoder = decoder;
19 |
20 | decoder.setDataReader(reader); // decoder and reader is now linked
21 | decoder.start();
22 | }
23 |
24 | public void finish() {
25 | decoder.finish();
26 | try {
27 | decoder.join(STOP_TIMEOUT);
28 | } catch (InterruptedException e) {
29 | log.log(Level.FINEST, "Waiting till decoder is stopped is interrupted", e);
30 | }
31 | reader.finish();
32 | }
33 |
34 | public void pause() {
35 | decoder.pauseDecoding();
36 | }
37 |
38 | public void resume() {
39 | decoder.pauseDecoding();
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/javadrone-utils/src/main/java/com/codeminders/ardrone/controllers/hid/manager/HIDControllerFinder.java:
--------------------------------------------------------------------------------
1 | package com.codeminders.ardrone.controllers.hid.manager;
2 |
3 | import java.io.IOException;
4 |
5 | import com.codeminders.ardrone.controllers.Controller;
6 | import com.codeminders.ardrone.controllers.hid.HIDAPIAfterGlowController;
7 | import com.codeminders.ardrone.controllers.hid.HIDAPIMotioninJoyVirtualController;
8 | import com.codeminders.ardrone.controllers.hid.HIDAPISonyPS3Controller;
9 | import com.codeminders.hidapi.HIDDeviceInfo;
10 | import com.codeminders.hidapi.HIDManager;
11 |
12 | public class HIDControllerFinder {
13 |
14 | public static Controller findController() throws IOException
15 | {
16 |
17 | HIDDeviceInfo[] devs = HIDManager.getInstance().listDevices();
18 | if (null != devs) {
19 | for(int i = 0; i < devs.length; i++)
20 | {
21 | if(HIDAPIAfterGlowController.isA(devs[i]))
22 | return new HIDAPIAfterGlowController(devs[i]);
23 | if(HIDAPISonyPS3Controller.isA(devs[i]))
24 | return new HIDAPISonyPS3Controller(devs[i]);
25 | if(HIDAPIMotioninJoyVirtualController.isA(devs[i]))
26 | return new HIDAPIMotioninJoyVirtualController(devs[i]);
27 | }
28 | }
29 | return null;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/javadrone-api/src/main/java/com/codeminders/ardrone/examples/TakeOffAndLand.java:
--------------------------------------------------------------------------------
1 |
2 | package com.codeminders.ardrone.examples;
3 |
4 | import com.codeminders.ardrone.ARDrone;
5 |
6 | public class TakeOffAndLand
7 | {
8 |
9 | private static final long CONNECT_TIMEOUT = 3000;
10 |
11 | /**
12 | * @param args
13 | */
14 | public static void main(String[] args)
15 | {
16 | ARDrone drone;
17 | try
18 | {
19 | // Create ARDrone object,
20 | // connect to drone and initialize it.
21 | drone = new ARDrone();
22 | drone.connect();
23 | drone.clearEmergencySignal();
24 |
25 | // Wait until drone is ready
26 | drone.waitForReady(CONNECT_TIMEOUT);
27 |
28 | // do TRIM operation
29 | drone.trim();
30 |
31 | // Take off
32 | System.err.println("Taking off");
33 | drone.takeOff();
34 |
35 | // Fly a little :)
36 | Thread.sleep(5000);
37 |
38 | // Land
39 | System.err.println("Landing");
40 | drone.land();
41 |
42 | // Give it some time to land
43 | Thread.sleep(2000);
44 |
45 | // Disconnect from the done
46 | drone.disconnect();
47 |
48 | } catch(Throwable e)
49 | {
50 | e.printStackTrace();
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/controltower/src/resources/log.properties:
--------------------------------------------------------------------------------
1 | # Properties file which configures the operation of the JDK
2 | # logging facility.
3 |
4 | # The system will look for this config file, first using
5 | # a System property specified at startup:
6 | #
7 | # >java -Djava.util.logging.config.file=myLoggingConfigFilePath
8 | #
9 | # If this property is not specified, then the config file is
10 | # retrieved from its default location at:
11 | #
12 | # JDK_HOME/jre/lib/logging.properties
13 |
14 | # Global logging properties.
15 | # ------------------------------------------
16 | # The set of handlers to be loaded upon startup.
17 | # Comma-separated list of class names.
18 | # (? LogManager docs say no comma here, but JDK example has comma.)
19 | handlers=java.util.logging.ConsoleHandler
20 |
21 | # Default global logging level.
22 | # Loggers and Handlers may override this level
23 | .level=INFO
24 |
25 | # Loggers
26 | # ------------------------------------------
27 | # Loggers are usually attached to packages.
28 | # Here, the level for each package is specified.
29 | # The global level is used by default, so levels
30 | # specified here simply act as an override.
31 | com.codeminders.ardrone.level=ALL
32 | com.codeminders.controltower.level=SEVERE
33 |
34 | # Handlers
35 | # -----------------------------------------
36 |
37 | # --- ConsoleHandler ---
38 | # Override of global logging level
39 | java.util.logging.ConsoleHandler.level=ALL
40 | java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter
--------------------------------------------------------------------------------
/javadrone-api/src/main/java/com/codeminders/ardrone/data/logger/ARDroneDataReaderAndLogWrapper.java:
--------------------------------------------------------------------------------
1 | package com.codeminders.ardrone.data.logger;
2 |
3 | import java.io.IOException;
4 | import java.io.InputStream;
5 |
6 | import com.codeminders.ardrone.data.ARDroneDataReader;
7 |
8 | public class ARDroneDataReaderAndLogWrapper implements ARDroneDataReader {
9 |
10 | ARDroneDataReader reader;
11 | DataLogger logger;
12 |
13 | public ARDroneDataReaderAndLogWrapper(ARDroneDataReader reader, DataLogger logger) {
14 | super();
15 | this.reader = reader;
16 | this.logger = logger;
17 | }
18 |
19 | @Override
20 | public int readDataBlock(byte[] buf) throws IOException {
21 | int len = reader.readDataBlock(buf);
22 | if (len > 0) {
23 | byte[] data = new byte[len];
24 | System.arraycopy(buf,0, data, 0, len);
25 | logger.log(new ChannelDataChunk(data, System.currentTimeMillis()));
26 | }
27 | return len;
28 | }
29 |
30 | @Override
31 | public InputStream getDataStream() {
32 | return new LogStreamWrapper(reader.getDataStream(), logger);
33 | }
34 |
35 | @Override
36 | public boolean isStreamSupported() {
37 | return reader.isStreamSupported();
38 | }
39 |
40 | @Override
41 | public void reconnect() throws IOException {
42 | reader.reconnect();
43 | }
44 |
45 | @Override
46 | public void finish() {
47 | reader.finish();
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/controltower/src/main/java/com/codeminders/controltower/VideoPanel.form:
--------------------------------------------------------------------------------
1 |
2 |
3 |
22 |
--------------------------------------------------------------------------------
/controltower-android/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
14 |
15 |
19 |
23 |
24 |
25 |
26 |
27 |
28 |
32 |
33 |
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/javadrone-utils/src/main/java/com/codeminders/ardrone/util/ImageVideoRecorderBase.java:
--------------------------------------------------------------------------------
1 |
2 | package com.codeminders.ardrone.util;
3 |
4 | import java.io.File;
5 | import java.io.IOException;
6 | import java.text.DecimalFormat;
7 |
8 |
9 | public abstract class ImageVideoRecorderBase extends BufferedImageVideoListener
10 | {
11 | private DecimalFormat format;
12 |
13 | protected File base_path;
14 | protected int seq;
15 | protected String prefix;
16 | protected RecordingSuccessCallback callback;
17 |
18 | public ImageVideoRecorderBase(File base_path, int starting_seq, String prefix, RecordingSuccessCallback callback)
19 | {
20 | this.base_path = base_path;
21 | this.seq = starting_seq;
22 | this.prefix = prefix;
23 | this.callback = callback;
24 |
25 | format = new java.text.DecimalFormat("0000");
26 | }
27 |
28 | public abstract String getExtension();
29 |
30 | protected File openFile() throws IOException
31 | {
32 | while(seq < 9999)
33 | {
34 | String fname = generateFileName();
35 | File f = new File(base_path, fname);
36 | if(f.createNewFile())
37 | return f;
38 | seq++;
39 | continue;
40 | }
41 | throw new IOException("Filename space is exhausted. Could not create file");
42 | }
43 |
44 | private String generateFileName()
45 | {
46 | return prefix + format.format(new Integer(seq)) + getExtension();
47 | }
48 |
49 | }
50 |
--------------------------------------------------------------------------------
/controltower/src/main/java/com/codeminders/controltower/config/AudioPlayer.java:
--------------------------------------------------------------------------------
1 |
2 | package com.codeminders.controltower.config;
3 |
4 | import java.io.BufferedInputStream;
5 |
6 | import javax.sound.sampled.AudioFormat;
7 | import javax.sound.sampled.AudioInputStream;
8 | import javax.sound.sampled.AudioSystem;
9 | import javax.sound.sampled.DataLine;
10 | import javax.sound.sampled.SourceDataLine;
11 |
12 | public class AudioPlayer
13 | {
14 |
15 | private static final int EXTERNAL_BUFFER_SIZE = 128000;
16 |
17 | public static synchronized void playResource(Class resclass, String resname) throws Exception
18 | {
19 | play(AudioSystem.getAudioInputStream(new BufferedInputStream(resclass.getResourceAsStream(resname))));
20 | }
21 |
22 | public static synchronized void play(AudioInputStream audioInputStream) throws Exception
23 | {
24 |
25 | AudioFormat audioFormat = audioInputStream.getFormat();
26 | SourceDataLine line = null;
27 | DataLine.Info info = new DataLine.Info(SourceDataLine.class, audioFormat);
28 | try
29 | {
30 | line = (SourceDataLine) AudioSystem.getLine(info);
31 | line.open(audioFormat);
32 | line.start();
33 |
34 | int nBytesRead = 0;
35 | byte[] abData = new byte[EXTERNAL_BUFFER_SIZE];
36 | while((nBytesRead = audioInputStream.read(abData, 0, abData.length)) > 0)
37 | {
38 | line.write(abData, 0, nBytesRead);
39 | }
40 | } finally
41 | {
42 | if(line != null)
43 | {
44 | line.drain();
45 | line.close();
46 | }
47 | }
48 | }
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/javadrone-api/src/main/java/com/codeminders/ardrone/data/DataDecoder.java:
--------------------------------------------------------------------------------
1 | package com.codeminders.ardrone.data;
2 |
3 | import java.util.logging.Level;
4 | import java.util.logging.Logger;
5 |
6 |
7 | public abstract class DataDecoder extends Thread {
8 |
9 | private Logger log = Logger.getLogger(this.getClass().getName());
10 |
11 | private ARDroneDataReader datareader;
12 | private boolean pauseFlag;
13 |
14 |
15 | @Override
16 | public synchronized void start() {
17 | super.start();
18 | if (null == datareader) {
19 | throw new RuntimeException("No reading thread is arrached");
20 | }
21 | }
22 |
23 | protected void pauseCheck(){
24 | if (pauseFlag) {
25 | synchronized(this) {
26 | if (pauseFlag) {
27 | try {
28 | wait();
29 | } catch (InterruptedException e) {
30 | log.log(Level.SEVERE, "Pause is interrupted", e);
31 | }
32 | }
33 | }
34 | }
35 | }
36 |
37 | protected void setDataReader(ARDroneDataReader datareader) {
38 | if (this.isAlive()) {
39 | throw new RuntimeException("Rading Thrad already started. You can't change stream on fly");
40 | }
41 | this.datareader = datareader;
42 | }
43 |
44 | public ARDroneDataReader getDataReader() {
45 | return datareader;
46 | }
47 |
48 | public synchronized void pauseDecoding() {
49 | pauseFlag = true;
50 | }
51 |
52 | public synchronized void resumeDecoding() {
53 | pauseFlag = false;
54 | notify();
55 | }
56 |
57 | public abstract void finish();
58 |
59 | }
60 |
--------------------------------------------------------------------------------
/lib/maven/com/twilight/h264-decoder/1.0/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 |
5 | com.twilight
6 | h264-decoder
7 |
8 | jar
9 | JAVA H264 Decoder
10 | 1.0
11 | A pure JAVA H264 Decoder ported from FFmpeg (libavcodec) library
12 | https://code.google.com/p/h264j/
13 |
14 | h264-decoder
15 | ./src
16 |
17 |
18 | org.apache.maven.plugins
19 | maven-compiler-plugin
20 | true
21 |
22 | 1.6
23 | 1.6
24 |
25 |
26 |
27 | org.apache.maven.plugins
28 | maven-javadoc-plugin
29 | 2.8.1
30 |
31 |
32 | attach-javadocs
33 |
34 | jar
35 |
36 |
37 |
38 |
39 |
40 | org.apache.maven.plugins
41 | maven-source-plugin
42 | 2.1.2
43 |
44 |
45 | attach-sources
46 | verify
47 |
48 | jar
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/javadrone-utils/src/main/java/com/codeminders/ardrone/tools/ControllerTest.java:
--------------------------------------------------------------------------------
1 |
2 | package com.codeminders.ardrone.tools;
3 |
4 | import java.io.IOException;
5 |
6 | import com.codeminders.ardrone.controllers.*;
7 | import com.codeminders.ardrone.controllers.hid.manager.HIDControllerFinder;
8 | import com.codeminders.hidapi.ClassPathLibraryLoader;
9 |
10 | public class ControllerTest
11 | {
12 | private static final long READ_UPDATE_DELAY_MS = 30L;
13 |
14 | static
15 | {
16 | ClassPathLibraryLoader.loadNativeHIDLibrary();
17 | }
18 |
19 | /**
20 | * @param args
21 | */
22 | public static void main(String[] args)
23 | {
24 | try
25 | {
26 | Controller c = findController();
27 | if(c == null)
28 | {
29 | System.err.println("Controller not found");
30 | System.exit(1);
31 | } else
32 | {
33 | System.err.println("Controller found "+c);
34 | }
35 | try
36 | {
37 | while(true)
38 | {
39 |
40 | GameControllerState x = c.read();
41 | System.err.println(x);
42 | try
43 | {
44 | Thread.sleep(READ_UPDATE_DELAY_MS);
45 | } catch(InterruptedException e)
46 | {
47 | // Ignore
48 | }
49 | }
50 | } finally
51 | {
52 | c.close();
53 | }
54 | } catch(IOException e)
55 | {
56 | e.printStackTrace();
57 | }
58 |
59 | }
60 |
61 | private static Controller findController() throws IOException
62 | {
63 | return HIDControllerFinder.findController();
64 | }
65 |
66 | }
67 |
--------------------------------------------------------------------------------
/javadrone-utils/src/main/java/com/codeminders/ardrone/controllers/hid/HIDAPIMotioninJoyVirtualController.java:
--------------------------------------------------------------------------------
1 | package com.codeminders.ardrone.controllers.hid;
2 |
3 | import java.io.IOException;
4 |
5 | import com.codeminders.ardrone.controllers.ControllerData;
6 | import com.codeminders.ardrone.controllers.decoders.ControllerStateDecoder;
7 | import com.codeminders.hidapi.HIDDeviceInfo;
8 | import com.codeminders.hidapi.HIDDeviceNotFoundException;
9 |
10 | public class HIDAPIMotioninJoyVirtualController extends HIDAPIController {
11 |
12 | private static final int VENDOR_ID = 34952;
13 | private static final int PRODUCT_ID = 776;
14 |
15 | private static final int BUFSIZE = 64;
16 | private static final int EXPECTED_BUFSIZE = 11;
17 |
18 | private static ControllerStateDecoder decoder;
19 |
20 |
21 | public HIDAPIMotioninJoyVirtualController() throws HIDDeviceNotFoundException, IOException
22 | {
23 | super(VENDOR_ID, PRODUCT_ID, decoder, BUFSIZE);
24 | }
25 |
26 | public HIDAPIMotioninJoyVirtualController(HIDDeviceInfo hidDeviceInfo) throws IOException
27 | {
28 | super(decoder, BUFSIZE, hidDeviceInfo);
29 | }
30 |
31 | @Override
32 | public String getName() {
33 | return "HID API MotioninJoy VirtualController for PS3";
34 | }
35 |
36 | @Override
37 | public boolean isValid(ControllerData data) throws IOException {
38 | if(data.getActualBufferDataLength() != EXPECTED_BUFSIZE)
39 | {
40 | throw new IOException("Received packed with unexpected size " + data.getActualBufferDataLength());
41 | }
42 | return true;
43 | }
44 |
45 | public static boolean isA(HIDDeviceInfo hidDeviceInfo) {
46 | return VENDOR_ID == hidDeviceInfo.getVendor_id() && PRODUCT_ID == hidDeviceInfo.getProduct_id();
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/scripts/ar_drone_connect.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | import sys,os
4 | from subprocess import Popen,PIPE,call
5 | import re,string
6 |
7 | INTF="wlan0"
8 |
9 | def runCmd(cmd):
10 | retcode = call(string.join(cmd, " "), shell=True)
11 | if retcode < 0:
12 | print >>sys.stderr, "Child was terminated by signal", -retcode
13 | sys.exit(1)
14 | elif retcode!=0:
15 | print >>sys.stderr, "Child returned", retcode
16 | sys.exit(1)
17 |
18 | if os.getuid()!=0:
19 | print >>sys.stderr, "Not enough privilidges"
20 | sys.exit(1)
21 |
22 | print "Detecting AR Drone"
23 |
24 | runCmd(["/sbin/ifconfig", INTF ,"up"])
25 | scanres = Popen(["/sbin/iwlist", INTF, "scan"], stdout=PIPE).communicate()[0]
26 | SSID=None
27 | cells = re.split(r'\s+Cell [0-9]+',scanres)
28 | for c in cells:
29 | m = re.search(r'\s+ESSID\:"(ardrone_[0-9]+)',c)
30 | if m:
31 | SSID=m.group(1)
32 | m = re.search(r'\s+Channel\:([0-9]+)',c)
33 | if not m:
34 | print >>sys.stderr, "Could not detect channel!"
35 | sys.exit(1)
36 | CHANNEL = m.group(1)
37 | break
38 |
39 | if SSID:
40 | print "Found Ar.Drone with SSID %s on channel %s" % (SSID,CHANNEL)
41 | else:
42 | print >>sys.stderr, "Ar.Drone not found"
43 | sys.exit(1)
44 |
45 | print "Configuring WiFi interface"
46 |
47 | runCmd(["/sbin/ifconfig", INTF ,"up"])
48 | runCmd(["/sbin/iwconfig", INTF ,"mode","ad-hoc"])
49 | runCmd(["/sbin/iwconfig", INTF ,"channel",str(CHANNEL)])
50 | runCmd(["/sbin/iwconfig", INTF ,"Bit","54Mb/s"])
51 | runCmd(["/sbin/iwconfig", INTF ,"essid",SSID])
52 |
53 | print "Connecting to Ar.Drone"
54 |
55 | runCmd(["/sbin/dhclient", INTF])
56 | runCmd(["/sbin/route", "delete", "default", "gw", "192.168.1.1"])
57 |
58 | print "Checking connectivity"
59 | runCmd(["/bin/ping", "-c3", "192.168.1.1"])
60 |
61 | print "Ar.Drone is ready with IP 192.168.1.1"
62 |
--------------------------------------------------------------------------------
/javadrone-api/src/main/java/com/codeminders/ardrone/DroneCommand.java:
--------------------------------------------------------------------------------
1 |
2 | package com.codeminders.ardrone;
3 |
4 | public abstract class DroneCommand
5 | {
6 | protected static final int MIN_PRIORITY = 0;
7 | protected static final int HIGH_PRIORITY = 50;
8 | protected static final int VERY_HIGH_PRIORITY = 90;
9 | protected static final int MAX_PRIORITY = 100;
10 | protected static final long DEFAULT_STICKY_RATE_MS = 100;
11 |
12 | protected static final String LAND_TAKEOFF_CATEGORY = "takeoffland";
13 |
14 | private int sticky_counter = 0;
15 |
16 | public abstract int getPriority();
17 |
18 | public String getCategory()
19 | {
20 | return null;
21 | }
22 |
23 | public boolean isSticky()
24 | {
25 | return false;
26 | }
27 |
28 | /**
29 | * For sticky packets indicates how many times it has been sent.
30 | *
31 | * @return current value
32 | */
33 | public int incrementStickyCounter()
34 | {
35 | return ++sticky_counter;
36 | }
37 |
38 | public int getStickyCounter()
39 | {
40 | return sticky_counter;
41 | }
42 |
43 | /**
44 | * For sticky packets indicates delay between sending repeated packets;
45 | */
46 | public long getStickyRate()
47 | {
48 | return DEFAULT_STICKY_RATE_MS;
49 | }
50 |
51 | /**
52 | * This method is used to check if 2 commands are are relaceable by each
53 | * other.
54 | *
55 | * @param cmd
56 | * @return true if they are replaceable
57 | */
58 | public boolean replaces(DroneCommand cmd)
59 | {
60 | if(equals(cmd))
61 | {
62 | return true;
63 | } else
64 | {
65 | String c = getCategory();
66 | return c != null && c.equals(cmd.getCategory());
67 | }
68 | }
69 |
70 | }
71 |
--------------------------------------------------------------------------------
/javadrone-utils/src/main/java/com/codeminders/ardrone/controllers/hid/HIDAPIAfterGlowController.java:
--------------------------------------------------------------------------------
1 | package com.codeminders.ardrone.controllers.hid;
2 |
3 | import java.io.IOException;
4 |
5 | import com.codeminders.ardrone.controllers.ControllerData;
6 | import com.codeminders.ardrone.controllers.decoders.AfterGlowControllerDecoder;
7 | import com.codeminders.ardrone.controllers.decoders.ControllerStateDecoder;
8 | import com.codeminders.hidapi.HIDDeviceInfo;
9 | import com.codeminders.hidapi.HIDDeviceNotFoundException;
10 |
11 | public class HIDAPIAfterGlowController extends HIDAPIController {
12 |
13 | private static final int VENDOR_ID = 3695;
14 | private static final int PRODUCT_ID = 25346;
15 |
16 | private static final int BUFSIZE = 32;
17 | private static final int EXPECTED_BUFSIZE = 27;
18 |
19 | private static ControllerStateDecoder decoder = new AfterGlowControllerDecoder();
20 |
21 |
22 | public HIDAPIAfterGlowController() throws HIDDeviceNotFoundException, IOException
23 | {
24 | super(VENDOR_ID, PRODUCT_ID, decoder, BUFSIZE);
25 | }
26 |
27 | public HIDAPIAfterGlowController(HIDDeviceInfo hidDeviceInfo) throws IOException
28 | {
29 | super(decoder, BUFSIZE, hidDeviceInfo);
30 | }
31 |
32 | @Override
33 | public String getName() {
34 | return "HID API connected AfterGlowController";
35 | }
36 |
37 | @Override
38 | public boolean isValid(ControllerData data) throws IOException {
39 | if(data.getActualBufferDataLength() != EXPECTED_BUFSIZE)
40 | {
41 | throw new IOException("Received packed with unexpected size " + data.getActualBufferDataLength());
42 | }
43 | return true;
44 | }
45 |
46 | public static boolean isA(HIDDeviceInfo hidDeviceInfo) {
47 | return VENDOR_ID == hidDeviceInfo.getVendor_id() && PRODUCT_ID == hidDeviceInfo.getProduct_id();
48 | }
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Java API and demo programs to control Parrot's [AR.Drone](http://ardrone.parrot.com/).
2 |
3 | The goal of the project to have Java API (without using native code) to control AR.Drone. This project does not user Parrot's SDK, but rather implement networking protocols directly in Java.
4 |
5 | The code supposed to be cross-platform. We use MacOS X and Linux for development. The library works both on PC/Mac as well as on Android. The demo programs are using GameController.
6 |
7 | You can watch a [small video](http://www.youtube.com/watch?v=J0CsKlIfquo) of how it works.
8 | The project also includes drone navigation program, written in Java: ControlTower.
9 |
10 | Developed by [Codeminders](http://www.codeminders.com/) and contributors.
11 | Patches, bug reports and other help is very welcome.
12 |
13 |
14 | ## Support ##
15 |
16 | Questions? Suggestiaons? Please join our [Discussion group](http://groups.google.com/group/javadrone).
17 |
18 | If you need a professional support or need to do a custom project based on JavaDrone,
19 | please contact [Codeminders](http://www.codeminders.com/) for a quote.
20 |
21 |
22 | ## Pages ##
23 | * [ControlTower](https://github.com/vzaliva/javadrone/blob/wiki/ControlTower.md) - demo navigation program using this API
24 | * [ControlTowerAndroid](https://github.com/vzaliva/javadrone/blob/wiki/ControlTowerAndroid.md) - demo navigation Android App using this API
25 | * [GameController](https://github.com/vzaliva/javadrone/blob/wiki/GameController.md) - information about supported controllers
26 | * [BuildInstructions](https://github.com/vzaliva/javadrone/blob/wiki/BuildInstructions.md) - Build instructions
27 | * [FrequentlyAskedQuestions](https://github.com/vzaliva/javadrone/blob/wiki/FrequentlyAskedQuestions.md) - FAQ
28 |
29 | ## Links ##
30 | * [Official AR.Drone API project](https://projects.ardrone.org/projects/show/ardrone-api)
31 | * [Developer forums](https://projects.ardrone.org/projects/ardrone-api/boards)
32 |
--------------------------------------------------------------------------------
/javadrone-api/src/main/java/com/codeminders/ardrone/data/decoder/ardrone10/video/MacroBlock.java:
--------------------------------------------------------------------------------
1 |
2 | package com.codeminders.ardrone.data.decoder.ardrone10.video;
3 |
4 | // Copyright � 2007-2011, PARROT SA, all rights reserved.
5 |
6 | // DISCLAIMER
7 | // The APIs is provided by PARROT and contributors "AS IS" and any express or
8 | // implied warranties, including, but not limited to, the implied warranties of
9 | // merchantability
10 | // and fitness for a particular purpose are disclaimed. In no event shall PARROT
11 | // and contributors be liable for any direct, indirect, incidental, special,
12 | // exemplary, or
13 | // consequential damages (including, but not limited to, procurement of
14 | // substitute goods or services; loss of use, data, or profits; or business
15 | // interruption) however
16 | // caused and on any theory of liability, whether in contract, strict liability,
17 | // or tort (including negligence or otherwise) arising in any way out of the use
18 | // of this
19 | // software, even if advised of the possibility of such damage.
20 |
21 | // Author : Daniel Schmidt
22 | // Publishing date : 2010-01-06
23 | // based on work by : Wilke Jansoone
24 |
25 | // Redistribution and use in source and binary forms, with or without
26 | // modification, are permitted provided that the following conditions
27 | // are met:
28 | // - Redistributions of source code must retain the above copyright notice, this
29 | // list of conditions, the disclaimer and the original author of the source
30 | // code.
31 | // - Neither the name of the PixVillage Team, nor the names of its contributors
32 | // may be used to endorse or promote products derived from this software without
33 | // specific prior written permission.
34 |
35 | class MacroBlock
36 | {
37 | short[][] DataBlocks;
38 |
39 | MacroBlock()
40 | {
41 | DataBlocks = new short[6][];
42 |
43 | for(int index = 0; index < 6; index++)
44 | DataBlocks[index] = new short[64];
45 | }
46 | }
--------------------------------------------------------------------------------
/javadrone-utils/src/main/java/com/codeminders/ardrone/controllers/hid/HIDAPISonyPS3Controller.java:
--------------------------------------------------------------------------------
1 |
2 | package com.codeminders.ardrone.controllers.hid;
3 |
4 | import java.io.IOException;
5 |
6 | import com.codeminders.ardrone.controllers.ControllerData;
7 | import com.codeminders.ardrone.controllers.decoders.SonyPS3ControllerStateDecoder;
8 | import com.codeminders.hidapi.HIDDeviceInfo;
9 | import com.codeminders.hidapi.HIDDeviceNotFoundException;
10 |
11 | public class HIDAPISonyPS3Controller extends HIDAPIController
12 | {
13 | private static final int VENDOR_ID = 1356;
14 | private static final int PRODUCT_ID = 616;
15 |
16 | private static final int BUFSIZE = 64;
17 | private static final int EXPECTED_BUFSIZE = 32;
18 | private static final int EXPECTED_BUFSIZE_2 = 49;
19 |
20 | static final SonyPS3ControllerStateDecoder decoder = new SonyPS3ControllerStateDecoder();
21 |
22 | public HIDAPISonyPS3Controller() throws HIDDeviceNotFoundException, IOException
23 | {
24 | super(VENDOR_ID, PRODUCT_ID, decoder, BUFSIZE);
25 | }
26 |
27 | public HIDAPISonyPS3Controller(HIDDeviceInfo hidDeviceInfo) throws IOException
28 | {
29 | super(decoder, BUFSIZE, hidDeviceInfo);
30 | }
31 |
32 | @Override
33 | public String getName() {
34 | return "HID API connected SonyPS3Controller";
35 | }
36 |
37 | @Override
38 | public boolean isValid(ControllerData data) throws IOException {
39 | if(data.getActualBufferDataLength() != EXPECTED_BUFSIZE && data.getActualBufferDataLength() != EXPECTED_BUFSIZE_2)
40 | {
41 | throw new IOException("Received packed with unexpected size " + data.getActualBufferDataLength());
42 | }
43 | return true;
44 | }
45 |
46 | public static boolean isA(HIDDeviceInfo hidDeviceInfo) {
47 | return VENDOR_ID == hidDeviceInfo.getVendor_id() && PRODUCT_ID == hidDeviceInfo.getProduct_id();
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/javadrone-api/src/main/java/com/codeminders/ardrone/data/decoder/ardrone10/video/ImageSlice.java:
--------------------------------------------------------------------------------
1 |
2 | package com.codeminders.ardrone.data.decoder.ardrone10.video;
3 |
4 | // Copyright � 2007-2011, PARROT SA, all rights reserved.
5 |
6 | // DISCLAIMER
7 | // The APIs is provided by PARROT and contributors "AS IS" and any express or
8 | // implied warranties, including, but not limited to, the implied warranties of
9 | // merchantability
10 | // and fitness for a particular purpose are disclaimed. In no event shall PARROT
11 | // and contributors be liable for any direct, indirect, incidental, special,
12 | // exemplary, or
13 | // consequential damages (including, but not limited to, procurement of
14 | // substitute goods or services; loss of use, data, or profits; or business
15 | // interruption) however
16 | // caused and on any theory of liability, whether in contract, strict liability,
17 | // or tort (including negligence or otherwise) arising in any way out of the use
18 | // of this
19 | // software, even if advised of the possibility of such damage.
20 |
21 | // Author : Daniel Schmidt
22 | // Publishing date : 2010-01-06
23 | // based on work by : Wilke Jansoone
24 |
25 | // Redistribution and use in source and binary forms, with or without
26 | // modification, are permitted provided that the following conditions
27 | // are met:
28 | // - Redistributions of source code must retain the above copyright notice, this
29 | // list of conditions, the disclaimer and the original author of the source
30 | // code.
31 | // - Neither the name of the PixVillage Team, nor the names of its contributors
32 | // may be used to endorse or promote products derived from this software without
33 | // specific prior written permission.
34 |
35 | class ImageSlice
36 | {
37 | MacroBlock[] MacroBlocks;
38 |
39 | ImageSlice(int macroBlockCount)
40 | {
41 | MacroBlocks = new MacroBlock[macroBlockCount];
42 |
43 | for(int index = 0; index < macroBlockCount; index++)
44 | MacroBlocks[index] = new MacroBlock();
45 | }
46 | }
--------------------------------------------------------------------------------
/javadrone-api/src/main/java/com/codeminders/ardrone/version/ftp/DroneFTPversionReader.java:
--------------------------------------------------------------------------------
1 | package com.codeminders.ardrone.version.ftp;
2 |
3 | import java.io.ByteArrayOutputStream;
4 | import java.io.IOException;
5 | import java.io.InputStream;
6 | import java.net.InetAddress;
7 | import java.net.URL;
8 | import java.net.URLConnection;
9 | import java.util.logging.Logger;
10 |
11 | import com.codeminders.ardrone.version.DroneVersionReader;
12 |
13 | public class DroneFTPversionReader implements DroneVersionReader {
14 |
15 | private Logger log = Logger.getLogger(getClass().getName());
16 |
17 | private static final int FTP_PORT = 5551;
18 | private static final String VERSION_FILE_NAME = "version.txt";
19 |
20 | String ftpVersionFileLocation;
21 |
22 | public DroneFTPversionReader(InetAddress drone_addr) {
23 | this.ftpVersionFileLocation = "ftp://"+drone_addr.getHostAddress() + ":" + FTP_PORT + "/" + VERSION_FILE_NAME;
24 | }
25 |
26 | @Override
27 | public String readDroneVersion() throws IOException {
28 |
29 | InputStream is = null;
30 | ByteArrayOutputStream bos = null;
31 | try {
32 | log.info("Attempting to read AR Drone version using FTP. Version file is: "+ ftpVersionFileLocation);
33 | URL url = new URL(ftpVersionFileLocation);
34 | URLConnection ftpConnection = url.openConnection();
35 | log.info(ftpVersionFileLocation + "- Connection Opened");
36 |
37 | is = ftpConnection.getInputStream();
38 | bos = new ByteArrayOutputStream();
39 |
40 | byte[] buffer = new byte[1024];
41 | int readCount;
42 |
43 | while((readCount = is.read(buffer)) > 0)
44 | {
45 | bos.write(buffer, 0, readCount);
46 | }
47 |
48 | return bos.toString();
49 | } finally {
50 | if (null != bos) {
51 | bos.close();
52 | }
53 | if (null != is) {
54 | is.close ();
55 | }
56 | }
57 | }
58 |
59 | }
60 |
--------------------------------------------------------------------------------
/javadrone-api/src/main/java/com/codeminders/ardrone/data/reader/TCPDataRader.java:
--------------------------------------------------------------------------------
1 | package com.codeminders.ardrone.data.reader;
2 |
3 | import java.io.IOException;
4 | import java.io.InputStream;
5 | import java.net.InetAddress;
6 | import java.net.Socket;
7 | import java.util.logging.Level;
8 | import java.util.logging.Logger;
9 |
10 | import com.codeminders.ardrone.data.ARDroneDataReader;
11 |
12 |
13 | public class TCPDataRader implements ARDroneDataReader {
14 |
15 | Logger log = Logger.getLogger(this.getClass().getName());
16 |
17 | private InetAddress drone_addr;
18 | private int data_port;
19 | private int timeout;
20 |
21 | private Socket socket;
22 |
23 | private InputStream socketInput;
24 |
25 | public TCPDataRader(InetAddress drone_addr, int data_port, int timeout) throws IOException {
26 | super();
27 |
28 | this.drone_addr = drone_addr;
29 | this.data_port = data_port;
30 | this.timeout = timeout;
31 |
32 | connect();
33 | }
34 |
35 | private void connect() throws IOException {
36 |
37 | socket = new Socket(drone_addr, data_port);
38 | socket.setSoTimeout(timeout);
39 | socketInput = socket.getInputStream();
40 | }
41 |
42 | @Override
43 | public InputStream getDataStream() {
44 | return socketInput;
45 | }
46 |
47 | @Override
48 | public void finish() {
49 | disconnect();
50 | }
51 |
52 | private void disconnect() {
53 | if (socket.isClosed()) {
54 | try {
55 | socket.close();
56 | } catch (IOException e) {
57 | log.log(Level.FINER, "Excepton on stopping TCP reading", e);
58 | }
59 | }
60 | }
61 |
62 | @Override
63 | public int readDataBlock(byte[] buf) throws IOException {
64 | return socketInput.read(buf);
65 | }
66 |
67 | @Override
68 | public boolean isStreamSupported() {
69 | return true;
70 | }
71 |
72 | @Override
73 | public void reconnect() throws IOException {
74 | disconnect();
75 | connect();
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/javadrone-api/src/main/java/com/codeminders/ardrone/data/decoder/ardrone10/ARDrone10VideoDataDecoder.java:
--------------------------------------------------------------------------------
1 | package com.codeminders.ardrone.data.decoder.ardrone10;
2 |
3 | import java.io.IOException;
4 | import java.util.logging.Level;
5 | import java.util.logging.Logger;
6 |
7 | import com.codeminders.ardrone.ARDrone;
8 | import com.codeminders.ardrone.VideoDataDecoder;
9 | import com.codeminders.ardrone.data.ARDroneDataReader;
10 | import com.codeminders.ardrone.data.decoder.ardrone10.video.BufferedVideoImage;
11 |
12 | public class ARDrone10VideoDataDecoder extends VideoDataDecoder {
13 |
14 | private Logger log = Logger.getLogger(this.getClass().getName());
15 |
16 | final BufferedVideoImage vi = new BufferedVideoImage();
17 |
18 | private boolean done = false;
19 |
20 | byte[] buffer;
21 |
22 | public ARDrone10VideoDataDecoder(ARDrone drone, int buffer_size) {
23 | super(drone);
24 | buffer = new byte[buffer_size];
25 |
26 | setName("ARDrone 1.0 Video decoding thread");
27 | }
28 |
29 | @Override
30 | public void run() {
31 |
32 | super.run();
33 | ARDroneDataReader reader = getDataReader();
34 | int len = 0;
35 | while (!done) {
36 | try {
37 | pauseCheck();
38 | len = reader.readDataBlock(buffer);
39 | if (len > 0) {
40 | vi.addImageStream(buffer, len);
41 | notifyDroneWithDecodedFrame(0, 0, vi.getWidth(), vi.getHeight(), vi.getJavaPixelData(), 0, vi.getWidth());
42 | }
43 | } catch (IOException e) {
44 | log.log(Level.SEVERE, " Error reading data from data input stream. Stopping decoding thread", e);
45 | try {
46 | reader.reconnect();
47 | } catch (IOException e1) {
48 | log.log(Level.SEVERE, " Error reconnecting data reader", e);
49 | }
50 | }
51 | }
52 |
53 | log.fine("Video Decodding thread is stopped");
54 | }
55 |
56 | @Override
57 | public void finish() {
58 | done = true;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/javadrone-api/src/main/java/com/codeminders/ardrone/CommandSender.java:
--------------------------------------------------------------------------------
1 |
2 | package com.codeminders.ardrone;
3 |
4 | import java.io.IOException;
5 | import java.net.*;
6 |
7 | import java.util.logging.Logger;
8 |
9 | import com.codeminders.ardrone.commands.*;
10 |
11 | public class CommandSender implements Runnable
12 | {
13 | private static final int CMD_PORT = 5556;
14 |
15 | private CommandQueue cmd_queue;
16 | private ARDrone drone;
17 | private InetAddress drone_addr;
18 | private DatagramSocket cmd_socket;
19 | private int sequence = 1;
20 |
21 | private Logger log = Logger.getLogger(getClass().getName());
22 |
23 | public CommandSender(CommandQueue cmd_queue, ARDrone drone, InetAddress drone_addr, DatagramSocket cmd_socket)
24 | {
25 | this.cmd_queue = cmd_queue;
26 | this.drone = drone;
27 | this.drone_addr = drone_addr;
28 | this.cmd_socket = cmd_socket;
29 | }
30 |
31 | @Override
32 | public void run()
33 | {
34 | while(true)
35 | {
36 | try
37 | {
38 | DroneCommand c = cmd_queue.take();
39 | if(c instanceof QuitCommand)
40 | {
41 | // Terminating
42 | break;
43 | }
44 |
45 | if(c instanceof ATCommand)
46 | {
47 | ATCommand cmd = (ATCommand) c;
48 | //if(!(c instanceof KeepAliveCommand) && !(c instanceof MoveCommand) && !(c instanceof HoverCommand) && c.getStickyCounter()==0)
49 | log.fine("Q[" + cmd_queue.size() + "]Sending AT command " + c);
50 | byte[] pdata = cmd.getPacket(sequence++); // TODO: pass
51 | // sequence number
52 | DatagramPacket p = new DatagramPacket(pdata, pdata.length, drone_addr, CMD_PORT);
53 | cmd_socket.send(p);
54 | }
55 | } catch(InterruptedException e)
56 | {
57 | // ignoring
58 | } catch(IOException e)
59 | {
60 | drone.changeToErrorState(e);
61 | break;
62 | }
63 | }
64 | }
65 |
66 | }
67 |
--------------------------------------------------------------------------------
/javadrone-utils/src/main/java/com/codeminders/ardrone/data/logger/file/SaveStreamToFile.java:
--------------------------------------------------------------------------------
1 | package com.codeminders.ardrone.data.logger.file;
2 |
3 | import java.io.DataOutputStream;
4 | import java.io.File;
5 | import java.io.FileNotFoundException;
6 | import java.io.FileOutputStream;
7 | import java.io.IOException;
8 | import java.util.concurrent.LinkedBlockingQueue;
9 | import java.util.logging.Level;
10 | import java.util.logging.Logger;
11 |
12 | public class SaveStreamToFile extends Thread {
13 |
14 | private Logger log = Logger.getLogger(getClass().getName());
15 |
16 | FileOutputStream fout;
17 | DataOutputStream dout;
18 | LinkedBlockingQueue queue;
19 | boolean done = false;
20 |
21 | public SaveStreamToFile(File file, int queueCapacity) throws FileNotFoundException {
22 | super();
23 | fout = new FileOutputStream(file);
24 | dout = new DataOutputStream(fout);
25 | queue = new LinkedBlockingQueue(queueCapacity);
26 | setName("File " + file.getName() + " writer");
27 | }
28 |
29 | @Override
30 | public void run() {
31 | Integer toSave;
32 | while (!done) {
33 | toSave = null;
34 | try {
35 | toSave = queue.take();
36 | } catch (InterruptedException e) {
37 | break;
38 | }
39 |
40 | if (null != toSave) {
41 | try {
42 | dout.writeInt(toSave);
43 | } catch (IOException e) {
44 | done = true;
45 | log.log(Level.SEVERE, "Failed to store data", e);
46 | }
47 | }
48 | }
49 | try {
50 | fout.flush();
51 | fout.close();
52 | } catch (IOException e) {}
53 |
54 | }
55 |
56 | public void toFile(int data) {
57 | try {
58 | if (!done) {
59 | queue.put(data);
60 | } /**else {
61 | // throw
62 | } **/
63 | } catch (InterruptedException e) {
64 | // external interrupt
65 | }
66 | }
67 |
68 | public synchronized void finish()
69 | {
70 | done = true;
71 | try {
72 | queue.put(null);
73 | } catch (InterruptedException e) {}
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/javadrone-api/src/main/java/com/codeminders/ardrone/commands/ATCommand.java:
--------------------------------------------------------------------------------
1 |
2 | package com.codeminders.ardrone.commands;
3 |
4 | import java.io.UnsupportedEncodingException;
5 |
6 | import com.codeminders.ardrone.DroneCommand;
7 |
8 | public abstract class ATCommand extends DroneCommand
9 | {
10 | private String encodeParameter(Object p)
11 | {
12 | if(p instanceof Integer)
13 | return p.toString();
14 |
15 | if(p instanceof Float)
16 | return Integer.toString(Float.floatToIntBits((Float) p));
17 |
18 | if(p instanceof String)
19 | return "\"" + p + "\"";
20 |
21 | throw new IllegalArgumentException("Unsupported parameter type: " + p.getClass().getName() + " " + p);
22 | }
23 |
24 | public String getCommandString(int seq)
25 | {
26 | return "AT*" + getID() + "=" + seq + getParametersString() + "\r";
27 | }
28 |
29 | protected abstract String getID();
30 |
31 | public byte[] getPacket(int seq)
32 | {
33 | try
34 | {
35 | return getCommandString(seq).getBytes("ASCII");
36 | } catch(UnsupportedEncodingException e)
37 | {
38 | // never happens
39 | return null;
40 | }
41 | }
42 |
43 | protected abstract Object[] getParameters();
44 |
45 | private String getParametersString()
46 | {
47 | StringBuffer sb = new StringBuffer();
48 | for(Object p : getParameters())
49 | {
50 | sb.append(',').append(encodeParameter(p));
51 | }
52 |
53 | return sb.toString();
54 | }
55 |
56 | @Override
57 | public int getPriority()
58 | {
59 | return MIN_PRIORITY;
60 | }
61 |
62 | @Override
63 | public String toString()
64 | {
65 | StringBuilder builder = new StringBuilder();
66 | builder.append(getClass().getSimpleName());
67 | builder.append(" [ID=");
68 | builder.append(getID());
69 | builder.append(", param=");
70 | builder.append(getParametersString());
71 | builder.append("]");
72 | return builder.toString();
73 | }
74 |
75 | public boolean equals(Object obj)
76 | {
77 | if(obj == null || !(obj instanceof ATCommand))
78 | return false;
79 | ATCommand o = (ATCommand) obj;
80 | return o.getCommandString(0).equals(getCommandString(0));
81 | }
82 |
83 | }
84 |
--------------------------------------------------------------------------------
/controltower-android/res/layout/seek_bar_preference.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
11 |
12 |
21 |
22 |
27 |
28 |
34 |
35 |
40 |
41 |
47 |
48 |
54 |
55 |
--------------------------------------------------------------------------------
/javadrone-utils/src/main/java/com/codeminders/ardrone/data/logger/file/SaveToFile.java:
--------------------------------------------------------------------------------
1 | package com.codeminders.ardrone.data.logger.file;
2 |
3 | import java.io.DataOutputStream;
4 | import java.io.File;
5 | import java.io.FileNotFoundException;
6 | import java.io.FileOutputStream;
7 | import java.io.IOException;
8 | import java.util.concurrent.LinkedBlockingQueue;
9 | import java.util.logging.Level;
10 | import java.util.logging.Logger;
11 |
12 | import com.codeminders.ardrone.data.logger.ChannelDataChunk;
13 |
14 | public class SaveToFile extends Thread {
15 |
16 | private Logger log = Logger.getLogger(getClass().getName());
17 |
18 | FileOutputStream fout;
19 | DataOutputStream dout;
20 | LinkedBlockingQueue queue;
21 | boolean done = false;
22 |
23 | public SaveToFile(File file, int queueCapacity) throws FileNotFoundException {
24 | super();
25 | fout = new FileOutputStream(file);
26 | dout = new DataOutputStream(fout);
27 | queue = new LinkedBlockingQueue(queueCapacity);
28 | setName("File " + file.getName() + " writer");
29 | }
30 |
31 | @Override
32 | public void run() {
33 | ChannelDataChunk toSave;
34 | while (!done) {
35 | toSave = null;
36 | try {
37 | toSave = queue.take();
38 | } catch (InterruptedException e) {
39 | break;
40 | }
41 |
42 | if (null != toSave) {
43 | try {
44 | toSave.writeToStream(dout);
45 | } catch (IOException e) {
46 | done = true;
47 | log.log(Level.SEVERE, "Failed to store data", e);
48 | }
49 | }
50 | }
51 | try {
52 | fout.flush();
53 | fout.close();
54 | } catch (IOException e) {}
55 |
56 | }
57 |
58 | public void toFile(ChannelDataChunk chunk) {
59 | try {
60 | if (!done) {
61 | queue.put(chunk);
62 | } /**else {
63 | // throw
64 | } **/
65 | } catch (InterruptedException e) {
66 | // external interrupt
67 | }
68 | }
69 |
70 | public synchronized void finish()
71 | {
72 | done = true;
73 | try {
74 | queue.put(null);
75 | } catch (InterruptedException e) {}
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/javadrone-api/src/main/java/com/codeminders/ardrone/controllers/decoders/MotioninJoyVirtualStateDecoder.java:
--------------------------------------------------------------------------------
1 | package com.codeminders.ardrone.controllers.decoders;
2 |
3 | import java.io.IOException;
4 | import java.util.BitSet;
5 |
6 | import com.codeminders.ardrone.controllers.GameControllerState;
7 | import com.codeminders.ardrone.controllers.ControllerData;
8 |
9 | public class MotioninJoyVirtualStateDecoder implements ControllerStateDecoder {
10 |
11 | public GameControllerState decodeState(ControllerData data) throws IOException {
12 |
13 | byte[] buf = data.getBuffer();
14 |
15 | BitSet bs = new BitSet(16);
16 |
17 | for(int i = 0; i < 8; i++)
18 | {
19 | if((1 & (buf[0] >> i)) == 1)
20 | bs.set(i);
21 | }
22 |
23 | for(int i = 0; i < 8; i++)
24 | {
25 | if((1 & (buf[1] >> i)) == 1)
26 | bs.set(8 + i);
27 | }
28 |
29 | int i = 0;
30 |
31 | boolean triangle = bs.get(i++);
32 | boolean circle = bs.get(i++);
33 | boolean cross = bs.get(i++);
34 | boolean square = bs.get(i++);
35 | boolean L1 = bs.get(i++);
36 | boolean R1 = bs.get(i++);
37 | boolean L2 = bs.get(i++);
38 | boolean R2 = bs.get(i++);
39 | boolean select = bs.get(i++);
40 | boolean leftJoystickPress = bs.get(i++);
41 | boolean rightJoystickPress = bs.get(i++);
42 | boolean start = bs.get(i++);
43 | boolean PS = bs.get(i++);
44 |
45 |
46 | int leftJoystickX = joystickCoordConv(buf[3]);
47 | int leftJoystickY = joystickCoordConv(buf[4]);
48 | int rightJoystickX = joystickCoordConv(buf[5]);
49 | int rightJoystickY = joystickCoordConv(buf[8]);
50 |
51 | // TODO: decode HAT switch
52 | int hatSwitchLeftRight = 0;
53 | int hatSwitchUpDown = 0;
54 |
55 | GameControllerState res = new GameControllerState(square, cross, circle, triangle, L1, R1, L2, R2, select, start,
56 | leftJoystickPress, rightJoystickPress, PS, hatSwitchLeftRight, hatSwitchUpDown, leftJoystickX,
57 | leftJoystickY, rightJoystickX, rightJoystickY);
58 |
59 | return res;
60 | }
61 |
62 | private int joystickCoordConv(byte b)
63 | {
64 | int v = b < 0 ? b + 256 : b;
65 | return(v - 128);
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/javadrone-api/src/main/java/com/codeminders/ardrone/controllers/decoders/AfterGlowControllerDecoder.java:
--------------------------------------------------------------------------------
1 |
2 | package com.codeminders.ardrone.controllers.decoders;
3 |
4 | import java.io.IOException;
5 | import java.util.BitSet;
6 |
7 | import com.codeminders.ardrone.controllers.GameControllerState;
8 | import com.codeminders.ardrone.controllers.ControllerData;
9 |
10 | /**
11 | * "Afterglow" controller for PS3 state decodder
12 | *
13 | * @author lord
14 | *
15 | */
16 | public class AfterGlowControllerDecoder implements ControllerStateDecoder
17 | {
18 |
19 | private int joystickCoordConv(byte b)
20 | {
21 | int v = b < 0 ? b + 256 : b;
22 | return v - 128;
23 | }
24 |
25 | @Override
26 | public GameControllerState decodeState(ControllerData data) throws IOException
27 | {
28 | byte[] buf = data.getBuffer();
29 |
30 | BitSet bs = new BitSet(13);
31 | for(int i = 0; i < 8; i++)
32 | {
33 | if((1 & (buf[0] >> i)) == 1)
34 | bs.set(i);
35 | }
36 | for(int i = 0; i < 5; i++)
37 | {
38 | if((1 & (buf[1] >> i)) == 1)
39 | bs.set(8 + i);
40 | }
41 |
42 | int i = 0;
43 | boolean square = bs.get(i++);
44 | boolean cross = bs.get(i++);
45 | boolean circle = bs.get(i++);
46 | boolean triangle = bs.get(i++);
47 | boolean L1 = bs.get(i++);
48 | boolean R1 = bs.get(i++);
49 | boolean L2 = bs.get(i++);
50 | boolean R2 = bs.get(i++);
51 | boolean select = bs.get(i++);
52 | boolean start = bs.get(i++);
53 | boolean leftJoystickPress = bs.get(i++);
54 | boolean rightJoystickPress = bs.get(i++);
55 | boolean PS = bs.get(i++);
56 |
57 | int leftJoystickX = joystickCoordConv(buf[3]);
58 | int leftJoystickY = joystickCoordConv(buf[4]);
59 | int rightJoystickX = joystickCoordConv(buf[5]);
60 | int rightJoystickY = joystickCoordConv(buf[6]);
61 |
62 | // TODO: decode HAT switch
63 | int hatSwitchLeftRight = 0;
64 | int hatSwitchUpDown = 0;
65 |
66 | GameControllerState res = new GameControllerState(square, cross, circle, triangle, L1, R1, L2, R2, select, start,
67 | leftJoystickPress, rightJoystickPress, PS, hatSwitchLeftRight, hatSwitchUpDown, leftJoystickX,
68 | leftJoystickY, rightJoystickX, rightJoystickY);
69 |
70 |
71 | return res;
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/javadrone-api/src/main/java/com/codeminders/ardrone/data/reader/LigthUDPDataReader.java:
--------------------------------------------------------------------------------
1 | package com.codeminders.ardrone.data.reader;
2 |
3 | import java.io.IOException;
4 | import java.io.InputStream;
5 | import java.net.DatagramPacket;
6 | import java.net.DatagramSocket;
7 | import java.net.InetAddress;
8 |
9 | import com.codeminders.ardrone.data.ARDroneDataReader;
10 |
11 | public class LigthUDPDataReader implements ARDroneDataReader {
12 |
13 | private int timeout;
14 |
15 | private int data_port;
16 |
17 | static final byte[] TRIGGER_BYTES = { 0x01, 0x00, 0x00, 0x00 };
18 |
19 | protected DatagramSocket socket;
20 | private DatagramPacket trigger_packet;
21 |
22 | private InetAddress drone_addr;
23 |
24 | public LigthUDPDataReader(InetAddress drone_addr, int data_port, int timeout) throws IOException {
25 |
26 | super();
27 | this.data_port = data_port;
28 | this.timeout = timeout;
29 | this.drone_addr = drone_addr;
30 |
31 | trigger_packet = new DatagramPacket(TRIGGER_BYTES, TRIGGER_BYTES.length, drone_addr, data_port);
32 |
33 | connect();
34 | }
35 |
36 | public InputStream getDataStream() {
37 | return null;
38 | }
39 |
40 | public void connect() throws IOException {
41 | disconnect();
42 | socket = new DatagramSocket(data_port);
43 | socket.setSoTimeout(timeout);
44 | }
45 |
46 | private void disconnect() {
47 |
48 | if (null != socket && socket.isConnected()) {
49 | socket.disconnect();
50 | }
51 |
52 | if (null != socket && !socket.isClosed()) {
53 | socket.close();
54 | }
55 |
56 | }
57 |
58 | public int readDataBlock(byte[] buf) throws IOException {
59 | //send trigger data
60 | socket.send(trigger_packet);
61 | //receive data
62 | DatagramPacket packet = new DatagramPacket(buf, buf.length, drone_addr, data_port);
63 | socket.receive(packet);
64 |
65 | return packet.getLength();
66 | }
67 |
68 | public synchronized void finish()
69 | {
70 | disconnect();
71 | }
72 |
73 | @Override
74 | public boolean isStreamSupported() {
75 | return false;
76 | }
77 |
78 | @Override
79 | public void reconnect() throws IOException {
80 | disconnect();
81 | connect();
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/javadrone-utils/src/main/java/com/codeminders/ardrone/data/reader/FileDataReader.java:
--------------------------------------------------------------------------------
1 | package com.codeminders.ardrone.data.reader;
2 |
3 | import java.io.DataInputStream;
4 | import java.io.File;
5 | import java.io.FileInputStream;
6 | import java.io.FileNotFoundException;
7 | import java.io.IOException;
8 | import java.nio.ByteBuffer;
9 | import java.util.logging.Level;
10 | import java.util.logging.Logger;
11 |
12 | import com.codeminders.ardrone.data.logger.ChannelDataChunk;
13 |
14 | public abstract class FileDataReader implements Runnable {
15 |
16 | private boolean done;
17 | private Logger log = Logger.getLogger(this.getClass().getName());
18 |
19 | File dataFile;
20 | FileInputStream fin;
21 | DataInputStream din;
22 |
23 | long lastFrameTime = 0;
24 |
25 | public FileDataReader(File dataFile) throws FileNotFoundException {
26 | super();
27 | this.dataFile = dataFile;
28 | fin = new FileInputStream(dataFile);
29 | }
30 |
31 | @Override
32 | public void run() {
33 | din = new DataInputStream(fin);
34 |
35 | ChannelDataChunk dataChunk = null;
36 |
37 | try {
38 | while (!done) {
39 | dataChunk = ChannelDataChunk.readFromStream(din);
40 | if (null == dataChunk.getData()) {
41 | break;
42 | }
43 |
44 | if (lastFrameTime > 0 && dataChunk.getIoDelay() > 0) {
45 | Thread.sleep(dataChunk.getIoDelay() - lastFrameTime);
46 | }
47 |
48 | lastFrameTime = dataChunk.getIoDelay();
49 |
50 | handleData(ByteBuffer.wrap(dataChunk.getData()), dataChunk.getData().length);
51 | }
52 | } catch (IOException e) {
53 | log.log(Level.SEVERE, "DataReading is stoped", e);
54 | } catch (Exception e) {
55 | log.log(Level.SEVERE, "DataReading is stoped", e);
56 | } finally {
57 | try {
58 | fin.close();
59 | } catch (IOException e) {
60 | log.log(Level.SEVERE, "Failed to correctly close input stream", e);
61 | }
62 | }
63 | }
64 |
65 | public abstract void handleData(ByteBuffer buf, int len) throws Exception;
66 |
67 | public synchronized void finish()
68 | {
69 | done = true;
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/javadrone-api/src/main/java/com/codeminders/ardrone/data/decoder/ardrone10/ARDrone10NavDataDecoder.java:
--------------------------------------------------------------------------------
1 | package com.codeminders.ardrone.data.decoder.ardrone10;
2 |
3 | import java.io.IOException;
4 | import java.nio.ByteBuffer;
5 | import java.util.logging.Level;
6 | import java.util.logging.Logger;
7 |
8 | import com.codeminders.ardrone.ARDrone;
9 | import com.codeminders.ardrone.NavDataDecoder;
10 | import com.codeminders.ardrone.data.ARDroneDataReader;
11 | import com.codeminders.ardrone.data.decoder.ardrone10.navdata.ARDrone10NavData;
12 | import com.codeminders.ardrone.data.navdata.NavDataFormatException;
13 |
14 | public class ARDrone10NavDataDecoder extends NavDataDecoder {
15 |
16 | private Logger log = Logger.getLogger(this.getClass().getName());
17 |
18 | private boolean done = false;
19 |
20 | byte[] buffer;
21 |
22 | public ARDrone10NavDataDecoder(ARDrone drone, int buffer_size) {
23 | super(drone);
24 | setName("ARDrone 1.0 NavData decodding thread");
25 | buffer = new byte[buffer_size];
26 | }
27 |
28 | @Override
29 | public void run() {
30 |
31 | super.run();
32 | ARDroneDataReader reader = getDataReader();
33 | while (!done) {
34 | try {
35 |
36 | pauseCheck();
37 |
38 | int len = reader.readDataBlock(buffer);
39 |
40 | if (len > 0) {
41 | try {
42 | notifyDroneWithDecodedNavdata(ARDrone10NavData.createFromData(ByteBuffer.wrap(buffer), len));
43 | } catch (NavDataFormatException e) {
44 | log.log(Level.SEVERE, "Failed to decode receivd navdata information", e);
45 | } catch (Exception ex) {
46 | log.log(Level.SEVERE, "Failed to decode receivd navdata information", ex);
47 | }
48 | }
49 | } catch (IOException e) {
50 | log.log(Level.SEVERE, " Error reading data from data input stream. Stopping decoding thread", e);
51 | try {
52 | reader.reconnect();
53 | } catch (IOException e1) {
54 | log.log(Level.SEVERE, " Error reconnecting data reader", e);
55 | }
56 | }
57 | }
58 | log.fine("Decodding thread is stopped");
59 | }
60 |
61 | @Override
62 | public void finish() {
63 | done = true;
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/controltower-android/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | ControlTower
4 | Settings
5 | ControlTower
6 | Settings
7 | Exit
8 |
9 | AR.Drone State:
10 | DISCONNECTED
11 | AR.Drone Camera signal
12 | Land
13 | TakeOff
14 | Connect
15 | Settings
16 | Connect PS3
17 | USB PS3 controller State:
18 | Altitude
19 | Angle
20 | Vertical Speed
21 | Rotation Speed
22 | Controller Deadzone
23 | Maximum drone altitude in meters
24 | Maximum bending angle for the drone in degrees
25 | Maximum vertical speed, in meters per second
26 | Maximum yaw speed, in degrees per second.
27 | Minimum controller axis position change that will impact on drone, in percents
28 | Cancel
29 | Save
30 | Configuration
31 | Application Configuration
32 | Connect AR.Drone
33 | Automatically connect/reconnect AR.Drone on application start.\nDefault: false
34 | Connect PS3
35 | Automatically connect/reconnect PS3 game controller over USB on application start.\nDefault: fasle
36 | Settings
37 | USB Controller
38 | AR.Drone
39 | PS3 Controller
40 | PS3 Buttons
41 |
42 |
--------------------------------------------------------------------------------
/javadrone-api/src/main/java/com/codeminders/ardrone/controllers/decoders/SonyPS3ControllerStateDecoder.java:
--------------------------------------------------------------------------------
1 | package com.codeminders.ardrone.controllers.decoders;
2 |
3 | import java.io.IOException;
4 | import java.util.BitSet;
5 |
6 | import com.codeminders.ardrone.controllers.GameControllerState;
7 | import com.codeminders.ardrone.controllers.ControllerData;
8 |
9 | public class SonyPS3ControllerStateDecoder implements ControllerStateDecoder {
10 |
11 | private int joystickCoordConv(byte b)
12 | {
13 | int v = b < 0 ? b + 256 : b;
14 | return(v - 128);
15 | }
16 |
17 | public GameControllerState decodeState(ControllerData data) throws IOException {
18 |
19 | byte[] buf = data.getBuffer();
20 |
21 | BitSet bs = new BitSet(24);
22 | for(int i = 0; i < 8; i++)
23 | {
24 | if((1 & (buf[2] >> i)) == 1)
25 | bs.set(i);
26 | }
27 |
28 | for(int i = 0; i < 8; i++)
29 | {
30 | if((1 & (buf[3] >> i)) == 1)
31 | bs.set(8 + i);
32 | }
33 | for(int i = 0; i < 8; i++)
34 | {
35 | if((1 & (buf[4] >> i)) == 1)
36 | bs.set(16 + i);
37 | }
38 |
39 | int i = 0;
40 | boolean select = bs.get(i++);
41 | boolean leftJoystickPress = bs.get(i++);
42 | boolean rightJoystickPress = bs.get(i++);
43 | boolean start = bs.get(i++);
44 | bs.get(i++);
45 | bs.get(i++);
46 | bs.get(i++);
47 | bs.get(i++);
48 | boolean L2 = bs.get(i++);
49 | boolean R2 = bs.get(i++);
50 | boolean R1 = bs.get(i++);
51 | boolean L1 = bs.get(i++);
52 | boolean triangle = bs.get(i++);
53 | boolean circle = bs.get(i++);
54 | boolean cross = bs.get(i++);
55 | boolean square = bs.get(i++);
56 | boolean PS = bs.get(i++);
57 |
58 | int leftJoystickX = joystickCoordConv(buf[6]);
59 | int leftJoystickY = joystickCoordConv(buf[7]);
60 | int rightJoystickX = joystickCoordConv(buf[8]);
61 | int rightJoystickY = joystickCoordConv(buf[9]);
62 |
63 | // TODO: decode HAT switch
64 | int hatSwitchLeftRight = 0;
65 | int hatSwitchUpDown = 0;
66 |
67 | GameControllerState res = new GameControllerState(square, cross, circle, triangle, L1, R1, L2, R2, select, start,
68 | leftJoystickPress, rightJoystickPress, PS, hatSwitchLeftRight, hatSwitchUpDown, leftJoystickX,
69 | leftJoystickY, rightJoystickX, rightJoystickY);
70 |
71 | return res;
72 | }
73 |
74 | }
75 |
--------------------------------------------------------------------------------
/controltower-android/src/com/codeminders/ardrone/ControlMap.java:
--------------------------------------------------------------------------------
1 | package com.codeminders.ardrone;
2 |
3 | import java.io.IOException;
4 | import java.util.HashMap;
5 | import java.util.Iterator;
6 | import java.util.LinkedList;
7 | import java.util.List;
8 | import java.util.concurrent.Callable;
9 | import java.util.concurrent.ScheduledThreadPoolExecutor;
10 | import java.util.concurrent.TimeUnit;
11 |
12 | import com.codeminders.ardrone.AssignableControl.ControllerButton;
13 |
14 |
15 | public class ControlMap {
16 |
17 | private HashMap> map = new HashMap>();
18 | ScheduledThreadPoolExecutor exec = new ScheduledThreadPoolExecutor(1);
19 |
20 | public ControlMap() {
21 | loadMap();
22 | }
23 |
24 | public synchronized void sendCommand(ARDrone drone, ControllerButton button) throws IOException {
25 | List commands = map.get(button);
26 | if (commands == null) {
27 | return;
28 | }
29 | for (Iterator it = commands.iterator(); it.hasNext();) {
30 | final AssignableControl assignableCommand = it.next();
31 | if (assignableCommand.getDelay() > 0) {
32 | delayCommand(assignableCommand, drone);
33 | } else {
34 | assignableCommand.sendToDrone(drone);
35 | }
36 | }
37 | }
38 |
39 | /**
40 | * Executes a command for a drone with its assigned delay using an Executor
41 | * @param command
42 | * @param drone
43 | */
44 | private void delayCommand(final AssignableControl command, final ARDrone drone) {
45 | exec.schedule(new Callable