Hardware components | ||||||
![]() |
| × | 1 |
I discovered that there was an open source software package that allows users to create Java applications to control the AR Parrot drones. The API is called Autonomous4J and can be located here. The AR drones have their own wireless access point and I essentially used my computer to connect to WiFi signal. Once a connection was established, the software will control any action the drone is capable of including flight directions, LED control, and recording.
How to do itHere's a brief run down of the steps to get up and running:
1) Have a computer with Java installed.
2) Ensure that the Autonomous4J libraries are on the classpath for your application.
3) Code your application.
4) Make sure your computer/device is connected to the WAP signal for the AR Drone.
5) Execute your application.
6) Have some Java!
The project in actionHere is a video of the project in action:
package drone;
public class demo {
public static void main(String[] args) {
performDemo(new Brain());
}
private static void performDemo(Brain br) {
//Attempt to connect to the drone
if (br.connect()) {
try {
//Execute drone commands
commands(br);
} catch (Exception e) {
e.printStackTrace();
} finally {
br.disconnect();
}
} else {
System.out.println("No Drone Connection.");
}
}
private static void commands(Brain br) {
br.takeoff().hold(3000);
br.stay().hold(3000);
br.land();
}
}
Brain class
Javapackage drone;
import java.util.List;
import org.autonomous4j.interfaces.A4jBrain;
import org.autonomous4j.listeners.xyz.A4jErrorListener;
import org.autonomous4j.listeners.xyz.A4jNavDataListener;
import org.autonomous4j.listeners.xyz.A4jReadyStateChangeListener;
import org.autonomous4j.tracking.A4jBlackBox;
import org.autonomous4j.tracking.A4jBlackBox.Movement;
import com.dronecontrol.droneapi.DroneController;
import com.dronecontrol.droneapi.ParrotDroneController;
import com.dronecontrol.droneapi.commands.composed.PlayLedAnimationCommand;
import com.dronecontrol.droneapi.data.Config;
import com.dronecontrol.droneapi.data.enums.LedAnimation;
public class Brain implements A4jBrain {
private Config cfg;
private DroneController controller;
private final A4jBlackBox recorder;
private boolean isRecording;
public Brain() {
cfg = new Config("ProtoDrone", "profile", 1);
this.recorder = new A4jBlackBox();
isRecording = true;
}
@Override
public boolean connect() {
return connectToDrone("192.168.1.1");
}
public boolean connectToDrone(String ipAddress) {
try {
controller = ParrotDroneController.build();
controller.start(cfg);
controller.addNavDataListener(new A4jNavDataListener());
controller.addReadyStateChangeListener(new A4jReadyStateChangeListener());
controller.addErrorListener(new A4jErrorListener());
} catch (Exception ex) {
System.err.println("Exception creating new drone connection: " + ex.getMessage());
return false;
}
return true;
}
@Override
public void disconnect() {
if (controller != null) {
controller.stop();
}
recorder.shutdown();
}
@Override
public A4jBrain doFor(long ms) {
return hold(ms);
}
@Override
public A4jBrain hold(long ms) {
System.out.println("Hold for " + ms + " milliseconds...");
try {
Thread.sleep(ms);
if (isRecording) {
recorder.recordDuration(ms);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
return this;
}
@Override
public A4jBrain stay() {
return hover();
}
private A4jBrain hover() {
System.out.println("--Hover--");
controller.move(0, 0, 0, 0);
if (isRecording) {
recorder.recordAction(A4jBlackBox.Action.STAY);
}
return this;
}
@Override
public A4jBrain goHome() {
processRecordedMovements(recorder.home());
return this;
}
@Override
public A4jBrain replay() {
processRecordedMovements(recorder.getRecording());
return this;
}
@Override
public void processRecordedMovements(List<Movement> moves) {
// Disable recording for playback
isRecording = false;
for (Movement curMov : moves) {
switch(curMov.getAction()) {
case FORWARD:
forward(curMov.getSpeed());
break;
case BACKWARD:
backward(curMov.getSpeed());
break;
case RIGHT:
goRight(curMov.getSpeed());
break;
case LEFT:
goLeft(curMov.getSpeed());
break;
case UP:
up(curMov.getSpeed());
break;
case DOWN:
down(curMov.getSpeed());
break;
case STAY:
stay();
break;
case TAKEOFF:
takeoff();
break;
case LAND:
land();
break;
case LIGHTS:
playLedAnimation(curMov.getSpeed(), (int) curMov.getDuration()/1000);
break;
}
hold(curMov.getDuration());
System.out.println(curMov);
}
// Re-enable recording
isRecording = true;
}
public void land() {
System.out.println("Land.");
controller.land();
if (isRecording) {
recorder.recordAction(A4jBlackBox.Action.LAND);
}
}
public A4jBrain takeoff() {
System.out.println("Takeoff!");
controller.takeOff();
if (isRecording) {
recorder.recordAction(A4jBlackBox.Action.TAKEOFF);
}
return this;
}
public A4jBrain forward(int speed) {
System.out.println("Forward @" + speed);
if (isRecording) {
recorder.recordAction(A4jBlackBox.Action.FORWARD, speed);
}
return move(0f, -perc2float(speed), 0f, 0f);
}
public A4jBrain backward() {
return backward(100);
}
public A4jBrain backward(int speed) {
System.out.println("Backward @" + speed);
if (isRecording) {
recorder.recordAction(A4jBlackBox.Action.BACKWARD, speed);
}
return move(0f, perc2float(speed), 0f, 0f);
}
public A4jBrain up() {
return up(100);
}
public A4jBrain up(int speed) {
System.out.println("up @" + speed);
if (isRecording) {
recorder.recordAction(A4jBlackBox.Action.UP, speed);
}
return move(0f, 0f, perc2float(speed), 0f);
}
public A4jBrain down() {
return down(100);
}
public A4jBrain down(int speed) {
System.out.println("down @" + speed);
if (isRecording) {
recorder.recordAction(A4jBlackBox.Action.DOWN, speed);
}
return move(0f, 0f, -perc2float(speed), 0f);
}
public A4jBrain goRight(int speed) {
System.out.println("goRight @" + speed);
if (isRecording) {
recorder.recordAction(A4jBlackBox.Action.RIGHT, speed);
}
return move(perc2float(speed), 0f, 0f, 0f);
}
public A4jBrain goLeft(int speed) {
System.out.println("goLeft @" + speed);
if (isRecording) {
recorder.recordAction(A4jBlackBox.Action.LEFT, speed);
}
return move(-perc2float(speed), 0f, 0f, 0f);
}
public A4jBrain playLedAnimation(float frequency, int durationSeconds) {
// "Default" LED animation sequence is blank for now
playLedAnimation(LedAnimation.BLANK, frequency, durationSeconds);
return this;
}
public A4jBrain playLedAnimation(LedAnimation animation, float frequency, int durationSeconds) {
if (isRecording) {
recorder.recordAction(A4jBlackBox.Action.LIGHTS, (int) frequency);
}
controller.executeCommandsAsync(
new PlayLedAnimationCommand(cfg.getLoginData(),
animation, frequency, durationSeconds));
hold(durationSeconds * 1000);
System.out.println("Blinking " + animation.name() + ", Frequency: " +
frequency + " for " + durationSeconds + " seconds.");
return this;
}
public A4jBrain move(float roll ,float pitch, float gaz, float yaw) {
roll = limit(roll, -1f, 1f);
pitch = limit(pitch, -1f, 1f);
gaz = limit(gaz, -1f, 1f);
yaw = limit(yaw, -1f, 1f);
controller.move(roll, pitch, yaw, gaz);
return this;
}
private float limit(float f, float min, float max) {
return (f > max ? max : (f < min ? min : f));
}
private float perc2float(int speed) {
return (float) (speed / 100.0f);
}
}
Comments
Please log in or sign up to comment.