Merge branch 'develop'

This commit is contained in:
2014-04-04 10:27:33 -04:30
5 changed files with 160 additions and 20 deletions

4
README.md Normal file
View File

@@ -0,0 +1,4 @@
NxtAR-core
==========
Modulo 2 de mi trabajo especial de grado.

View File

@@ -5,7 +5,7 @@ import java.io.Serializable;
public class MotorEvent implements Serializable{ public class MotorEvent implements Serializable{
private static final long serialVersionUID = 9989L; private static final long serialVersionUID = 9989L;
public enum motor_t {NONE, MOTOR_A, MOTOR_B, MOTOR_C, MOTOR_AC}; public enum motor_t {NONE, MOTOR_A, MOTOR_B, MOTOR_C, MOTOR_AC, RECENTER};
private motor_t motor; private motor_t motor;
private byte power; private byte power;

View File

@@ -20,6 +20,7 @@ import ve.ucv.ciens.ccg.nxtar.interfaces.MulticastEnabler;
import ve.ucv.ciens.ccg.nxtar.interfaces.NetworkConnectionListener; import ve.ucv.ciens.ccg.nxtar.interfaces.NetworkConnectionListener;
import ve.ucv.ciens.ccg.nxtar.interfaces.Toaster; import ve.ucv.ciens.ccg.nxtar.interfaces.Toaster;
import ve.ucv.ciens.ccg.nxtar.network.RobotControlThread; import ve.ucv.ciens.ccg.nxtar.network.RobotControlThread;
import ve.ucv.ciens.ccg.nxtar.network.SensorReportThread;
import ve.ucv.ciens.ccg.nxtar.network.ServiceDiscoveryThread; import ve.ucv.ciens.ccg.nxtar.network.ServiceDiscoveryThread;
import ve.ucv.ciens.ccg.nxtar.network.VideoStreamingThread; import ve.ucv.ciens.ccg.nxtar.network.VideoStreamingThread;
import ve.ucv.ciens.ccg.nxtar.states.BaseState; import ve.ucv.ciens.ccg.nxtar.states.BaseState;
@@ -76,10 +77,12 @@ public class NxtARCore extends Game implements NetworkConnectionListener{
return this.value; return this.value;
} }
}; };
/** /**
* The current application state. * The current application state.
*/ */
private game_states_t currState; private game_states_t currState;
/** /**
* <p>The state to change to.</p> * <p>The state to change to.</p>
* <p> Usually null. A state change is scheduled by setting this field to a {@link game_states_t} value.</p> * <p> Usually null. A state change is scheduled by setting this field to a {@link game_states_t} value.</p>
@@ -100,6 +103,7 @@ public class NxtARCore extends Game implements NetworkConnectionListener{
private ServiceDiscoveryThread serviceDiscoveryThread; private ServiceDiscoveryThread serviceDiscoveryThread;
private VideoStreamingThread videoThread; private VideoStreamingThread videoThread;
private RobotControlThread robotThread; private RobotControlThread robotThread;
private SensorReportThread sensorThread;
// Overlays. // Overlays.
private OrthographicCamera pixelPerfectCamera; private OrthographicCamera pixelPerfectCamera;
@@ -144,8 +148,10 @@ public class NxtARCore extends Game implements NetworkConnectionListener{
public void create(){ public void create(){
// Create the state objects. // Create the state objects.
states = new BaseState[3]; states = new BaseState[3];
if(Ouya.runningOnOuya)states[game_states_t.MAIN_MENU.getValue()] = new OuyaMainMenuState(this); if(Ouya.runningOnOuya)
else states[game_states_t.MAIN_MENU.getValue()] = new TabletMainMenuState(this); states[game_states_t.MAIN_MENU.getValue()] = new OuyaMainMenuState(this);
else
states[game_states_t.MAIN_MENU.getValue()] = new TabletMainMenuState(this);
states[game_states_t.IN_GAME.getValue()] = new InGameState(this); states[game_states_t.IN_GAME.getValue()] = new InGameState(this);
states[game_states_t.PAUSED.getValue()] = new PauseState(this); states[game_states_t.PAUSED.getValue()] = new PauseState(this);
@@ -179,6 +185,7 @@ public class NxtARCore extends Game implements NetworkConnectionListener{
serviceDiscoveryThread = ServiceDiscoveryThread.getInstance(); serviceDiscoveryThread = ServiceDiscoveryThread.getInstance();
videoThread = VideoStreamingThread.getInstance(); videoThread = VideoStreamingThread.getInstance();
robotThread = RobotControlThread.getInstance(); robotThread = RobotControlThread.getInstance();
sensorThread = SensorReportThread.getInstance();
serviceDiscoveryThread.start(); serviceDiscoveryThread.start();
@@ -189,6 +196,9 @@ public class NxtARCore extends Game implements NetworkConnectionListener{
robotThread.addNetworkConnectionListener(this); robotThread.addNetworkConnectionListener(this);
robotThread.start(); robotThread.start();
sensorThread.addNetworkConnectionListener(this);
sensorThread.start();
// Set the current and next states. // Set the current and next states.
currState = game_states_t.MAIN_MENU; currState = game_states_t.MAIN_MENU;
nextState = null; nextState = null;
@@ -275,6 +285,7 @@ public class NxtARCore extends Game implements NetworkConnectionListener{
font.draw(batch, String.format("Render FPS: %d", Gdx.graphics.getFramesPerSecond()), fontX, fontY); font.draw(batch, String.format("Render FPS: %d", Gdx.graphics.getFramesPerSecond()), fontX, fontY);
font.draw(batch, String.format("Total stream FPS: %d", videoThread.getFps()), fontX, fontY - font.getCapHeight() - 5); font.draw(batch, String.format("Total stream FPS: %d", videoThread.getFps()), fontX, fontY - font.getCapHeight() - 5);
font.draw(batch, String.format("Lost stream FPS: %d", videoThread.getLostFrames()), fontX, fontY - (2 * font.getCapHeight()) - 10); font.draw(batch, String.format("Lost stream FPS: %d", videoThread.getLostFrames()), fontX, fontY - (2 * font.getCapHeight()) - 10);
font.draw(batch, String.format("Light sensor data: %d", sensorThread.getLightSensorReading()), fontX, fontY - (3 * font.getCapHeight()) - 15);
}batch.end(); }batch.end();
} }
} }
@@ -309,10 +320,10 @@ public class NxtARCore extends Game implements NetworkConnectionListener{
@Override @Override
public synchronized void networkStreamConnected(String streamName){ public synchronized void networkStreamConnected(String streamName){
//if(streamName.equals(VideoStreamingThread.THREAD_NAME) || streamName.equals(RobotControlThread.THREAD_NAME))
Gdx.app.log(TAG, CLASS_NAME + ".networkStreamConnected() :: Stream " + streamName + " connected."); Gdx.app.log(TAG, CLASS_NAME + ".networkStreamConnected() :: Stream " + streamName + " connected.");
connections += 1; connections += 1;
if(connections >= 2){
if(connections >= 3){
Gdx.app.debug(TAG, CLASS_NAME + ".networkStreamConnected() :: Stopping service broadcast."); Gdx.app.debug(TAG, CLASS_NAME + ".networkStreamConnected() :: Stopping service broadcast.");
serviceDiscoveryThread.finish(); serviceDiscoveryThread.finish();
mcastEnabler.disableMulticast(); mcastEnabler.disableMulticast();

View File

@@ -15,10 +15,44 @@
*/ */
package ve.ucv.ciens.ccg.nxtar.network; package ve.ucv.ciens.ccg.nxtar.network;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import ve.ucv.ciens.ccg.nxtar.interfaces.NetworkConnectionListener;
import ve.ucv.ciens.ccg.nxtar.utils.ProjectConstants;
import com.badlogic.gdx.Gdx;
public class SensorReportThread extends Thread { public class SensorReportThread extends Thread {
public static final String THREAD_NAME = "SensorReportThread";
private static final String TAG = "NXTAR_CORE_ROBOTTHREAD";
private static final String CLASS_NAME = SensorReportThread.class.getSimpleName();
private NetworkConnectionListener netListener;
private ServerSocket server;
private Socket client;
private Object pauseMonitor;
private boolean paused;
private boolean done;
private InputStream reader;
private Byte lightReading;
private SensorReportThread(){ private SensorReportThread(){
paused = false;
done = false;
netListener = null;
pauseMonitor = null;
client = null;
lightReading = -1;
try{
server = new ServerSocket(ProjectConstants.SENSOR_REPORT_PORT);
}catch(IOException io){
Gdx.app.error(TAG, CLASS_NAME + ".RobotControlThread() :: Error creating server: " + io.getMessage(), io);
server = null;
}
} }
private static class SingletonHolder{ private static class SingletonHolder{
@@ -29,8 +63,64 @@ public class SensorReportThread extends Thread {
return SingletonHolder.INSTANCE; return SingletonHolder.INSTANCE;
} }
public void addNetworkConnectionListener(NetworkConnectionListener listener){
netListener = listener;
}
public void pauseThread(){
synchronized(pauseMonitor){
paused = true;
}
}
public void resumeThread(){
synchronized(pauseMonitor){
paused = false;
}
}
public void finish(){
done = true;
}
public byte getLightSensorReading(){
byte data;
synchronized(lightReading){
data = lightReading.byteValue();
}
return data;
}
@Override @Override
public void run(){ public void run(){
byte[] reading = new byte[1];
try{
client = server.accept();
client.setTcpNoDelay(true);
if(netListener != null) netListener.networkStreamConnected(THREAD_NAME);
reader = client.getInputStream();
}catch(IOException io){
Gdx.app.error(TAG, CLASS_NAME + ".run() :: Error accepting client: " + io.getMessage(), io);
return;
}
while(!paused){
if(done) break;
try{
reader.read(reading);
}catch(IOException io){
Gdx.app.error(TAG, CLASS_NAME + ".run() :: IOException during sensor read: " + io.getMessage(), io);
break;
}
synchronized (lightReading) {
lightReading = reading[0];
}
}
} }
} }

View File

@@ -75,6 +75,7 @@ public class InGameState extends BaseState{
private Sprite motorD; private Sprite motorD;
private Sprite headA; private Sprite headA;
private Sprite headB; private Sprite headB;
private Sprite headC;
// Button touch helper fields. // Button touch helper fields.
private Vector3 win2world; private Vector3 win2world;
@@ -82,7 +83,6 @@ public class InGameState extends BaseState{
private boolean[] motorButtonsTouched; private boolean[] motorButtonsTouched;
private int[] motorButtonsPointers; private int[] motorButtonsPointers;
private boolean[] motorGamepadButtonPressed; private boolean[] motorGamepadButtonPressed;
private boolean[] axisStopSent;
// Monitors. // Monitors.
private VideoFrameMonitor frameMonitor; private VideoFrameMonitor frameMonitor;
@@ -106,35 +106,32 @@ public class InGameState extends BaseState{
win2world = new Vector3(0.0f, 0.0f, 0.0f); win2world = new Vector3(0.0f, 0.0f, 0.0f);
touchPointWorldCoords = new Vector2(); touchPointWorldCoords = new Vector2();
motorButtonsTouched = new boolean[6]; motorButtonsTouched = new boolean[7];
motorButtonsTouched[0] = false; motorButtonsTouched[0] = false;
motorButtonsTouched[1] = false; motorButtonsTouched[1] = false;
motorButtonsTouched[2] = false; motorButtonsTouched[2] = false;
motorButtonsTouched[3] = false; motorButtonsTouched[3] = false;
motorButtonsTouched[4] = false; motorButtonsTouched[4] = false;
motorButtonsTouched[5] = false; motorButtonsTouched[5] = false;
motorButtonsTouched[6] = false;
motorButtonsPointers = new int[6]; motorButtonsPointers = new int[7];
motorButtonsPointers[0] = -1; motorButtonsPointers[0] = -1;
motorButtonsPointers[1] = -1; motorButtonsPointers[1] = -1;
motorButtonsPointers[2] = -1; motorButtonsPointers[2] = -1;
motorButtonsPointers[3] = -1; motorButtonsPointers[3] = -1;
motorButtonsPointers[4] = -1; motorButtonsPointers[4] = -1;
motorButtonsPointers[5] = -1; motorButtonsPointers[5] = -1;
motorButtonsPointers[6] = -1;
motorGamepadButtonPressed = new boolean[6]; motorGamepadButtonPressed = new boolean[7];
motorGamepadButtonPressed[0] = false; motorGamepadButtonPressed[0] = false;
motorGamepadButtonPressed[1] = false; motorGamepadButtonPressed[1] = false;
motorGamepadButtonPressed[2] = false; motorGamepadButtonPressed[2] = false;
motorGamepadButtonPressed[3] = false; motorGamepadButtonPressed[3] = false;
motorGamepadButtonPressed[4] = false; motorGamepadButtonPressed[4] = false;
motorGamepadButtonPressed[5] = false; motorGamepadButtonPressed[5] = false;
motorGamepadButtonPressed[6] = false;
axisStopSent = new boolean[4];
axisStopSent[0] = true;
axisStopSent[1] = true;
axisStopSent[2] = true;
axisStopSent[3] = true;
backgroundTexture = new Texture(Gdx.files.internal("data/gfx/textures/tile_aqua.png")); backgroundTexture = new Texture(Gdx.files.internal("data/gfx/textures/tile_aqua.png"));
backgroundTexture.setWrap(TextureWrap.Repeat, TextureWrap.Repeat); backgroundTexture.setWrap(TextureWrap.Repeat, TextureWrap.Repeat);
@@ -231,6 +228,7 @@ public class InGameState extends BaseState{
motorD.draw(core.batch); motorD.draw(core.batch);
headA.draw(core.batch); headA.draw(core.batch);
headB.draw(core.batch); headB.draw(core.batch);
headC.draw(core.batch);
} }
}core.batch.end(); }core.batch.end();
@@ -320,6 +318,10 @@ public class InGameState extends BaseState{
headA.setPosition(-headA.getWidth() - 10, motorA.getY() + (headA.getHeight() / 2)); headA.setPosition(-headA.getWidth() - 10, motorA.getY() + (headA.getHeight() / 2));
headB.setPosition(10, motorA.getY() + (headA.getHeight() / 2)); headB.setPosition(10, motorA.getY() + (headA.getHeight() / 2));
headC = new Sprite(buttonTexture2);
headC.setSize(headC.getWidth() * 0.3f, headC.getHeight() * 0.6f);
headC.setPosition(-(headC.getWidth() / 2), headA.getY() - headA.getHeight() - 10);
} }
/*;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; /*;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -352,7 +354,6 @@ public class InGameState extends BaseState{
}else if(motorB.getBoundingRectangle().contains(touchPointWorldCoords)){ }else if(motorB.getBoundingRectangle().contains(touchPointWorldCoords)){
Gdx.app.log(TAG, CLASS_NAME + ".touchDown() :: Motor B button pressed"); Gdx.app.log(TAG, CLASS_NAME + ".touchDown() :: Motor B button pressed");
motorButtonsTouched[1] = true; motorButtonsTouched[1] = true;
motorButtonsPointers[1] = pointer; motorButtonsPointers[1] = pointer;
@@ -405,6 +406,18 @@ public class InGameState extends BaseState{
event.setPower((byte)40); event.setPower((byte)40);
queue.addEvent(event); queue.addEvent(event);
}else if(headC.getBoundingRectangle().contains(touchPointWorldCoords)){
Gdx.app.log(TAG, CLASS_NAME + ".touchDown() :: Head C button pressed");
if(!motorButtonsTouched[4] && !motorButtonsTouched[5]){
motorButtonsTouched[6] = true;
motorButtonsPointers[6] = pointer;
event = new MotorEvent();
event.setMotor(motor_t.RECENTER);
event.setPower((byte)0x00);
queue.addEvent(event);
}
} }
} }
return true; return true;
@@ -506,6 +519,11 @@ public class InGameState extends BaseState{
queue.addEvent(event); queue.addEvent(event);
} }
}else if(headC.getBoundingRectangle().contains(touchPointWorldCoords)){
Gdx.app.log(TAG, CLASS_NAME + ".touchUp() :: Head C button released");
motorButtonsPointers[6] = -1;
motorButtonsTouched[6] = false;
} }
} }
return true; return true;
@@ -576,8 +594,8 @@ public class InGameState extends BaseState{
queue.addEvent(event); queue.addEvent(event);
} }
}else if(pointer == motorButtonsPointers[4] && headA.getBoundingRectangle().contains(touchPointWorldCoords)){ }else if(pointer == motorButtonsPointers[4] && !headA.getBoundingRectangle().contains(touchPointWorldCoords)){
Gdx.app.log(TAG, CLASS_NAME + ".touchUp() :: Head A button released"); Gdx.app.log(TAG, CLASS_NAME + ".touchDragged() :: Head A button released");
motorButtonsPointers[4] = -1; motorButtonsPointers[4] = -1;
motorButtonsTouched[4] = false; motorButtonsTouched[4] = false;
@@ -590,8 +608,8 @@ public class InGameState extends BaseState{
queue.addEvent(event); queue.addEvent(event);
} }
}else if(pointer == motorButtonsPointers[5] && headB.getBoundingRectangle().contains(touchPointWorldCoords)){ }else if(pointer == motorButtonsPointers[5] && !headB.getBoundingRectangle().contains(touchPointWorldCoords)){
Gdx.app.log(TAG, CLASS_NAME + ".touchUp() :: Head B button released"); Gdx.app.log(TAG, CLASS_NAME + ".touchDragged() :: Head B button released");
motorButtonsPointers[5] = -1; motorButtonsPointers[5] = -1;
motorButtonsTouched[5] = false; motorButtonsTouched[5] = false;
@@ -604,6 +622,11 @@ public class InGameState extends BaseState{
queue.addEvent(event); queue.addEvent(event);
} }
}else if(pointer == motorButtonsPointers[6] && !headC.getBoundingRectangle().contains(touchPointWorldCoords)){
Gdx.app.log(TAG, CLASS_NAME + ".touchDragged() :: Head C button released");
motorButtonsPointers[6] = -1;
motorButtonsTouched[6] = false;
} }
} }
return true; return true;
@@ -659,6 +682,7 @@ public class InGameState extends BaseState{
event.setPower((byte)-40); event.setPower((byte)-40);
queue.addEvent(event); queue.addEvent(event);
} }
}else if(buttonCode == Ouya.BUTTON_DPAD_RIGHT){ }else if(buttonCode == Ouya.BUTTON_DPAD_RIGHT){
motorGamepadButtonPressed[3] = false; motorGamepadButtonPressed[3] = false;
@@ -668,6 +692,7 @@ public class InGameState extends BaseState{
event.setPower((byte)40); event.setPower((byte)40);
queue.addEvent(event); queue.addEvent(event);
} }
}else if(buttonCode == Ouya.BUTTON_L2){ }else if(buttonCode == Ouya.BUTTON_L2){
motorGamepadButtonPressed[4] = false; motorGamepadButtonPressed[4] = false;
@@ -688,6 +713,13 @@ public class InGameState extends BaseState{
queue.addEvent(event); queue.addEvent(event);
} }
}else if(buttonCode == Ouya.BUTTON_Y){
motorGamepadButtonPressed[6] = true;
event = new MotorEvent();
event.setMotor(motor_t.RECENTER);
event.setPower((byte)0x00);
queue.addEvent(event);
} }
return true; return true;
@@ -760,6 +792,9 @@ public class InGameState extends BaseState{
event.setPower((byte)0); event.setPower((byte)0);
queue.addEvent(event); queue.addEvent(event);
} }
}else if(buttonCode == Ouya.BUTTON_Y){
motorGamepadButtonPressed[6] = false;
} }
return true; return true;