From a37ff0fba5c0bddd021ef328b61922ce291f8817 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 3 Apr 2014 11:28:30 -0430 Subject: [PATCH] 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]; + } + } } }