From ebb943925fdbf55983fc4a9b401e02bc4fc476e2 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 31 Mar 2014 11:02:20 -0430 Subject: [PATCH 1/3] Renamed the project. --- README.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..1d5ec59 --- /dev/null +++ b/README.md @@ -0,0 +1,4 @@ +NxtAR-core +========== + +Modulo 2 de mi trabajo especial de grado. From a37ff0fba5c0bddd021ef328b61922ce291f8817 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 3 Apr 2014 11:28:30 -0430 Subject: [PATCH 2/3] Added a sensor data receiving thread. --- src/ve/ucv/ciens/ccg/nxtar/NxtARCore.java | 19 +++- .../ccg/nxtar/network/SensorReportThread.java | 90 +++++++++++++++++++ 2 files changed, 105 insertions(+), 4 deletions(-) diff --git a/src/ve/ucv/ciens/ccg/nxtar/NxtARCore.java b/src/ve/ucv/ciens/ccg/nxtar/NxtARCore.java index a42e495..429d5d1 100644 --- a/src/ve/ucv/ciens/ccg/nxtar/NxtARCore.java +++ b/src/ve/ucv/ciens/ccg/nxtar/NxtARCore.java @@ -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.Toaster; 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.VideoStreamingThread; import ve.ucv.ciens.ccg.nxtar.states.BaseState; @@ -76,10 +77,12 @@ public class NxtARCore extends Game implements NetworkConnectionListener{ return this.value; } }; + /** * The current application state. */ private game_states_t currState; + /** *

The state to change to.

*

Usually null. A state change is scheduled by setting this field to a {@link game_states_t} value.

@@ -100,6 +103,7 @@ public class NxtARCore extends Game implements NetworkConnectionListener{ private ServiceDiscoveryThread serviceDiscoveryThread; private VideoStreamingThread videoThread; private RobotControlThread robotThread; + private SensorReportThread sensorThread; // Overlays. private OrthographicCamera pixelPerfectCamera; @@ -144,8 +148,10 @@ public class NxtARCore extends Game implements NetworkConnectionListener{ public void create(){ // Create the state objects. states = new BaseState[3]; - if(Ouya.runningOnOuya)states[game_states_t.MAIN_MENU.getValue()] = new OuyaMainMenuState(this); - else states[game_states_t.MAIN_MENU.getValue()] = new TabletMainMenuState(this); + if(Ouya.runningOnOuya) + 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.PAUSED.getValue()] = new PauseState(this); @@ -179,6 +185,7 @@ public class NxtARCore extends Game implements NetworkConnectionListener{ serviceDiscoveryThread = ServiceDiscoveryThread.getInstance(); videoThread = VideoStreamingThread.getInstance(); robotThread = RobotControlThread.getInstance(); + sensorThread = SensorReportThread.getInstance(); serviceDiscoveryThread.start(); @@ -189,6 +196,9 @@ public class NxtARCore extends Game implements NetworkConnectionListener{ robotThread.addNetworkConnectionListener(this); robotThread.start(); + sensorThread.addNetworkConnectionListener(this); + sensorThread.start(); + // Set the current and next states. currState = game_states_t.MAIN_MENU; 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("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("Light sensor data: %d", sensorThread.getLightSensorReading()), fontX, fontY - (3 * font.getCapHeight()) - 15); }batch.end(); } } @@ -309,10 +320,10 @@ public class NxtARCore extends Game implements NetworkConnectionListener{ @Override 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."); connections += 1; - if(connections >= 2){ + + if(connections >= 3){ Gdx.app.debug(TAG, CLASS_NAME + ".networkStreamConnected() :: Stopping service broadcast."); serviceDiscoveryThread.finish(); mcastEnabler.disableMulticast(); diff --git a/src/ve/ucv/ciens/ccg/nxtar/network/SensorReportThread.java b/src/ve/ucv/ciens/ccg/nxtar/network/SensorReportThread.java index d6d935e..a30ff01 100644 --- a/src/ve/ucv/ciens/ccg/nxtar/network/SensorReportThread.java +++ b/src/ve/ucv/ciens/ccg/nxtar/network/SensorReportThread.java @@ -15,10 +15,44 @@ */ 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 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(){ + 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{ @@ -29,8 +63,64 @@ public class SensorReportThread extends Thread { 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 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]; + } + } } } From 1e2de5ee55fe9958c705411c7a16d4dd1807f0d9 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 4 Apr 2014 10:26:56 -0430 Subject: [PATCH 3/3] Added recenter button and corresponding event handling. --- .../ucv/ciens/ccg/networkdata/MotorEvent.java | 2 +- .../ciens/ccg/nxtar/states/InGameState.java | 65 ++++++++++++++----- 2 files changed, 51 insertions(+), 16 deletions(-) diff --git a/src/ve/ucv/ciens/ccg/networkdata/MotorEvent.java b/src/ve/ucv/ciens/ccg/networkdata/MotorEvent.java index 5cdcfc9..50f1c60 100644 --- a/src/ve/ucv/ciens/ccg/networkdata/MotorEvent.java +++ b/src/ve/ucv/ciens/ccg/networkdata/MotorEvent.java @@ -5,7 +5,7 @@ import java.io.Serializable; public class MotorEvent implements Serializable{ 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 byte power; diff --git a/src/ve/ucv/ciens/ccg/nxtar/states/InGameState.java b/src/ve/ucv/ciens/ccg/nxtar/states/InGameState.java index c09a615..e8d2c38 100644 --- a/src/ve/ucv/ciens/ccg/nxtar/states/InGameState.java +++ b/src/ve/ucv/ciens/ccg/nxtar/states/InGameState.java @@ -75,6 +75,7 @@ public class InGameState extends BaseState{ private Sprite motorD; private Sprite headA; private Sprite headB; + private Sprite headC; // Button touch helper fields. private Vector3 win2world; @@ -82,7 +83,6 @@ public class InGameState extends BaseState{ private boolean[] motorButtonsTouched; private int[] motorButtonsPointers; private boolean[] motorGamepadButtonPressed; - private boolean[] axisStopSent; // Monitors. private VideoFrameMonitor frameMonitor; @@ -106,35 +106,32 @@ public class InGameState extends BaseState{ win2world = new Vector3(0.0f, 0.0f, 0.0f); touchPointWorldCoords = new Vector2(); - motorButtonsTouched = new boolean[6]; + motorButtonsTouched = new boolean[7]; motorButtonsTouched[0] = false; motorButtonsTouched[1] = false; motorButtonsTouched[2] = false; motorButtonsTouched[3] = false; motorButtonsTouched[4] = false; motorButtonsTouched[5] = false; + motorButtonsTouched[6] = false; - motorButtonsPointers = new int[6]; + motorButtonsPointers = new int[7]; motorButtonsPointers[0] = -1; motorButtonsPointers[1] = -1; motorButtonsPointers[2] = -1; motorButtonsPointers[3] = -1; motorButtonsPointers[4] = -1; motorButtonsPointers[5] = -1; + motorButtonsPointers[6] = -1; - motorGamepadButtonPressed = new boolean[6]; + motorGamepadButtonPressed = new boolean[7]; motorGamepadButtonPressed[0] = false; motorGamepadButtonPressed[1] = false; motorGamepadButtonPressed[2] = false; motorGamepadButtonPressed[3] = false; motorGamepadButtonPressed[4] = false; motorGamepadButtonPressed[5] = false; - - axisStopSent = new boolean[4]; - axisStopSent[0] = true; - axisStopSent[1] = true; - axisStopSent[2] = true; - axisStopSent[3] = true; + motorGamepadButtonPressed[6] = false; backgroundTexture = new Texture(Gdx.files.internal("data/gfx/textures/tile_aqua.png")); backgroundTexture.setWrap(TextureWrap.Repeat, TextureWrap.Repeat); @@ -231,6 +228,7 @@ public class InGameState extends BaseState{ motorD.draw(core.batch); headA.draw(core.batch); headB.draw(core.batch); + headC.draw(core.batch); } }core.batch.end(); @@ -320,6 +318,10 @@ public class InGameState extends BaseState{ headA.setPosition(-headA.getWidth() - 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)){ Gdx.app.log(TAG, CLASS_NAME + ".touchDown() :: Motor B button pressed"); - motorButtonsTouched[1] = true; motorButtonsPointers[1] = pointer; @@ -405,6 +406,18 @@ public class InGameState extends BaseState{ event.setPower((byte)40); 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; @@ -506,6 +519,11 @@ public class InGameState extends BaseState{ 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; @@ -576,8 +594,8 @@ public class InGameState extends BaseState{ queue.addEvent(event); } - }else if(pointer == motorButtonsPointers[4] && headA.getBoundingRectangle().contains(touchPointWorldCoords)){ - Gdx.app.log(TAG, CLASS_NAME + ".touchUp() :: Head A button released"); + }else if(pointer == motorButtonsPointers[4] && !headA.getBoundingRectangle().contains(touchPointWorldCoords)){ + Gdx.app.log(TAG, CLASS_NAME + ".touchDragged() :: Head A button released"); motorButtonsPointers[4] = -1; motorButtonsTouched[4] = false; @@ -590,8 +608,8 @@ public class InGameState extends BaseState{ queue.addEvent(event); } - }else if(pointer == motorButtonsPointers[5] && headB.getBoundingRectangle().contains(touchPointWorldCoords)){ - Gdx.app.log(TAG, CLASS_NAME + ".touchUp() :: Head B button released"); + }else if(pointer == motorButtonsPointers[5] && !headB.getBoundingRectangle().contains(touchPointWorldCoords)){ + Gdx.app.log(TAG, CLASS_NAME + ".touchDragged() :: Head B button released"); motorButtonsPointers[5] = -1; motorButtonsTouched[5] = false; @@ -604,6 +622,11 @@ public class InGameState extends BaseState{ 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; @@ -659,6 +682,7 @@ public class InGameState extends BaseState{ event.setPower((byte)-40); queue.addEvent(event); } + }else if(buttonCode == Ouya.BUTTON_DPAD_RIGHT){ motorGamepadButtonPressed[3] = false; @@ -668,6 +692,7 @@ public class InGameState extends BaseState{ event.setPower((byte)40); queue.addEvent(event); } + }else if(buttonCode == Ouya.BUTTON_L2){ motorGamepadButtonPressed[4] = false; @@ -688,6 +713,13 @@ public class InGameState extends BaseState{ 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; @@ -760,6 +792,9 @@ public class InGameState extends BaseState{ event.setPower((byte)0); queue.addEvent(event); } + + }else if(buttonCode == Ouya.BUTTON_Y){ + motorGamepadButtonPressed[6] = false; } return true;