Refactored USB Controller state decoding. Now Android and Desctop appications are using same decoding API

Esse commit está contido em:
Denis Shmyga
2012-09-21 19:15:56 +03:00
commit 8de69ed644
30 arquivos alterados com 647 adições e 1068 exclusões
+1 -1
Ver Arquivo
@@ -11,6 +11,6 @@
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
# Project target.
target=Google Inc.:Google APIs:8
target=android-12
android.library=false
android.library.reference.1=../javadrone-api
+2 -3
Ver Arquivo
@@ -1,9 +1,8 @@
<resources>
<string name="app_name">andaDrdrone</string>
<string name="hello_world">Hello world!</string>
<string name="app_name">ControlTower</string>
<string name="menu_settings">Settings</string>
<string name="title_activity_main">MainActivity</string>
<string name="title_activity_main">ControlTower</string>
<string name="str_exit">Exit</string>
</resources>
@@ -1,13 +1,12 @@
package com.codeminders.ardrone;
import java.io.IOException;
import com.codeminders.ardrone.ARDrone;
import com.codeminders.ardrone.ARDrone.Animation;
import com.codeminders.ardrone.ARDrone.LED;
import com.codeminders.ardrone.ARDrone.VideoChannel;
import java.io.*;
import java.util.logging.Level;
/**
* This class represents one control mapping for a button and at the same
@@ -45,74 +44,14 @@ public class AssignableControl {
private float frequency;
private int duration;
private int delay;
private String prefString;
private static final VideoChannel[] VIDEO_CYCLE = {VideoChannel.HORIZONTAL_ONLY,
VideoChannel.VERTICAL_ONLY, VideoChannel.VERTICAL_IN_HORIZONTAL, VideoChannel.HORIZONTAL_IN_VERTICAL};
private int video_index = 0;
private File recFile;
/**
* Creates the control from a string that is stored in the java preferences of this app
* @param prefString
*/
public AssignableControl(String prefString) {
String[] strings = prefString.split("/");
if (strings.length < 3) {
throw new IllegalStateException("preference string malformed");
}
button = ControllerButton.valueOf(strings[0]);
command = Command.valueOf(strings[1]);
delay = Integer.parseInt(strings[2]);
switch (command) {
case PLAY_ANIMATION:
anim = Animation.valueOf(strings[3]);
duration = Integer.parseInt(strings[4]);
break;
case PLAY_LED:
led = LED.valueOf(strings[3]);
frequency = Float.parseFloat(strings[4]);
duration = Integer.parseInt(strings[5]);
break;
case RECORD_VIDEO:
case TAKE_SNAPSHOT:
try {
recFile = new File(strings[3].replace('?', File.separatorChar));
} catch (Exception e) {
}
break;
}
this.prefString = prefString;
}
public AssignableControl(ControllerButton button, LED led, int delay, float frequency, int duration) {
this.command = Command.PLAY_LED;
this.delay = delay;
this.led = led;
this.frequency = frequency;
this.duration = duration;
prefString = button.name() + "/" + command.name() + "/" + delay + "/" + led.name() + "/" + frequency + "/" + duration;
}
public AssignableControl(ControllerButton button, Animation anim, int delay, int duration) {
this.command = Command.PLAY_ANIMATION;
this.delay = delay;
this.anim = anim;
this.duration = duration;
prefString = button.name() + "/" + command.name() + "/" + delay + "/" + anim.name() + "/" + duration;
}
public AssignableControl(ControllerButton button, Command command, int delay, File file) {
this.command = command;
this.delay = delay;
this.recFile = file;
prefString = button.name() + "/" + command.name() + "/" + delay + "/" + file.getPath().replace(File.separatorChar, '?');
}
public AssignableControl(ControllerButton button, Command command, int delay) {
this.command = command;
this.delay = delay;
prefString = button.name() + "/" + command.name() + "/" + delay;
}
/**
@@ -169,11 +108,6 @@ public class AssignableControl {
}
/**
* Used for VIDEO_CYCLE commands to cycle the video channel
* @param drone
* @throws IOException
*/
private void cycleVideoChannel(ARDrone drone) throws IOException {
if (++video_index == VIDEO_CYCLE.length) {
video_index = 0;
@@ -216,16 +150,4 @@ public class AssignableControl {
public int getDelay() {
return delay;
}
public File getRecFile() {
return recFile;
}
/**
* Gets the complete data of this object as a string for storing into java preferences
* @return
*/
public String getPrefString() {
return prefString;
}
}
@@ -4,20 +4,20 @@ import java.io.IOException;
import java.util.concurrent.atomic.AtomicBoolean;
import com.codeminders.ardrone.AssignableControl.ControllerButton;
import com.codeminders.ardrone.controller.PS3Controller;
import com.codeminders.ardrone.controller.PS3ControllerState;
import com.codeminders.ardrone.controller.PS3ControllerStateChange;
import com.codeminders.ardrone.controllers.Controller;
import com.codeminders.ardrone.controllers.ControllerStateChange;
import com.codeminders.ardrone.controllers.GameControllerState;
public class ControllerThread extends Thread{
ARDrone drone;
PS3Controller controller;
Controller controller;
private final ControlMap controlMap = new ControlMap();
private static float CONTROL_THRESHOLD = 0.5f;
private static final long READ_UPDATE_DELAY_MS = 5L;
private final AtomicBoolean flipSticks = new AtomicBoolean(false);
public ControllerThread(ARDrone drone, PS3Controller controller) {
public ControllerThread(ARDrone drone, Controller controller) {
super();
this.drone = drone;
this.controller = controller;
@@ -28,11 +28,11 @@ public class ControllerThread extends Thread{
public void run() {
try
{
PS3ControllerState oldpad = null;
GameControllerState oldpad = null;
while(true)
{
PS3ControllerState pad = controller.read();
PS3ControllerStateChange pad_change = new PS3ControllerStateChange(oldpad, pad);
GameControllerState pad = controller.read();
ControllerStateChange pad_change = new ControllerStateChange(oldpad, pad);
oldpad = pad;
if(pad_change.isStartChanged() && pad_change.isStart())
@@ -145,7 +145,6 @@ public class ControllerThread extends Thread{
try {
drone.disconnect();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@@ -6,8 +6,9 @@ import java.net.InetAddress;
import java.util.HashMap;
import java.util.Iterator;
import com.codeminders.ardrone.controller.PS3Controller;
import com.codeminders.ardrone.controller.SonyPS3Controller;
import com.codeminders.ardrone.controller.usbhost.AfterGlowUsbHostController;
import com.codeminders.ardrone.controller.usbhost.SonyPS3UsbHostController;
import com.codeminders.ardrone.controller.usbhost.UsbHostController;
import android.app.Activity;
import android.app.PendingIntent;
@@ -31,14 +32,14 @@ import android.widget.TextView;
public class MainActivity extends Activity implements DroneVideoListener {
private static final long CONNECTION_TIMEOUT = 100000;
private static final long CONNECTION_TIMEOUT = 10000;
static ARDrone drone;
ImageView display;
TextView state;
Button connectButton;
PS3Controller controller;
Button connectPs3Button;
UsbHostController controller;
Button connectUsbControllerButton;
UsbManager manager;
@@ -59,26 +60,37 @@ public class MainActivity extends Activity implements DroneVideoListener {
if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
if (deviceConnected != null) {
if (SonyPS3Controller.isA(deviceConnected)) {
boolean joystickFound = false;
if (SonyPS3UsbHostController.isA(deviceConnected)) {
try {
controller = new SonyPS3Controller(deviceConnected, manager);
connectPs3Button.setEnabled(false);
connectPs3Button.setText("Connected");
// Start joystic reading thread
ctrThread = new ControllerThread(drone, controller);
ctrThread.setName("Controll Thread");
ctrThread.start();
controller = new SonyPS3UsbHostController(deviceConnected, manager);
joystickFound = true;
} catch (Throwable e) {
connectPs3Button.setText("Error");
connectUsbControllerButton.setText("Error");
}
} else if (AfterGlowUsbHostController.isA(deviceConnected)) {
try {
controller = new AfterGlowUsbHostController(deviceConnected, manager);
joystickFound = true;
} catch (Throwable e) {
connectUsbControllerButton.setText("Error");
}
}
if (joystickFound) {
connectUsbControllerButton.setEnabled(false);
connectUsbControllerButton.setText("Connected");
// Start joystick reading thread
ctrThread = new ControllerThread(drone, controller);
ctrThread.setName("Controll Thread");
ctrThread.start();
}
}
} else {
connectPs3Button.setText("Denied");
connectPs3Button.setEnabled(false);
connectUsbControllerButton.setText("Denied");
connectUsbControllerButton.setEnabled(false);
}
}
}
@@ -112,9 +124,9 @@ public class MainActivity extends Activity implements DroneVideoListener {
});
manager = (UsbManager) getSystemService(Context.USB_SERVICE);
connectPs3Button = (Button) findViewById(R.id.ps3Button);
connectUsbControllerButton = (Button) findViewById(R.id.ps3Button);
connectPs3Button.setOnClickListener(new View.OnClickListener() {
connectUsbControllerButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
HashMap<String, UsbDevice> deviceList = manager.getDeviceList();
Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
@@ -1,38 +0,0 @@
package com.codeminders.ardrone.controller;
import java.io.IOException;
import android.hardware.usb.UsbDevice;
/**
* Base abstract class for supported PS3-compatible USB controllers
*
* @author lord
*
*/
public abstract class PS3Controller
{
UsbDevice dev;
public abstract void close() throws IOException;
public abstract PS3ControllerState read() throws IOException;
@Override
public String toString()
{
StringBuilder builder = new StringBuilder();
builder.append("PS3Controller [");
builder.append("DeviceName=");
builder.append(dev.getDeviceName());
builder.append(", product=");
builder.append(dev.getProductId());
builder.append("]");
return builder.toString();
}
}
@@ -1,242 +0,0 @@
package com.codeminders.ardrone.controller;
/**
* Data structure describing state of generic PS-3 compatible game controller.
*
* @author lord
*/
public class PS3ControllerState
{
// buttons with pictures
protected boolean square;
protected boolean cross;
protected boolean circle;
protected boolean triangle;
// Front-side buttons
protected boolean L1;
protected boolean R1;
protected boolean L2;
protected boolean R2;
// square small "select" button
protected boolean select;
// triangular small "start" button
protected boolean start;
// Pressing on joysticks (button)
protected boolean leftJoystickPress;
protected boolean rightJoystickPress;
// PS3 button (sometimes labeled as Home on 3rd party models)
protected boolean PS;
// Direction pad (hatswitch)
protected int hatSwitchLeftRight;
protected int hatSwitchUpDown;
// Analog joysticks
protected int leftJoystickX;
protected int leftJoystickY;
protected int rightJoystickX;
protected int rightJoystickY;
public PS3ControllerState(boolean square, boolean cross, boolean circle, boolean triangle, boolean l1, boolean r1,
boolean l2, boolean r2, boolean select, boolean start, boolean leftJoystickPress,
boolean rightJoystickPress, boolean pS, int hatSwitchLeftRight, int hatSwitchUpDown, int leftJoystickX,
int leftJoystickY, int rightJoystickX, int rightJoystickY)
{
this.square = square;
this.cross = cross;
this.circle = circle;
this.triangle = triangle;
L1 = l1;
R1 = r1;
L2 = l2;
R2 = r2;
this.select = select;
this.start = start;
this.leftJoystickPress = leftJoystickPress;
this.rightJoystickPress = rightJoystickPress;
PS = pS;
this.hatSwitchLeftRight = hatSwitchLeftRight;
this.hatSwitchUpDown = hatSwitchUpDown;
this.leftJoystickX = leftJoystickX;
this.leftJoystickY = leftJoystickY;
this.rightJoystickX = rightJoystickX;
this.rightJoystickY = rightJoystickY;
}
public PS3ControllerState(PS3ControllerState o)
{
this.square = o.square;
this.cross = o.cross;
this.circle = o.circle;
this.triangle = o.triangle;
L1 = o.L1;
R1 = o.R1;
L2 = o.L2;
R2 = o.R2;
this.select = o.select;
this.start = o.start;
this.leftJoystickPress = o.leftJoystickPress;
this.rightJoystickPress = o.rightJoystickPress;
PS = o.PS;
this.hatSwitchLeftRight = o.hatSwitchLeftRight;
this.hatSwitchUpDown = o.hatSwitchUpDown;
this.leftJoystickX = o.leftJoystickX;
this.leftJoystickY = o.leftJoystickY;
this.rightJoystickX = o.rightJoystickX;
this.rightJoystickY = o.rightJoystickY;
}
public PS3ControllerState()
{
}
public int getHatSwitchLeftRight()
{
return hatSwitchLeftRight;
}
public int getHatSwitchUpDown()
{
return hatSwitchUpDown;
}
public int getLeftJoystickX()
{
return leftJoystickX;
}
public int getLeftJoystickY()
{
return leftJoystickY;
}
public int getRightJoystickX()
{
return rightJoystickX;
}
public int getRightJoystickY()
{
return rightJoystickY;
}
public boolean isCircle()
{
return circle;
}
public boolean isCross()
{
return cross;
}
public boolean isL1()
{
return L1;
}
public boolean isL2()
{
return L2;
}
public boolean isLeftJoystickPress()
{
return leftJoystickPress;
}
public boolean isPS()
{
return PS;
}
public boolean isR1()
{
return R1;
}
public boolean isR2()
{
return R2;
}
public boolean isRightJoystickPress()
{
return rightJoystickPress;
}
public boolean isSelect()
{
return select;
}
public boolean isSquare()
{
return square;
}
public boolean isStart()
{
return start;
}
public boolean isTriangle()
{
return triangle;
}
@Override
public String toString()
{
StringBuilder builder = new StringBuilder();
builder.append("PS3ControllerState [square=");
builder.append(square);
builder.append(", cross=");
builder.append(cross);
builder.append(", circle=");
builder.append(circle);
builder.append(", triangle=");
builder.append(triangle);
builder.append(", L1=");
builder.append(L1);
builder.append(", R1=");
builder.append(R1);
builder.append(", L2=");
builder.append(L2);
builder.append(", R2=");
builder.append(R2);
builder.append(", select=");
builder.append(select);
builder.append(", start=");
builder.append(start);
builder.append(", rightJoystickPress=");
builder.append(rightJoystickPress);
builder.append(", leftJoystickPress=");
builder.append(leftJoystickPress);
builder.append(", PS=");
builder.append(PS);
builder.append(", hatSwitchLeftRight=");
builder.append(hatSwitchLeftRight);
builder.append(", hatSwitchUpDown=");
builder.append(hatSwitchUpDown);
builder.append(", leftJoystickX=");
builder.append(leftJoystickX);
builder.append(", leftJoystickY=");
builder.append(leftJoystickY);
builder.append(", rightJoystickX=");
builder.append(rightJoystickX);
builder.append(", rightJoystickY=");
builder.append(rightJoystickY);
builder.append("]");
return builder.toString();
}
}
@@ -1,207 +0,0 @@
package com.codeminders.ardrone.controller;
public class PS3ControllerStateChange extends PS3ControllerState
{
protected boolean squareChanged;
protected boolean crossChanged;
protected boolean circleChanged;
protected boolean triangleChanged;
protected boolean L1Changed;
protected boolean R1Changed;
protected boolean L2Changed;
protected boolean R2Changed;
protected boolean selectChanged;
protected boolean startChanged;
protected boolean leftJoystickPressChanged;
protected boolean rightJoystickPressChanged;
protected boolean PSChanged;
protected int hatSwitchLeftRightChange;
protected int hatSwitchUpDownChange;
protected int leftJoystickXChange;
protected int leftJoystickYChange;
protected int rightJoystickXChange;
protected int rightJoystickYChange;
// composite change flags
private boolean buttonStateChanged;
private boolean hatChanged;
private boolean leftJoystickChanged;
private boolean rightJoystickChanged;
private boolean joysticksChanged;
private boolean changed;
/**
*
* @param o Old state
* @param n New state
*/
public PS3ControllerStateChange(PS3ControllerState o, PS3ControllerState n)
{
super(n);
if(o==null)
o=n;
squareChanged = o.square != n.square;
crossChanged = o.cross != n.cross;
circleChanged = o.circle != n.circle;
triangleChanged = o.triangle != n.triangle;
L1Changed = o.L1 != n.L1;
R1Changed = o.R1 != n.R1;
L2Changed = o.L2 != n.L2;
R2Changed = o.R2 != n.R2;
selectChanged = o.select != n.select;
startChanged = o.start != n.start;
leftJoystickPressChanged = o.leftJoystickPress != n.leftJoystickPress;
rightJoystickPressChanged = o.rightJoystickPress != n.rightJoystickPress;
PSChanged = o.PS != n.PS;
hatSwitchLeftRightChange = n.hatSwitchLeftRight - o.hatSwitchLeftRight;
hatSwitchUpDownChange = n.hatSwitchUpDown - o.hatSwitchUpDown;
leftJoystickXChange = n.leftJoystickX - o.leftJoystickX;
leftJoystickYChange = n.leftJoystickY - o.leftJoystickY;
rightJoystickXChange = n.rightJoystickX - o.rightJoystickX;
rightJoystickYChange = n.rightJoystickY - o.rightJoystickY;
buttonStateChanged = squareChanged || crossChanged || circleChanged || triangleChanged || L1Changed
|| R1Changed || L2Changed || R2Changed || selectChanged || startChanged || leftJoystickPressChanged
|| rightJoystickPressChanged || PSChanged;
hatChanged = hatSwitchLeftRightChange != 0 || hatSwitchUpDownChange != 0;
leftJoystickChanged = leftJoystickXChange != 0 || leftJoystickYChange != 0;
rightJoystickChanged = rightJoystickXChange != 0 || rightJoystickYChange != 0;
joysticksChanged = leftJoystickChanged || rightJoystickChanged;
changed = joysticksChanged || hatChanged || buttonStateChanged;
}
public int getHatSwitchLeftRightChange()
{
return hatSwitchLeftRightChange;
}
public int getHatSwitchUpDownChange()
{
return hatSwitchUpDownChange;
}
public int getLeftJoystickXChange()
{
return leftJoystickXChange;
}
public int getLeftJoystickYChange()
{
return leftJoystickYChange;
}
public int getRightJoystickXChange()
{
return rightJoystickXChange;
}
public int getRightJoystickYChange()
{
return rightJoystickYChange;
}
public boolean isButtonStateChanged()
{
return buttonStateChanged;
}
public boolean isChanged()
{
return changed;
}
public boolean isCircleChanged()
{
return circleChanged;
}
public boolean isCrossChanged()
{
return crossChanged;
}
public boolean isHatChanged()
{
return hatChanged;
}
public boolean isJoysticksChanged()
{
return joysticksChanged;
}
public boolean isL1Changed()
{
return L1Changed;
}
public boolean isL2Changed()
{
return L2Changed;
}
public boolean isLeftJoystickChanged()
{
return leftJoystickChanged;
}
public boolean isLeftJoystickPressChanged()
{
return leftJoystickPressChanged;
}
public boolean isPSChanged()
{
return PSChanged;
}
public boolean isR1Changed()
{
return R1Changed;
}
public boolean isR2Changed()
{
return R2Changed;
}
public boolean isRightJoystickChanged()
{
return rightJoystickChanged;
}
public boolean isRightJoystickPressChanged()
{
return rightJoystickPressChanged;
}
public boolean isSelectChanged()
{
return selectChanged;
}
public boolean isSquareChanged()
{
return squareChanged;
}
public boolean isStartChanged()
{
return startChanged;
}
public boolean isTriangleChanged()
{
return triangleChanged;
}
}
@@ -1,147 +0,0 @@
package com.codeminders.ardrone.controller;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.BitSet;
import android.hardware.usb.UsbConstants;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbEndpoint;
import android.hardware.usb.UsbInterface;
import android.hardware.usb.UsbManager;
import android.hardware.usb.UsbRequest;
import android.widget.TextView;
public class SonyPS3Controller extends PS3Controller
{
private static final int VENDOR_ID = 1356;
private static final int PRODUCT_ID = 616;
int bufferSize = 0;
ByteBuffer buffer;
UsbDeviceConnection readDataConnection = null;
UsbEndpoint usbEndpointRead = null;
UsbRequest request;
UsbRequest requestQueued;
public static boolean isA(UsbDevice dev)
{
return(dev.getVendorId() == VENDOR_ID && dev.getProductId() == PRODUCT_ID);
}
public SonyPS3Controller(UsbDevice dev, UsbManager manager) throws IOException
{
this.dev = dev;
readDataConnection = manager.openDevice(dev);
if (null == readDataConnection) {
throw new IOException("Failed to open connection to USB device");
}
UsbInterface usbInterfaceRead = dev.getInterface(0);
readDataConnection.claimInterface(usbInterfaceRead, true);
for(int i = 0; i < usbInterfaceRead.getEndpointCount(); i++) {
if (usbInterfaceRead.getEndpoint(i).getDirection() == UsbConstants.USB_DIR_IN) {
usbEndpointRead = usbInterfaceRead.getEndpoint(i);
break;
}
}
if (null == usbEndpointRead) {
throw new IOException("Failed to find usb read endpoint");
}
bufferSize = usbEndpointRead.getMaxPacketSize();
buffer = ByteBuffer.allocate(bufferSize + 1);
request = new UsbRequest();
request.initialize(readDataConnection, usbEndpointRead);
}
private int joystickCoordConv(byte b)
{
int v = b < 0 ? b + 256 : b;
return(v - 128);
}
@Override
public PS3ControllerState read() throws IOException
{
PS3ControllerState res = null;
buffer.clear();
request.queue(buffer, bufferSize);
requestQueued = readDataConnection.requestWait();
if (request.equals(requestQueued))
{
byte[] buf = new byte[bufferSize + 1];
buffer.get(buf, 0, bufferSize);
BitSet bs = new BitSet(24);
for(int i = 0; i < 8; i++)
{
if((1 & (buf[2] >> i)) == 1)
bs.set(i);
}
for(int i = 0; i < 8; i++)
{
if((1 & (buf[3] >> i)) == 1)
bs.set(8 + i);
}
for(int i = 0; i < 8; i++)
{
if((1 & (buf[4] >> i)) == 1)
bs.set(16 + i);
}
int i = 0;
boolean select = bs.get(i++);
boolean leftJoystickPress = bs.get(i++);
boolean rightJoystickPress = bs.get(i++);
boolean start = bs.get(i++);
bs.get(i++);
bs.get(i++);
bs.get(i++);
bs.get(i++);
boolean L2 = bs.get(i++);
boolean R2 = bs.get(i++);
boolean R1 = bs.get(i++);
boolean L1 = bs.get(i++);
boolean triangle = bs.get(i++);
boolean circle = bs.get(i++);
boolean cross = bs.get(i++);
boolean square = bs.get(i++);
boolean PS = bs.get(i++);
int leftJoystickX = joystickCoordConv(buf[6]);
int leftJoystickY = joystickCoordConv(buf[7]);
int rightJoystickX = joystickCoordConv(buf[8]);
int rightJoystickY = joystickCoordConv(buf[9]);
int hatSwitchLeftRight = 0;
int hatSwitchUpDown = 0;
res = new PS3ControllerState(square, cross, circle, triangle, L1, R1, L2, R2, select, start,
leftJoystickPress, rightJoystickPress, PS, hatSwitchLeftRight, hatSwitchUpDown, leftJoystickX,
leftJoystickY, rightJoystickX, rightJoystickY);
}
return res;
}
@Override
public void close() throws IOException {
if (null != readDataConnection) {
readDataConnection.close();
}
}
}
@@ -0,0 +1,31 @@
package com.codeminders.ardrone.controller.usbhost;
import java.io.IOException;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbManager;
import com.codeminders.ardrone.controllers.decoders.AfterGlowControllerDecoder;
import com.codeminders.ardrone.controllers.decoders.ControllerStateDecoder;
public class AfterGlowUsbHostController extends UsbHostController {
private static final int VENDOR_ID = 3695;
private static final int PRODUCT_ID = 25346;
static ControllerStateDecoder decoder = new AfterGlowControllerDecoder();
public AfterGlowUsbHostController(UsbDevice dev, UsbManager manager) throws IOException {
super(dev, manager, decoder);
}
@Override
public String getName() {
return "SonyPS3Controller over usb host";
}
public static boolean isA(UsbDevice dev)
{
return(dev.getVendorId() == VENDOR_ID && dev.getProductId() == PRODUCT_ID);
}
}
@@ -0,0 +1,31 @@
package com.codeminders.ardrone.controller.usbhost;
import java.io.IOException;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbManager;
import com.codeminders.ardrone.controllers.decoders.ControllerStateDecoder;
import com.codeminders.ardrone.controllers.decoders.SonyPS3ControllerStateDecoder;
public class SonyPS3UsbHostController extends UsbHostController {
private static final int VENDOR_ID = 1356;
private static final int PRODUCT_ID = 616;
static ControllerStateDecoder decoder = new SonyPS3ControllerStateDecoder();
public SonyPS3UsbHostController(UsbDevice dev, UsbManager manager) throws IOException {
super(dev, manager, decoder);
}
@Override
public String getName() {
return "SonyPS3Controller over usb host";
}
public static boolean isA(UsbDevice dev)
{
return(dev.getVendorId() == VENDOR_ID && dev.getProductId() == PRODUCT_ID);
}
}
@@ -0,0 +1,100 @@
package com.codeminders.ardrone.controller.usbhost;
import java.io.IOException;
import java.nio.ByteBuffer;
import android.hardware.usb.UsbConstants;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbEndpoint;
import android.hardware.usb.UsbInterface;
import android.hardware.usb.UsbManager;
import android.hardware.usb.UsbRequest;
import com.codeminders.ardrone.controllers.Controller;
import com.codeminders.ardrone.controllers.ControllerData;
import com.codeminders.ardrone.controllers.GameControllerState;
import com.codeminders.ardrone.controllers.decoders.ControllerStateDecoder;
public abstract class UsbHostController extends Controller {
int bufferSize = 0;
ByteBuffer buffer;
UsbDeviceConnection readDataConnection = null;
UsbEndpoint usbEndpointRead = null;
UsbRequest request;
UsbRequest requestQueued;
UsbDevice dev;
ControllerStateDecoder decodder;
@Override
public GameControllerState read() throws IOException
{
GameControllerState res = null;
buffer.clear();
request.queue(buffer, bufferSize);
requestQueued = readDataConnection.requestWait();
if (request.equals(requestQueued))
{
byte[] buf = new byte[bufferSize + 1];
buffer.get(buf, 0, bufferSize);
return decodder.decodeState(new ControllerData(buf, bufferSize + 1));
}
return res;
}
public UsbHostController(UsbDevice dev, UsbManager manager, ControllerStateDecoder decodder) throws IOException
{
this.decodder = decodder;
this.dev = dev;
readDataConnection = manager.openDevice(dev);
if (null == readDataConnection) {
throw new IOException("Failed to open connection to USB device");
}
UsbInterface usbInterfaceRead = dev.getInterface(0);
readDataConnection.claimInterface(usbInterfaceRead, true);
for(int i = 0; i < usbInterfaceRead.getEndpointCount(); i++) {
if (usbInterfaceRead.getEndpoint(i).getDirection() == UsbConstants.USB_DIR_IN) {
usbEndpointRead = usbInterfaceRead.getEndpoint(i);
break;
}
}
if (null == usbEndpointRead) {
throw new IOException("Failed to find usb read endpoint");
}
bufferSize = usbEndpointRead.getMaxPacketSize();
buffer = ByteBuffer.allocate(bufferSize + 1);
request = new UsbRequest();
request.initialize(readDataConnection, usbEndpointRead);
}
@Override
public void close() throws IOException {
if (null != readDataConnection) {
readDataConnection.close();
}
}
@Override
public String getManufacturerString() {
return "read api is not supported";
}
@Override
public String getProductString() {
return "read api is not supported";
}
}
@@ -8,11 +8,9 @@ package com.codeminders.controltower;
import java.awt.Color;
import java.awt.Dimension;
import java.io.IOException;
import java.net.URL;
import java.net.UnknownHostException;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import java.util.logging.LogManager;
import java.util.prefs.Preferences;
import javax.swing.ImageIcon;
@@ -25,18 +23,15 @@ import com.codeminders.ardrone.ARDrone.VideoChannel;
import com.codeminders.ardrone.DroneStatusChangeListener;
import com.codeminders.ardrone.NavData;
import com.codeminders.ardrone.NavDataListener;
import com.codeminders.ardrone.controllers.AfterGlowController;
import com.codeminders.ardrone.controllers.Controller;
import com.codeminders.ardrone.controllers.GameControllerState;
import com.codeminders.ardrone.controllers.ControllerStateChange;
import com.codeminders.ardrone.controllers.KeyboardController;
import com.codeminders.ardrone.controllers.PS3Controller;
import com.codeminders.ardrone.controllers.PS3ControllerState;
import com.codeminders.ardrone.controllers.PS3ControllerStateChange;
import com.codeminders.ardrone.controllers.SonyPS3Controller;
import com.codeminders.ardrone.controllers.hid.manager.HIDControllerFinder;
import com.codeminders.controltower.config.AssignableControl.ControllerButton;
import com.codeminders.controltower.config.ControlMap;
import com.codeminders.hidapi.ClassPathLibraryLoader;
import com.codeminders.hidapi.HIDDeviceInfo;
import com.codeminders.hidapi.HIDDeviceNotFoundException;
import com.codeminders.hidapi.HIDManager;
/**
* The central class that represents the main window and also manages the
@@ -68,7 +63,7 @@ public class ControlTower extends javax.swing.JFrame implements DroneStatusChang
private final AtomicBoolean flipSticks = new AtomicBoolean(false);
private final Preferences prefs = Preferences.userNodeForPackage(this.getClass());
private ARDrone drone;
private final AtomicReference<PS3Controller> dev = new AtomicReference<PS3Controller>();
private final AtomicReference<Controller> dev = new AtomicReference<Controller>();
private final VideoPanel video = new VideoPanel();
private final DroneConfig droneConfigWindow;
private final ControlConfig controlConfigWindow;
@@ -126,7 +121,7 @@ public class ControlTower extends javax.swing.JFrame implements DroneStatusChang
*/
private void initController()
{
PS3Controller current = dev.get();
Controller current = dev.get();
if(current != null)
{
try
@@ -159,27 +154,12 @@ public class ControlTower extends javax.swing.JFrame implements DroneStatusChang
}
}
private static PS3Controller findController() throws IOException
private static Controller findController() throws IOException
{
if(!isHIDLibLoaded)
return null;
HIDDeviceInfo[] devs = HIDManager.getInstance().listDevices();
if (null != devs) {
for(int i = 0; i < devs.length; i++)
{
System.out.println("" + devs[i]);
if(AfterGlowController.isA(devs[i]))
{
return new AfterGlowController(devs[i]);
}
if(SonyPS3Controller.isA(devs[i]))
{
return new SonyPS3Controller(devs[i]);
}
}
}
return null;
return HIDControllerFinder.findController();
}
private void updateLoop()
@@ -222,11 +202,11 @@ public class ControlTower extends javax.swing.JFrame implements DroneStatusChang
System.err.println("Connected to the drone");
try
{
PS3ControllerState oldpad = null;
GameControllerState oldpad = null;
while(running.get())
{
PS3ControllerState pad = dev.get().read();
PS3ControllerStateChange pad_change = new PS3ControllerStateChange(oldpad, pad);
GameControllerState pad = dev.get().read();
ControllerStateChange pad_change = new ControllerStateChange(oldpad, pad);
oldpad = pad;
if(pad_change.isStartChanged() && pad_change.isStart())
+1 -1
Ver Arquivo
@@ -11,5 +11,5 @@
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
# Project target.
target=Google Inc.:Google APIs:8
target=Motorola Mobility, LLC.:ICS_R2:15
android.library=true
@@ -0,0 +1,38 @@
package com.codeminders.ardrone.controllers;
import java.io.IOException;
/**
* Base abstract class for supported controllers
*
* @author lord
*
*/
public abstract class Controller
{
public abstract void close() throws IOException;
public abstract String getName();
public abstract String getManufacturerString();
public abstract String getProductString();
public abstract GameControllerState read() throws IOException;
@Override
public String toString()
{
StringBuilder builder = new StringBuilder();
builder.append(getName() + " [");
builder.append("manufacturer=");
builder.append(getManufacturerString());
builder.append(", product=");
builder.append(getProductString());
builder.append("]");
return builder.toString();
}
}
@@ -0,0 +1,18 @@
package com.codeminders.ardrone.controllers;
public class ControllerData {
private byte[] buf;
int actualBufferDataLength;
public ControllerData(byte[] buf, int actualBufferDataLength) {
super();
this.buf = buf;
this.actualBufferDataLength = actualBufferDataLength;
}
public byte[] getBuffer() {
return buf;
}
public int getActualBufferDataLength() {
return actualBufferDataLength;
}
}
@@ -1,7 +1,7 @@
package com.codeminders.ardrone.controllers;
public class PS3ControllerStateChange extends PS3ControllerState
public class ControllerStateChange extends GameControllerState
{
protected boolean squareChanged;
protected boolean crossChanged;
@@ -36,7 +36,7 @@ public class PS3ControllerStateChange extends PS3ControllerState
* @param o Old state
* @param n New state
*/
public PS3ControllerStateChange(PS3ControllerState o, PS3ControllerState n)
public ControllerStateChange(GameControllerState o, GameControllerState n)
{
super(n);
@@ -2,11 +2,11 @@
package com.codeminders.ardrone.controllers;
/**
* Data structure describing state of generic PS-3 compatible game controller.
* Data structure describing state of generic compatible game controller.
*
* @author lord
*/
public class PS3ControllerState
public class GameControllerState
{
// buttons with pictures
protected boolean square;
@@ -44,7 +44,7 @@ public class PS3ControllerState
protected int rightJoystickX;
protected int rightJoystickY;
public PS3ControllerState(boolean square, boolean cross, boolean circle, boolean triangle, boolean l1, boolean r1,
public GameControllerState(boolean square, boolean cross, boolean circle, boolean triangle, boolean l1, boolean r1,
boolean l2, boolean r2, boolean select, boolean start, boolean leftJoystickPress,
boolean rightJoystickPress, boolean pS, int hatSwitchLeftRight, int hatSwitchUpDown, int leftJoystickX,
int leftJoystickY, int rightJoystickX, int rightJoystickY)
@@ -70,7 +70,7 @@ public class PS3ControllerState
this.rightJoystickY = rightJoystickY;
}
public PS3ControllerState(PS3ControllerState o)
public GameControllerState(GameControllerState o)
{
this.square = o.square;
this.cross = o.cross;
@@ -94,7 +94,7 @@ public class PS3ControllerState
}
public PS3ControllerState()
public GameControllerState()
{
}
@@ -1,44 +1,21 @@
package com.codeminders.ardrone.controllers;
package com.codeminders.ardrone.controllers.decoders;
import java.io.IOException;
import java.util.BitSet;
import com.codeminders.hidapi.*;
import com.codeminders.ardrone.controllers.GameControllerState;
import com.codeminders.ardrone.controllers.ControllerData;
/**
* "Afterglow" controller for PS3
* "Afterglow" controller for PS3 state decodder
*
* @author lord
*
*/
public class AfterGlowController extends PS3Controller
public class AfterGlowControllerDecoder implements ControllerStateDecoder
{
private static final int VENDOR_ID = 3695;
private static final int PRODUCT_ID = 25346;
private static final int BUFSIZE = 32;
private static final int EXPECTED_BUFSIZE = 27;
public static boolean isA(HIDDeviceInfo hidDeviceInfo)
{
return(hidDeviceInfo.getVendor_id() == VENDOR_ID && hidDeviceInfo.getProduct_id() == PRODUCT_ID);
}
private byte[] buf = new byte[BUFSIZE];
public AfterGlowController() throws HIDDeviceNotFoundException, IOException
{
dev = HIDManager.getInstance().openById(VENDOR_ID, PRODUCT_ID, null);
dev.enableBlocking();
}
public AfterGlowController(HIDDeviceInfo hidDeviceInfo) throws IOException
{
dev = hidDeviceInfo.open();
dev.enableBlocking();
}
private int joystickCoordConv(byte b)
{
int v = b < 0 ? b + 256 : b;
@@ -46,13 +23,9 @@ public class AfterGlowController extends PS3Controller
}
@Override
public synchronized PS3ControllerState read() throws IOException
public GameControllerState decodeState(ControllerData data) throws IOException
{
int n = dev.read(buf);
if(n != EXPECTED_BUFSIZE)
{
throw new IOException("Received packed with unexpected size " + n);
}
byte[] buf = data.getBuffer();
BitSet bs = new BitSet(13);
for(int i = 0; i < 8; i++)
@@ -90,11 +63,10 @@ public class AfterGlowController extends PS3Controller
int hatSwitchLeftRight = 0;
int hatSwitchUpDown = 0;
PS3ControllerState res = new PS3ControllerState(square, cross, circle, triangle, L1, R1, L2, R2, select, start,
GameControllerState res = new GameControllerState(square, cross, circle, triangle, L1, R1, L2, R2, select, start,
leftJoystickPress, rightJoystickPress, PS, hatSwitchLeftRight, hatSwitchUpDown, leftJoystickX,
leftJoystickY, rightJoystickX, rightJoystickY);
// System.err.println(res.toString());
return res;
}
@@ -0,0 +1,11 @@
package com.codeminders.ardrone.controllers.decoders;
import java.io.IOException;
import com.codeminders.ardrone.controllers.GameControllerState;
import com.codeminders.ardrone.controllers.ControllerData;
public interface ControllerStateDecoder {
public GameControllerState decodeState(ControllerData data) throws IOException;
}
@@ -0,0 +1,67 @@
package com.codeminders.ardrone.controllers.decoders;
import java.io.IOException;
import java.util.BitSet;
import com.codeminders.ardrone.controllers.GameControllerState;
import com.codeminders.ardrone.controllers.ControllerData;
public class MotioninJoyVirtualStateDecoder implements ControllerStateDecoder {
public GameControllerState decodeState(ControllerData data) throws IOException {
byte[] buf = data.getBuffer();
BitSet bs = new BitSet(16);
for(int i = 0; i < 8; i++)
{
if((1 & (buf[0] >> i)) == 1)
bs.set(i);
}
for(int i = 0; i < 8; i++)
{
if((1 & (buf[1] >> i)) == 1)
bs.set(8 + i);
}
int i = 0;
boolean triangle = bs.get(i++);
boolean circle = bs.get(i++);
boolean cross = bs.get(i++);
boolean square = bs.get(i++);
boolean L1 = bs.get(i++);
boolean R1 = bs.get(i++);
boolean L2 = bs.get(i++);
boolean R2 = bs.get(i++);
boolean select = bs.get(i++);
boolean leftJoystickPress = bs.get(i++);
boolean rightJoystickPress = bs.get(i++);
boolean start = bs.get(i++);
boolean PS = bs.get(i++);
int leftJoystickX = joystickCoordConv(buf[3]);
int leftJoystickY = joystickCoordConv(buf[4]);
int rightJoystickX = joystickCoordConv(buf[5]);
int rightJoystickY = joystickCoordConv(buf[8]);
// TODO: decode HAT switch
int hatSwitchLeftRight = 0;
int hatSwitchUpDown = 0;
GameControllerState res = new GameControllerState(square, cross, circle, triangle, L1, R1, L2, R2, select, start,
leftJoystickPress, rightJoystickPress, PS, hatSwitchLeftRight, hatSwitchUpDown, leftJoystickX,
leftJoystickY, rightJoystickX, rightJoystickY);
return res;
}
private int joystickCoordConv(byte b)
{
int v = b < 0 ? b + 256 : b;
return(v - 128);
}
}
@@ -1,64 +1,23 @@
package com.codeminders.ardrone.controllers;
package com.codeminders.ardrone.controllers.decoders;
import java.io.IOException;
import java.util.BitSet;
import com.codeminders.hidapi.*;
public class SonyPS3Controller extends PS3Controller
{
private static final int VENDOR_ID = 1356;
private static final int PRODUCT_ID = 616;
private static final int BUFSIZE = 64;
private static final int EXPECTED_BUFSIZE = 32;
private static final int EXPECTED_BUFSIZE_2 = 49;
private byte[] buf = new byte[BUFSIZE];
public static boolean isA(HIDDeviceInfo hidDeviceInfo)
{
return(hidDeviceInfo.getVendor_id() == VENDOR_ID && hidDeviceInfo.getProduct_id() == PRODUCT_ID);
}
public SonyPS3Controller() throws HIDDeviceNotFoundException, IOException
{
dev = HIDManager.getInstance().openById(VENDOR_ID, PRODUCT_ID, null);
if (null != dev) {
dev.enableBlocking();
} else {
throw new HIDDeviceNotFoundException("Device not found");
}
}
public SonyPS3Controller(HIDDeviceInfo hidDeviceInfo) throws IOException
{
dev = hidDeviceInfo.open();
if (null != dev) {
dev.enableBlocking();
} else {
throw new HIDDeviceNotFoundException("Device not found");
}
// dev.close();
}
import com.codeminders.ardrone.controllers.GameControllerState;
import com.codeminders.ardrone.controllers.ControllerData;
public class SonyPS3ControllerStateDecoder implements ControllerStateDecoder {
private int joystickCoordConv(byte b)
{
int v = b < 0 ? b + 256 : b;
return(v - 128);
}
@Override
public PS3ControllerState read() throws IOException
{
int n = dev.read(buf);
if(n != EXPECTED_BUFSIZE && n != EXPECTED_BUFSIZE_2)
{
throw new IOException("Received packed with unexpected size " + n);
}
public GameControllerState decodeState(ControllerData data) throws IOException {
byte[] buf = data.getBuffer();
BitSet bs = new BitSet(24);
for(int i = 0; i < 8; i++)
{
@@ -105,7 +64,7 @@ public class SonyPS3Controller extends PS3Controller
int hatSwitchLeftRight = 0;
int hatSwitchUpDown = 0;
PS3ControllerState res = new PS3ControllerState(square, cross, circle, triangle, L1, R1, L2, R2, select, start,
GameControllerState res = new GameControllerState(square, cross, circle, triangle, L1, R1, L2, R2, select, start,
leftJoystickPress, rightJoystickPress, PS, hatSwitchLeftRight, hatSwitchUpDown, leftJoystickX,
leftJoystickY, rightJoystickX, rightJoystickY);
@@ -7,9 +7,10 @@ import java.io.IOException;
import javax.swing.JFrame;
public class KeyboardController extends PS3Controller implements KeyListener
public class KeyboardController extends Controller implements KeyListener
{
PS3ControllerState state = new PS3ControllerState();
GameControllerState state = new GameControllerState();
public KeyboardController(JFrame frame)
{
@@ -17,12 +18,12 @@ public class KeyboardController extends PS3Controller implements KeyListener
}
@Override
public PS3ControllerState read() throws IOException
public GameControllerState read() throws IOException
{
PS3ControllerState s;
GameControllerState s;
synchronized(state)
{
s = new PS3ControllerState(state);
s = new GameControllerState(state);
}
return s;
}
@@ -100,4 +101,24 @@ public class KeyboardController extends PS3Controller implements KeyListener
{
}
@Override
public void close() throws IOException {
// nothing to do;
}
@Override
public String getName() {
return "Standart KeyboardController";
}
@Override
public String getManufacturerString() {
return "not loading implemented";
}
@Override
public String getProductString() {
return "not loading implemented";
}
}
@@ -1,107 +0,0 @@
package com.codeminders.ardrone.controllers;
import java.io.IOException;
import java.util.BitSet;
import com.codeminders.hidapi.HIDDeviceInfo;
import com.codeminders.hidapi.HIDDeviceNotFoundException;
import com.codeminders.hidapi.HIDManager;
public class MotioninJoyVirtualController extends PS3Controller {
private static final int VENDOR_ID = 34952;
private static final int PRODUCT_ID = 776;
private static final int BUFSIZE = 64;
private static final int EXPECTED_BUFSIZE_3 = 11;
private byte[] buf = new byte[BUFSIZE];
boolean first_passed = false;
public MotioninJoyVirtualController() throws HIDDeviceNotFoundException, IOException {
dev = HIDManager.getInstance().openById(VENDOR_ID, PRODUCT_ID, null);
if (null != dev) {
dev.enableBlocking();
} else {
throw new HIDDeviceNotFoundException("Device not found");
}
}
public MotioninJoyVirtualController(HIDDeviceInfo hidDeviceInfo) throws IOException {
dev = hidDeviceInfo.open();
if (null != dev) {
dev.enableBlocking();
} else {
throw new HIDDeviceNotFoundException("Device not found");
}
}
public static boolean isA(HIDDeviceInfo hidDeviceInfo)
{
return(hidDeviceInfo.getVendor_id() == VENDOR_ID && hidDeviceInfo.getProduct_id() == PRODUCT_ID);
}
@Override
public PS3ControllerState read() throws IOException {
int n = dev.read(buf);
if(n != EXPECTED_BUFSIZE_3)
{
throw new IOException("Received packed with unexpected size " + n);
}
BitSet bs = new BitSet(16);
for(int i = 0; i < 8; i++)
{
if((1 & (buf[0] >> i)) == 1)
bs.set(i);
}
for(int i = 0; i < 8; i++)
{
if((1 & (buf[1] >> i)) == 1)
bs.set(8 + i);
}
int i = 0;
boolean triangle = bs.get(i++);
boolean circle = bs.get(i++);
boolean cross = bs.get(i++);
boolean square = bs.get(i++);
boolean L1 = bs.get(i++);
boolean R1 = bs.get(i++);
boolean L2 = bs.get(i++);
boolean R2 = bs.get(i++);
boolean select = bs.get(i++);
boolean leftJoystickPress = bs.get(i++);
boolean rightJoystickPress = bs.get(i++);
boolean start = bs.get(i++);
boolean PS = bs.get(i++);
int leftJoystickX = joystickCoordConv(buf[3]);
int leftJoystickY = joystickCoordConv(buf[4]);
int rightJoystickX = joystickCoordConv(buf[5]);
int rightJoystickY = joystickCoordConv(buf[8]);
// TODO: decode HAT switch
int hatSwitchLeftRight = 0;
int hatSwitchUpDown = 0;
PS3ControllerState res = new PS3ControllerState(square, cross, circle, triangle, L1, R1, L2, R2, select, start,
leftJoystickPress, rightJoystickPress, PS, hatSwitchLeftRight, hatSwitchUpDown, leftJoystickX,
leftJoystickY, rightJoystickX, rightJoystickY);
return res;
}
private int joystickCoordConv(byte b)
{
int v = b < 0 ? b + 256 : b;
return(v - 128);
}
}
@@ -1,63 +0,0 @@
package com.codeminders.ardrone.controllers;
import java.io.IOException;
import com.codeminders.hidapi.HIDDevice;
/**
* Base abstract class for supported PS3-compatible USB controllers
*
* @author lord
*
*/
public abstract class PS3Controller
{
protected HIDDevice dev;
protected static void printDelta(byte[] prev, int prev_size, byte[] cur, int cur_size)
{
if(prev_size != cur_size)
{
System.err.println("Packet size is different. Prev: " + prev_size + " New: " + cur_size);
return;
}
for(int i = 0; i < prev_size; i++)
{
if(prev[i] != cur[i])
{
System.err.println("Index: " + i + " Prev value: " + Integer.toHexString((int) prev[i])
+ " New value: " + Integer.toHexString((int) cur[i]));
}
}
}
public void close() throws IOException
{
if(dev != null)
dev.close();
}
public abstract PS3ControllerState read() throws IOException;
@Override
public String toString()
{
StringBuilder builder = new StringBuilder();
builder.append("PS3Controller [");
try
{
builder.append("manufacturer=");
builder.append(dev.getManufacturerString());
builder.append(", product=");
builder.append(dev.getProductString());
} catch(IOException e)
{
builder.append("<invalid>");
}
builder.append("]");
return builder.toString();
}
}
@@ -0,0 +1,50 @@
package com.codeminders.ardrone.controllers.hid;
import java.io.IOException;
import com.codeminders.ardrone.controllers.ControllerData;
import com.codeminders.ardrone.controllers.decoders.AfterGlowControllerDecoder;
import com.codeminders.ardrone.controllers.decoders.ControllerStateDecoder;
import com.codeminders.hidapi.HIDDeviceInfo;
import com.codeminders.hidapi.HIDDeviceNotFoundException;
public class HIDAPIAfterGlowController extends HIDAPIController {
private static final int VENDOR_ID = 3695;
private static final int PRODUCT_ID = 25346;
private static final int BUFSIZE = 32;
private static final int EXPECTED_BUFSIZE = 27;
private static ControllerStateDecoder decoder = new AfterGlowControllerDecoder();
public HIDAPIAfterGlowController() throws HIDDeviceNotFoundException, IOException
{
super(VENDOR_ID, PRODUCT_ID, decoder, BUFSIZE);
}
public HIDAPIAfterGlowController(HIDDeviceInfo hidDeviceInfo) throws IOException
{
super(decoder, BUFSIZE, hidDeviceInfo);
}
@Override
public String getName() {
return "HID API connected AfterGlowController";
}
@Override
public boolean isValid(ControllerData data) throws IOException {
if(data.getActualBufferDataLength() != EXPECTED_BUFSIZE)
{
throw new IOException("Received packed with unexpected size " + data.getActualBufferDataLength());
}
return true;
}
public static boolean isA(HIDDeviceInfo hidDeviceInfo) {
return VENDOR_ID == hidDeviceInfo.getVendor_id() && PRODUCT_ID == hidDeviceInfo.getProduct_id();
}
}
@@ -0,0 +1,88 @@
package com.codeminders.ardrone.controllers.hid;
import java.io.IOException;
import com.codeminders.ardrone.controllers.Controller;
import com.codeminders.ardrone.controllers.ControllerData;
import com.codeminders.ardrone.controllers.GameControllerState;
import com.codeminders.ardrone.controllers.decoders.ControllerStateDecoder;
import com.codeminders.hidapi.HIDDevice;
import com.codeminders.hidapi.HIDDeviceInfo;
import com.codeminders.hidapi.HIDDeviceNotFoundException;
import com.codeminders.hidapi.HIDManager;
public abstract class HIDAPIController extends Controller {
private byte[] buf;
HIDDevice dev;
ControllerStateDecoder decoder;
public HIDAPIController(int vid, int pid, ControllerStateDecoder decoder, int readBufferSize) throws HIDDeviceNotFoundException, IOException {
this.decoder = decoder;
buf = new byte[readBufferSize];
dev = HIDManager.getInstance().openById(vid, vid, null);
if (null != dev) {
dev.enableBlocking();
} else {
throw new HIDDeviceNotFoundException("Device not found");
}
}
public abstract boolean isValid(ControllerData data) throws IOException;
public HIDAPIController(ControllerStateDecoder decodder, int readBufferSize, HIDDeviceInfo hidDeviceInfo) throws IOException {
this.decoder = decodder;
buf = new byte[readBufferSize];
dev = hidDeviceInfo.open();
if (null != dev) {
dev.enableBlocking();
} else {
throw new HIDDeviceNotFoundException("Device not found");
}
}
public GameControllerState read() throws IOException {
ControllerData data = readDataFromDevice();
if (isValid(data)) {
return decoder.decodeState(data);
} else {
return null;
}
}
@Override
public synchronized void close() throws IOException {
if (dev != null) {
dev.close();
}
}
@Override
public String getManufacturerString() {
try {
return (dev != null)? dev.getManufacturerString() : "device not avalible";
} catch (IOException e) {
return "device not avalible";
}
}
@Override
public String getProductString() {
try {
return (dev != null)? dev.getProductString() : "device not avalible";
} catch (IOException e) {
return "device not avalible";
}
}
private synchronized ControllerData readDataFromDevice() throws IOException {
int n = dev.read(buf);
return new ControllerData(buf, n);
}
}
@@ -0,0 +1,48 @@
package com.codeminders.ardrone.controllers.hid;
import java.io.IOException;
import com.codeminders.ardrone.controllers.ControllerData;
import com.codeminders.ardrone.controllers.decoders.ControllerStateDecoder;
import com.codeminders.hidapi.HIDDeviceInfo;
import com.codeminders.hidapi.HIDDeviceNotFoundException;
public class HIDAPIMotioninJoyVirtualController extends HIDAPIController {
private static final int VENDOR_ID = 34952;
private static final int PRODUCT_ID = 776;
private static final int BUFSIZE = 64;
private static final int EXPECTED_BUFSIZE = 11;
private static ControllerStateDecoder decoder;
public HIDAPIMotioninJoyVirtualController() throws HIDDeviceNotFoundException, IOException
{
super(VENDOR_ID, PRODUCT_ID, decoder, BUFSIZE);
}
public HIDAPIMotioninJoyVirtualController(HIDDeviceInfo hidDeviceInfo) throws IOException
{
super(decoder, BUFSIZE, hidDeviceInfo);
}
@Override
public String getName() {
return "HID API MotioninJoy VirtualController for PS3";
}
@Override
public boolean isValid(ControllerData data) throws IOException {
if(data.getActualBufferDataLength() != EXPECTED_BUFSIZE)
{
throw new IOException("Received packed with unexpected size " + data.getActualBufferDataLength());
}
return true;
}
public static boolean isA(HIDDeviceInfo hidDeviceInfo) {
return VENDOR_ID == hidDeviceInfo.getVendor_id() && PRODUCT_ID == hidDeviceInfo.getProduct_id();
}
}
@@ -0,0 +1,49 @@
package com.codeminders.ardrone.controllers.hid;
import java.io.IOException;
import com.codeminders.ardrone.controllers.ControllerData;
import com.codeminders.ardrone.controllers.decoders.SonyPS3ControllerStateDecoder;
import com.codeminders.hidapi.HIDDeviceInfo;
import com.codeminders.hidapi.HIDDeviceNotFoundException;
public class HIDAPISonyPS3Controller extends HIDAPIController
{
private static final int VENDOR_ID = 1356;
private static final int PRODUCT_ID = 616;
private static final int BUFSIZE = 64;
private static final int EXPECTED_BUFSIZE = 32;
private static final int EXPECTED_BUFSIZE_2 = 49;
static final SonyPS3ControllerStateDecoder decoder = new SonyPS3ControllerStateDecoder();
public HIDAPISonyPS3Controller() throws HIDDeviceNotFoundException, IOException
{
super(VENDOR_ID, PRODUCT_ID, decoder, BUFSIZE);
}
public HIDAPISonyPS3Controller(HIDDeviceInfo hidDeviceInfo) throws IOException
{
super(decoder, BUFSIZE, hidDeviceInfo);
}
@Override
public String getName() {
return "HID API connected SonyPS3Controller";
}
@Override
public boolean isValid(ControllerData data) throws IOException {
if(data.getActualBufferDataLength() != EXPECTED_BUFSIZE && data.getActualBufferDataLength() != EXPECTED_BUFSIZE_2)
{
throw new IOException("Received packed with unexpected size " + data.getActualBufferDataLength());
}
return true;
}
public static boolean isA(HIDDeviceInfo hidDeviceInfo) {
return VENDOR_ID == hidDeviceInfo.getVendor_id() && PRODUCT_ID == hidDeviceInfo.getProduct_id();
}
}
@@ -4,9 +4,8 @@ package com.codeminders.ardrone.tools;
import java.io.IOException;
import com.codeminders.ardrone.controllers.*;
import com.codeminders.ardrone.controllers.hid.manager.HIDControllerFinder;
import com.codeminders.hidapi.ClassPathLibraryLoader;
import com.codeminders.hidapi.HIDDeviceInfo;
import com.codeminders.hidapi.HIDManager;
public class ControllerTest
{
@@ -24,7 +23,7 @@ public class ControllerTest
{
try
{
PS3Controller c = findController();
Controller c = findController();
if(c == null)
{
System.err.println("Controller not found");
@@ -38,7 +37,7 @@ public class ControllerTest
while(true)
{
PS3ControllerState x = c.read();
GameControllerState x = c.read();
System.err.println(x);
try
{
@@ -59,20 +58,9 @@ public class ControllerTest
}
private static PS3Controller findController() throws IOException
private static Controller findController() throws IOException
{
HIDDeviceInfo[] devs = HIDManager.getInstance().listDevices();
if (null != devs) {
for(int i = 0; i < devs.length; i++)
{
if(AfterGlowController.isA(devs[i]))
return new AfterGlowController(devs[i]);
if(SonyPS3Controller.isA(devs[i]))
return new SonyPS3Controller(devs[i]);
}
}
return null;
return HIDControllerFinder.findController();
}
}