Merge branch 'robot_control' into develop
This commit is contained in:
37
src/ve/ucv/ciens/ccg/networkdata/MotorEvent.java
Normal file
37
src/ve/ucv/ciens/ccg/networkdata/MotorEvent.java
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
package ve.ucv.ciens.ccg.networkdata;
|
||||||
|
|
||||||
|
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};
|
||||||
|
|
||||||
|
private motor_t motor;
|
||||||
|
private byte power;
|
||||||
|
|
||||||
|
public MotorEvent(){
|
||||||
|
motor = motor_t.NONE;
|
||||||
|
power = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMotor(motor_t motor){
|
||||||
|
this.motor = motor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPower(byte power) throws IllegalArgumentException{
|
||||||
|
if(power > 100 || power < -100){
|
||||||
|
throw new IllegalArgumentException("Motor power must be a number between -100 and 100");
|
||||||
|
}else{
|
||||||
|
this.power = power;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public motor_t getMotor(){
|
||||||
|
return this.motor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte getPower(){
|
||||||
|
return this.power;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -28,7 +28,12 @@ import ve.ucv.ciens.ccg.nxtar.utils.Size;
|
|||||||
import com.badlogic.gdx.Application;
|
import com.badlogic.gdx.Application;
|
||||||
import com.badlogic.gdx.ApplicationListener;
|
import com.badlogic.gdx.ApplicationListener;
|
||||||
import com.badlogic.gdx.Gdx;
|
import com.badlogic.gdx.Gdx;
|
||||||
import com.badlogic.gdx.graphics.FPSLogger;
|
import com.badlogic.gdx.InputProcessor;
|
||||||
|
import com.badlogic.gdx.controllers.Controller;
|
||||||
|
import com.badlogic.gdx.controllers.ControllerListener;
|
||||||
|
import com.badlogic.gdx.controllers.Controllers;
|
||||||
|
import com.badlogic.gdx.controllers.PovDirection;
|
||||||
|
import com.badlogic.gdx.controllers.mappings.Ouya;
|
||||||
import com.badlogic.gdx.graphics.GL10;
|
import com.badlogic.gdx.graphics.GL10;
|
||||||
import com.badlogic.gdx.graphics.OrthographicCamera;
|
import com.badlogic.gdx.graphics.OrthographicCamera;
|
||||||
import com.badlogic.gdx.graphics.Pixmap;
|
import com.badlogic.gdx.graphics.Pixmap;
|
||||||
@@ -38,23 +43,37 @@ import com.badlogic.gdx.graphics.g2d.BitmapFont;
|
|||||||
import com.badlogic.gdx.graphics.g2d.Sprite;
|
import com.badlogic.gdx.graphics.g2d.Sprite;
|
||||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
|
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
|
||||||
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
||||||
|
import com.badlogic.gdx.math.Vector2;
|
||||||
|
import com.badlogic.gdx.math.Vector3;
|
||||||
|
|
||||||
public class NxtARCore implements ApplicationListener, NetworkConnectionListener {
|
public class NxtARCore implements ApplicationListener, NetworkConnectionListener, InputProcessor, ControllerListener{
|
||||||
private static final String TAG = "NXTAR_CORE_MAIN";
|
private static final String TAG = "NXTAR_CORE_MAIN";
|
||||||
private static final String CLASS_NAME = NxtARCore.class.getSimpleName();
|
private static final String CLASS_NAME = NxtARCore.class.getSimpleName();
|
||||||
|
|
||||||
private OrthographicCamera camera;
|
private OrthographicCamera camera;
|
||||||
|
private OrthographicCamera pixelPerfectCamera;
|
||||||
private SpriteBatch batch;
|
private SpriteBatch batch;
|
||||||
private Texture texture;
|
private Texture texture;
|
||||||
|
private Texture buttonTexture;
|
||||||
private Sprite sprite;
|
private Sprite sprite;
|
||||||
|
private Sprite motorA;
|
||||||
|
private Sprite motorB;
|
||||||
|
private Sprite motorC;
|
||||||
|
private Sprite motorD;
|
||||||
private Toaster toaster;
|
private Toaster toaster;
|
||||||
private MulticastEnabler mcastEnabler;
|
private MulticastEnabler mcastEnabler;
|
||||||
private FPSLogger fps;
|
|
||||||
private BitmapFont font;
|
private BitmapFont font;
|
||||||
private int connections;
|
private int connections;
|
||||||
|
private float fontX;
|
||||||
|
private float fontY;
|
||||||
|
private Pixmap image;
|
||||||
|
private Vector3 win2world;
|
||||||
|
private Vector2 touchPointWorldCoords;
|
||||||
|
private boolean[] motorButtonsTouched;
|
||||||
|
private int[] motorButtonsPointers;
|
||||||
|
|
||||||
private VideoFrameMonitor frameMonitor;
|
private VideoFrameMonitor frameMonitor;
|
||||||
private ServiceDiscoveryThread udpThread;
|
private ServiceDiscoveryThread serviceDiscoveryThread;
|
||||||
private VideoStreamingThread videoThread;
|
private VideoStreamingThread videoThread;
|
||||||
private RobotControlThread robotThread;
|
private RobotControlThread robotThread;
|
||||||
|
|
||||||
@@ -66,41 +85,59 @@ public class NxtARCore implements ApplicationListener, NetworkConnectionListener
|
|||||||
this.mcastEnabler = (MulticastEnabler)concreteApp;
|
this.mcastEnabler = (MulticastEnabler)concreteApp;
|
||||||
}catch(ClassCastException cc){
|
}catch(ClassCastException cc){
|
||||||
Gdx.app.debug(TAG, CLASS_NAME + ".Main() :: concreteApp does not implement any of the required interfaces.");
|
Gdx.app.debug(TAG, CLASS_NAME + ".Main() :: concreteApp does not implement any of the required interfaces.");
|
||||||
System.exit(ProjectConstants.EXIT_FAILURE);
|
Gdx.app.exit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void create(){
|
public void create(){
|
||||||
float w = Gdx.graphics.getWidth();
|
image = null;
|
||||||
float h = Gdx.graphics.getHeight();
|
win2world = new Vector3(0.0f, 0.0f, 0.0f);
|
||||||
|
touchPointWorldCoords = new Vector2();
|
||||||
|
motorButtonsTouched = new boolean[4];
|
||||||
|
motorButtonsTouched[0] = false;
|
||||||
|
motorButtonsTouched[1] = false;
|
||||||
|
motorButtonsTouched[2] = false;
|
||||||
|
motorButtonsTouched[3] = false;
|
||||||
|
|
||||||
|
motorButtonsPointers = new int[4];
|
||||||
|
motorButtonsPointers[0] = -1;
|
||||||
|
motorButtonsPointers[1] = -1;
|
||||||
|
motorButtonsPointers[2] = -1;
|
||||||
|
motorButtonsPointers[3] = -1;
|
||||||
|
|
||||||
|
Gdx.input.setInputProcessor(this);
|
||||||
|
Controllers.addListener(this);
|
||||||
|
|
||||||
fps = new FPSLogger();
|
|
||||||
font = new BitmapFont();
|
font = new BitmapFont();
|
||||||
|
|
||||||
Gdx.app.setLogLevel(Application.LOG_DEBUG);
|
font.setColor(1.0f, 1.0f, 0.0f, 1.0f);
|
||||||
|
if(!Ouya.runningOnOuya){
|
||||||
|
font.setScale(1.0f);
|
||||||
|
}else{
|
||||||
|
font.setScale(2.5f);
|
||||||
|
}
|
||||||
|
|
||||||
camera = new OrthographicCamera(1, h/w);
|
//Gdx.app.setLogLevel(Application.LOG_INFO);
|
||||||
|
Gdx.app.setLogLevel(Application.LOG_NONE);
|
||||||
|
|
||||||
|
pixelPerfectCamera = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
|
||||||
|
camera = new OrthographicCamera(1.0f, Gdx.graphics.getHeight() / Gdx.graphics.getWidth());
|
||||||
batch = new SpriteBatch();
|
batch = new SpriteBatch();
|
||||||
|
|
||||||
texture = new Texture(Gdx.files.internal("data/libgdx.png"));
|
fontX = -((Gdx.graphics.getWidth() * ProjectConstants.OVERSCAN) / 2) + 10;
|
||||||
texture.setFilter(TextureFilter.Linear, TextureFilter.Linear);
|
fontY = ((Gdx.graphics.getHeight() * ProjectConstants.OVERSCAN) / 2) - 10;
|
||||||
|
if(!Ouya.runningOnOuya) setUpButtons();
|
||||||
TextureRegion region = new TextureRegion(texture, 0, 0, 512, 275);
|
|
||||||
|
|
||||||
sprite = new Sprite(region);
|
|
||||||
sprite.setSize(0.9f, 0.9f * sprite.getHeight() / sprite.getWidth());
|
|
||||||
sprite.setOrigin(sprite.getWidth()/2, sprite.getHeight()/2);
|
|
||||||
sprite.setPosition(-sprite.getWidth()/2, -sprite.getHeight()/2);
|
|
||||||
|
|
||||||
Gdx.app.debug(TAG, CLASS_NAME + ".create() :: Creating network threads");
|
Gdx.app.debug(TAG, CLASS_NAME + ".create() :: Creating network threads");
|
||||||
frameMonitor = VideoFrameMonitor.getInstance();
|
frameMonitor = VideoFrameMonitor.getInstance();
|
||||||
mcastEnabler.enableMulticast();
|
serviceDiscoveryThread = ServiceDiscoveryThread.getInstance();
|
||||||
udpThread = ServiceDiscoveryThread.getInstance();
|
videoThread = VideoStreamingThread.getInstance()/*.setToaster(toaster)*/;
|
||||||
videoThread = VideoStreamingThread.getInstance().setToaster(toaster);
|
|
||||||
//robotThread = RobotControlThread.getInstance().setToaster(toaster);
|
//robotThread = RobotControlThread.getInstance().setToaster(toaster);
|
||||||
|
|
||||||
udpThread.start();
|
mcastEnabler.enableMulticast();
|
||||||
|
|
||||||
|
serviceDiscoveryThread.start();
|
||||||
videoThread.start();
|
videoThread.start();
|
||||||
videoThread.startStreaming();
|
videoThread.startStreaming();
|
||||||
//robotThread.start();
|
//robotThread.start();
|
||||||
@@ -109,56 +146,83 @@ public class NxtARCore implements ApplicationListener, NetworkConnectionListener
|
|||||||
@Override
|
@Override
|
||||||
public void dispose() {
|
public void dispose() {
|
||||||
batch.dispose();
|
batch.dispose();
|
||||||
texture.dispose();
|
if(texture != null)
|
||||||
|
texture.dispose();
|
||||||
|
if(buttonTexture != null)
|
||||||
|
buttonTexture.dispose();
|
||||||
font.dispose();
|
font.dispose();
|
||||||
|
image.dispose();
|
||||||
|
videoThread.finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void render(){
|
public void render(){
|
||||||
Pixmap image;
|
|
||||||
Pixmap temp;
|
Pixmap temp;
|
||||||
byte[] frame;
|
byte[] frame;
|
||||||
Size dimensions;
|
Size dimensions = null;
|
||||||
|
|
||||||
Gdx.gl.glClearColor(1, 1, 1, 1);
|
Gdx.gl.glClearColor(1, 1, 1, 1);
|
||||||
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
|
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
frame = frameMonitor.getCurrentFrame();
|
frame = frameMonitor.getCurrentFrame();
|
||||||
if(frame != null){
|
if(frame != null){
|
||||||
texture.dispose();
|
|
||||||
|
|
||||||
dimensions = frameMonitor.getFrameDimensions();
|
dimensions = frameMonitor.getFrameDimensions();
|
||||||
temp = new Pixmap(frame, 0, dimensions.getWidth() * dimensions.getHeight());
|
temp = new Pixmap(frame, 0, dimensions.getWidth() * dimensions.getHeight());
|
||||||
image = new Pixmap(1024, 512, temp.getFormat());
|
if(image == null){
|
||||||
|
try{
|
||||||
|
image = new Pixmap(getOptimalTextureSize(dimensions.getWidth()), getOptimalTextureSize(dimensions.getHeight()), temp.getFormat());
|
||||||
|
}catch(ImageTooBigException e){
|
||||||
|
toaster.showLongToast("Cannot display received frame.\n" + e.getMessage());
|
||||||
|
Gdx.app.exit();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
image.drawPixmap(temp, 0, 0);
|
image.drawPixmap(temp, 0, 0);
|
||||||
|
temp.dispose();
|
||||||
texture = new Texture(image);
|
texture = new Texture(image);
|
||||||
texture.setFilter(TextureFilter.Linear, TextureFilter.Linear);
|
texture.setFilter(TextureFilter.Linear, TextureFilter.Linear);
|
||||||
|
|
||||||
TextureRegion region = new TextureRegion(texture, 0, 0, dimensions.getWidth(), dimensions.getHeight());
|
TextureRegion region = new TextureRegion(texture, 0, 0, dimensions.getWidth(), dimensions.getHeight());
|
||||||
|
|
||||||
sprite = new Sprite(region);
|
sprite = new Sprite(region);
|
||||||
sprite.setSize(0.9f, 0.9f * sprite.getWidth() / sprite.getHeight());
|
sprite.setOrigin(sprite.getWidth() / 2, sprite.getHeight() / 2);
|
||||||
sprite.setOrigin(sprite.getWidth()/2, sprite.getHeight()/2);
|
if(!Ouya.runningOnOuya){
|
||||||
sprite.setPosition(-sprite.getWidth()/2, -sprite.getHeight()/2);
|
sprite.setSize(1.0f, sprite.getHeight() / sprite.getWidth() );
|
||||||
sprite.rotate90(true);
|
sprite.rotate90(true);
|
||||||
|
sprite.translate(-sprite.getWidth() / 2, 0.5f - sprite.getHeight());
|
||||||
|
}else{
|
||||||
|
float xSize = Gdx.graphics.getHeight() * (dimensions.getWidth() / dimensions.getHeight());
|
||||||
|
sprite.setSize(xSize * ProjectConstants.OVERSCAN, Gdx.graphics.getHeight() * ProjectConstants.OVERSCAN);
|
||||||
|
sprite.rotate90(true);
|
||||||
|
sprite.translate(-sprite.getWidth() / 2, -sprite.getHeight() / 2);
|
||||||
|
}
|
||||||
|
|
||||||
batch.setProjectionMatrix(camera.combined);
|
if(!Ouya.runningOnOuya){
|
||||||
|
batch.setProjectionMatrix(camera.combined);
|
||||||
|
}else{
|
||||||
|
batch.setProjectionMatrix(pixelPerfectCamera.combined);
|
||||||
|
}
|
||||||
batch.begin();{
|
batch.begin();{
|
||||||
sprite.draw(batch);
|
sprite.draw(batch);
|
||||||
font.setColor(0.0f, 0.0f, 0.0f, 1.0f);
|
|
||||||
font.setScale(100.0f);
|
|
||||||
font.draw(batch, String.format("Render FPS: %d", Gdx.graphics.getFramesPerSecond()), 10, 300);
|
|
||||||
}batch.end();
|
}batch.end();
|
||||||
|
|
||||||
Gdx.app.log("Main", String.format("Network FPS: %d", videoThread.getFps()));
|
|
||||||
Gdx.app.log("Main", String.format("Render FPS: %d", Gdx.graphics.getFramesPerSecond()));
|
|
||||||
|
|
||||||
texture.dispose();
|
texture.dispose();
|
||||||
temp.dispose();
|
|
||||||
image.dispose();
|
|
||||||
|
|
||||||
//fps.log();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
batch.setProjectionMatrix(pixelPerfectCamera.combined);
|
||||||
|
batch.begin();{
|
||||||
|
if(!Ouya.runningOnOuya){
|
||||||
|
motorA.draw(batch);
|
||||||
|
motorB.draw(batch);
|
||||||
|
motorC.draw(batch);
|
||||||
|
motorD.draw(batch);
|
||||||
|
}
|
||||||
|
font.draw(batch, String.format("Render FPS: %d", Gdx.graphics.getFramesPerSecond()), fontX, fontY);
|
||||||
|
font.draw(batch, String.format("Network FPS: %d", videoThread.getFps()), fontX, fontY - font.getCapHeight() - 5);
|
||||||
|
font.draw(batch, String.format("Lost Network FPS: %d", videoThread.getLostFrames()), fontX, fontY - (2 * font.getCapHeight()) - 10);
|
||||||
|
if(dimensions != null)
|
||||||
|
font.draw(batch, String.format("Frame size: (%d, %d)", dimensions.getWidth(), dimensions.getHeight()), fontX, fontY - (3 * font.getCapHeight()) - 15);
|
||||||
|
}batch.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -167,10 +231,14 @@ public class NxtARCore implements ApplicationListener, NetworkConnectionListener
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void pause(){
|
public void pause(){
|
||||||
|
if(videoThread != null)
|
||||||
|
videoThread.pause();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void resume(){
|
public void resume(){
|
||||||
|
if(videoThread != null)
|
||||||
|
videoThread.play();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -179,8 +247,242 @@ public class NxtARCore implements ApplicationListener, NetworkConnectionListener
|
|||||||
connections += 1;
|
connections += 1;
|
||||||
if(connections >= 2){
|
if(connections >= 2){
|
||||||
Gdx.app.debug(TAG, CLASS_NAME + ".networkStreamConnected() :: Stopping service broadcast.");
|
Gdx.app.debug(TAG, CLASS_NAME + ".networkStreamConnected() :: Stopping service broadcast.");
|
||||||
udpThread.finish();
|
serviceDiscoveryThread.finish();
|
||||||
mcastEnabler.disableMulticast();
|
mcastEnabler.disableMulticast();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int getOptimalTextureSize(int imageSideLength) throws ImageTooBigException{
|
||||||
|
for(int po2: ProjectConstants.POWERS_OF_2){
|
||||||
|
if(imageSideLength < po2) return po2;
|
||||||
|
}
|
||||||
|
throw new ImageTooBigException("No valid texture size found. Image too large.");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setUpButtons(){
|
||||||
|
buttonTexture = new Texture(Gdx.files.internal("data/gfx/gui/PBCrichton_Flat_Button.png"));
|
||||||
|
buttonTexture.setFilter(TextureFilter.Linear, TextureFilter.Linear);
|
||||||
|
|
||||||
|
TextureRegion region = new TextureRegion(buttonTexture, 0, 0, buttonTexture.getWidth(), buttonTexture.getHeight());
|
||||||
|
|
||||||
|
motorA = new Sprite(region);
|
||||||
|
motorA.setSize(motorA.getWidth() * 0.7f, motorA.getHeight() * 0.7f);
|
||||||
|
|
||||||
|
motorB = new Sprite(region);
|
||||||
|
motorB.setSize(motorB.getWidth() * 0.7f, motorB.getHeight() * 0.7f);
|
||||||
|
|
||||||
|
motorC = new Sprite(region);
|
||||||
|
motorC.setSize(motorC.getWidth() * 0.7f, motorC.getHeight() * 0.7f);
|
||||||
|
|
||||||
|
motorD = new Sprite(region);
|
||||||
|
motorD.setSize(motorD.getWidth() * 0.7f, motorD.getHeight() * 0.7f);
|
||||||
|
|
||||||
|
motorA.setPosition(-(Gdx.graphics.getWidth() / 2) + 10, -(Gdx.graphics.getHeight() / 2) + motorB.getHeight() + 20);
|
||||||
|
motorB.setPosition(-(Gdx.graphics.getWidth() / 2) + 20 + (motorA.getWidth() / 2), -(Gdx.graphics.getHeight() / 2) + 10);
|
||||||
|
motorC.setPosition((Gdx.graphics.getWidth() / 2) - (1.5f * (motorD.getWidth())) - 20, -(Gdx.graphics.getHeight() / 2) + 10);
|
||||||
|
motorD.setPosition((Gdx.graphics.getWidth() / 2) - motorD.getWidth() - 10, -(Gdx.graphics.getHeight() / 2) + 20 + motorC.getHeight());
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ImageTooBigException extends Exception{
|
||||||
|
private static final long serialVersionUID = 9989L;
|
||||||
|
|
||||||
|
public ImageTooBigException(String msg){
|
||||||
|
super(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean keyDown(int keycode) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean keyUp(int keycode) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean keyTyped(char character) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
|
||||||
|
if(!Ouya.runningOnOuya){
|
||||||
|
win2world.set(screenX, screenY, 0.0f);
|
||||||
|
camera.unproject(win2world);
|
||||||
|
touchPointWorldCoords.set(win2world.x * Gdx.graphics.getWidth(), win2world.y * Gdx.graphics.getHeight());
|
||||||
|
|
||||||
|
Gdx.app.log(TAG, CLASS_NAME + String.format(".touchDown(%d, %d, %d, %d)", screenX, screenY, pointer, button));
|
||||||
|
Gdx.app.log(TAG, CLASS_NAME + String.format(".touchDown() :: Unprojected touch point: (%f, %f)", touchPointWorldCoords.x, touchPointWorldCoords.y));
|
||||||
|
|
||||||
|
if(motorA.getBoundingRectangle().contains(touchPointWorldCoords)){
|
||||||
|
Gdx.app.log(TAG, CLASS_NAME + ".touchDown() :: Motor A button pressed");
|
||||||
|
motorButtonsTouched[0] = true;
|
||||||
|
motorButtonsPointers[0] = pointer;
|
||||||
|
}else if(motorB.getBoundingRectangle().contains(touchPointWorldCoords)){
|
||||||
|
Gdx.app.log(TAG, CLASS_NAME + ".touchDown() :: Motor B button pressed");
|
||||||
|
motorButtonsTouched[1] = true;
|
||||||
|
motorButtonsPointers[1] = pointer;
|
||||||
|
}else if(motorC.getBoundingRectangle().contains(touchPointWorldCoords)){
|
||||||
|
Gdx.app.log(TAG, CLASS_NAME + ".touchDown() :: Motor C button pressed");
|
||||||
|
motorButtonsTouched[2] = true;
|
||||||
|
motorButtonsPointers[2] = pointer;
|
||||||
|
}else if(motorD.getBoundingRectangle().contains(touchPointWorldCoords)){
|
||||||
|
Gdx.app.log(TAG, CLASS_NAME + ".touchDown() :: Motor D button pressed");
|
||||||
|
motorButtonsTouched[3] = true;
|
||||||
|
motorButtonsPointers[3] = pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
|
||||||
|
if(!Ouya.runningOnOuya){
|
||||||
|
win2world.set(screenX, screenY, 0.0f);
|
||||||
|
camera.unproject(win2world);
|
||||||
|
touchPointWorldCoords.set(win2world.x * Gdx.graphics.getWidth(), win2world.y * Gdx.graphics.getHeight());
|
||||||
|
|
||||||
|
Gdx.app.log(TAG, CLASS_NAME + String.format(".touchUp(%d, %d, %d, %d)", screenX, screenY, pointer, button));
|
||||||
|
Gdx.app.log(TAG, CLASS_NAME + String.format(".touchUp() :: Unprojected touch point: (%f, %f)", touchPointWorldCoords.x, touchPointWorldCoords.y));
|
||||||
|
|
||||||
|
if(motorA.getBoundingRectangle().contains(touchPointWorldCoords)){
|
||||||
|
Gdx.app.log(TAG, CLASS_NAME + ".touchUp() :: Motor A button released");
|
||||||
|
motorButtonsPointers[0] = -1;
|
||||||
|
motorButtonsTouched[0] = false;
|
||||||
|
}else if(motorB.getBoundingRectangle().contains(touchPointWorldCoords)){
|
||||||
|
Gdx.app.log(TAG, CLASS_NAME + ".touchUp() :: Motor B button released");
|
||||||
|
motorButtonsPointers[1] = -1;
|
||||||
|
motorButtonsTouched[1] = false;
|
||||||
|
}else if(motorC.getBoundingRectangle().contains(touchPointWorldCoords)){
|
||||||
|
Gdx.app.log(TAG, CLASS_NAME + ".touchUp() :: Motor C button released");
|
||||||
|
motorButtonsPointers[2] = -1;
|
||||||
|
motorButtonsTouched[2] = false;
|
||||||
|
}else if(motorD.getBoundingRectangle().contains(touchPointWorldCoords)){
|
||||||
|
Gdx.app.log(TAG, CLASS_NAME + ".touchUp() :: Motor D button released");
|
||||||
|
motorButtonsPointers[3] = -1;
|
||||||
|
motorButtonsTouched[3] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean touchDragged(int screenX, int screenY, int pointer) {
|
||||||
|
if(!Ouya.runningOnOuya){
|
||||||
|
win2world.set(screenX, screenY, 0.0f);
|
||||||
|
camera.unproject(win2world);
|
||||||
|
touchPointWorldCoords.set(win2world.x * Gdx.graphics.getWidth(), win2world.y * Gdx.graphics.getHeight());
|
||||||
|
|
||||||
|
if(pointer == motorButtonsPointers[0] && !motorA.getBoundingRectangle().contains(touchPointWorldCoords)){
|
||||||
|
Gdx.app.log(TAG, CLASS_NAME + ".touchDragged() :: Motor A button released");
|
||||||
|
motorButtonsPointers[0] = -1;
|
||||||
|
motorButtonsTouched[0] = false;
|
||||||
|
}else if(pointer == motorButtonsPointers[1] && !motorB.getBoundingRectangle().contains(touchPointWorldCoords)){
|
||||||
|
Gdx.app.log(TAG, CLASS_NAME + ".touchDragged() :: Motor B button released");
|
||||||
|
motorButtonsPointers[1] = -1;
|
||||||
|
motorButtonsTouched[1] = false;
|
||||||
|
}else if(pointer == motorButtonsPointers[2] && !motorC.getBoundingRectangle().contains(touchPointWorldCoords)){
|
||||||
|
Gdx.app.log(TAG, CLASS_NAME + ".touchDragged() :: Motor C button released");
|
||||||
|
motorButtonsPointers[2] = -1;
|
||||||
|
motorButtonsTouched[2] = false;
|
||||||
|
}else if(pointer == motorButtonsPointers[3] && !motorD.getBoundingRectangle().contains(touchPointWorldCoords)){
|
||||||
|
Gdx.app.log(TAG, CLASS_NAME + ".touchDragged() :: Motor D button released");
|
||||||
|
motorButtonsPointers[3] = -1;
|
||||||
|
motorButtonsTouched[3] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean mouseMoved(int screenX, int screenY) {
|
||||||
|
Gdx.app.error(TAG, "MOUSE MOVED!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean scrolled(int amount) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void connected(Controller controller) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void disconnected(Controller controller) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean buttonDown(Controller controller, int buttonCode) {
|
||||||
|
if(buttonCode == Ouya.BUTTON_L1){
|
||||||
|
// Start right motor.
|
||||||
|
}
|
||||||
|
if(buttonCode == Ouya.BUTTON_L2){
|
||||||
|
// Start left motor.
|
||||||
|
}
|
||||||
|
if(buttonCode == Ouya.BUTTON_DPAD_LEFT){
|
||||||
|
// Look left.
|
||||||
|
}
|
||||||
|
if(buttonCode == Ouya.BUTTON_DPAD_RIGHT){
|
||||||
|
// Look right;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean buttonUp(Controller controller, int buttonCode) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean axisMoved(Controller controller, int axisCode, float value) {
|
||||||
|
if(axisCode == Ouya.AXIS_LEFT_TRIGGER){
|
||||||
|
|
||||||
|
}
|
||||||
|
if(axisCode == Ouya.AXIS_RIGHT_TRIGGER){
|
||||||
|
// Start
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean povMoved(Controller controller, int povCode,
|
||||||
|
PovDirection value) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean xSliderMoved(Controller controller, int sliderCode,
|
||||||
|
boolean value) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean ySliderMoved(Controller controller, int sliderCode,
|
||||||
|
boolean value) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean accelerometerMoved(Controller controller,
|
||||||
|
int accelerometerCode, Vector3 value) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return false;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ public class RobotControlThread extends Thread {
|
|||||||
Gdx.app.error(TAG, CLASS_NAME + ".RobotControlThread() :: Error creating server: " + io.getMessage(), io);
|
Gdx.app.error(TAG, CLASS_NAME + ".RobotControlThread() :: Error creating server: " + io.getMessage(), io);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class SingletonHolder{
|
private static class SingletonHolder{
|
||||||
public static final RobotControlThread INSTANCE = new RobotControlThread();
|
public static final RobotControlThread INSTANCE = new RobotControlThread();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,15 +18,12 @@ package ve.ucv.ciens.ccg.nxtar.network;
|
|||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.ObjectInputStream;
|
import java.io.ObjectInputStream;
|
||||||
import java.io.ObjectOutputStream;
|
|
||||||
import java.net.DatagramPacket;
|
import java.net.DatagramPacket;
|
||||||
import java.net.DatagramSocket;
|
import java.net.DatagramSocket;
|
||||||
import java.net.ServerSocket;
|
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
|
|
||||||
import ve.ucv.ciens.ccg.networkdata.VideoFrameDataMessage;
|
import ve.ucv.ciens.ccg.networkdata.VideoFrameDataMessage;
|
||||||
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.utils.ProjectConstants;
|
import ve.ucv.ciens.ccg.nxtar.utils.ProjectConstants;
|
||||||
|
|
||||||
import com.badlogic.gdx.Gdx;
|
import com.badlogic.gdx.Gdx;
|
||||||
@@ -36,44 +33,50 @@ public class VideoStreamingThread extends Thread {
|
|||||||
private static final String TAG = "NXTAR_CORE_VIDEOTHREAD";
|
private static final String TAG = "NXTAR_CORE_VIDEOTHREAD";
|
||||||
private static final String CLASS_NAME = VideoStreamingThread.class.getSimpleName();
|
private static final String CLASS_NAME = VideoStreamingThread.class.getSimpleName();
|
||||||
|
|
||||||
private enum ProtocolState_t {WAIT_FOR_START, SEND_CONTINUE, RECEIVE_DATA, SEND_ACK_NEXT, SEND_ACK_WAIT, PAUSED, END_STREAM};
|
//private enum ProtocolState_t {WAIT_FOR_START, SEND_CONTINUE, RECEIVE_DATA, SEND_ACK_NEXT, SEND_ACK_WAIT, PAUSED, END_STREAM};
|
||||||
|
|
||||||
private NetworkConnectionListener netListener;
|
private NetworkConnectionListener netListener;
|
||||||
private ServerSocket server;
|
//private ServerSocket server;
|
||||||
private DatagramSocket socket;
|
private DatagramSocket socket;
|
||||||
private Toaster toaster;
|
//private Toaster toaster;
|
||||||
private ProtocolState_t protocolState;
|
//private ProtocolState_t protocolState;
|
||||||
private boolean protocolStarted;
|
private boolean protocolStarted;
|
||||||
private boolean pauseProtocol;
|
/*private boolean pauseProtocol;
|
||||||
private boolean endProtocol;
|
private boolean endProtocol;*/
|
||||||
private boolean done;
|
private boolean done;
|
||||||
|
private boolean pause;
|
||||||
private Object protocolPauseMonitor;
|
private Object protocolPauseMonitor;
|
||||||
private Socket client;
|
private Socket client;
|
||||||
private ObjectInputStream reader;
|
//private ObjectInputStream reader;
|
||||||
private ObjectOutputStream writer;
|
//private ObjectOutputStream writer;
|
||||||
private VideoFrameMonitor frameMonitor;
|
private VideoFrameMonitor frameMonitor;
|
||||||
private long then;
|
private long then;
|
||||||
private long now;
|
private long now;
|
||||||
private long delta;
|
private long delta;
|
||||||
private int fps;
|
private int fps;
|
||||||
|
private int lostFramesPerSecond;
|
||||||
|
private int lostFrames;
|
||||||
|
private Object pauseMonitor;
|
||||||
|
|
||||||
private VideoStreamingThread(){
|
private VideoStreamingThread(){
|
||||||
super(THREAD_NAME);
|
super(THREAD_NAME);
|
||||||
|
|
||||||
|
pauseMonitor = new Object();
|
||||||
fps = 0;
|
fps = 0;
|
||||||
|
lostFramesPerSecond = 0;
|
||||||
netListener = null;
|
netListener = null;
|
||||||
toaster = null;
|
//toaster = null;
|
||||||
protocolStarted = false;
|
protocolStarted = false;
|
||||||
endProtocol = false;
|
/*endProtocol = false;
|
||||||
pauseProtocol = false;
|
pauseProtocol = false;*/
|
||||||
done = false;
|
done = false;
|
||||||
protocolState = ProtocolState_t.WAIT_FOR_START;
|
//protocolState = ProtocolState_t.WAIT_FOR_START;
|
||||||
protocolPauseMonitor = new Object();
|
protocolPauseMonitor = new Object();
|
||||||
frameMonitor = VideoFrameMonitor.getInstance();
|
frameMonitor = VideoFrameMonitor.getInstance();
|
||||||
|
|
||||||
try{
|
try{
|
||||||
server = new ServerSocket(ProjectConstants.SERVER_TCP_PORT_1);
|
//server = new ServerSocket(ProjectConstants.SERVER_TCP_PORT_1);
|
||||||
socket = new DatagramSocket(ProjectConstants.SERVER_TCP_PORT_2);
|
socket = new DatagramSocket(ProjectConstants.SERVER_TCP_PORT_1);
|
||||||
}catch(IOException io){
|
}catch(IOException io){
|
||||||
Gdx.app.error(TAG, CLASS_NAME + ".VideoStreamingThread() :: Error creating server: " + io.getMessage(), io);
|
Gdx.app.error(TAG, CLASS_NAME + ".VideoStreamingThread() :: Error creating server: " + io.getMessage(), io);
|
||||||
}
|
}
|
||||||
@@ -87,26 +90,26 @@ public class VideoStreamingThread extends Thread {
|
|||||||
return SingletonHolder.INSTANCE;
|
return SingletonHolder.INSTANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public VideoStreamingThread setToaster(Toaster toaster){
|
/*public VideoStreamingThread setToaster(Toaster toaster){
|
||||||
this.toaster = toaster;
|
this.toaster = toaster;
|
||||||
return this;
|
return this;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
public void addNetworkConnectionListener(NetworkConnectionListener listener){
|
public void addNetworkConnectionListener(NetworkConnectionListener listener){
|
||||||
netListener = listener;
|
netListener = listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void toast(String message){
|
/*private void toast(String message){
|
||||||
if(toaster != null)
|
if(toaster != null)
|
||||||
toaster.showShortToast(message);
|
toaster.showShortToast(message);
|
||||||
}
|
}*/
|
||||||
|
|
||||||
public void startStreaming(){
|
public void startStreaming(){
|
||||||
if(!protocolStarted){
|
if(!protocolStarted){
|
||||||
Gdx.app.debug(TAG, CLASS_NAME + ".startStreaming() :: Requesting protocol start.");
|
Gdx.app.debug(TAG, CLASS_NAME + ".startStreaming() :: Requesting protocol start.");
|
||||||
synchronized(protocolPauseMonitor){
|
synchronized(protocolPauseMonitor){
|
||||||
protocolStarted = true;
|
protocolStarted = true;
|
||||||
protocolState = ProtocolState_t.SEND_CONTINUE;
|
//protocolState = ProtocolState_t.SEND_CONTINUE;
|
||||||
protocolPauseMonitor.notifyAll();
|
protocolPauseMonitor.notifyAll();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -115,7 +118,7 @@ public class VideoStreamingThread extends Thread {
|
|||||||
public void pauseStreaming(){
|
public void pauseStreaming(){
|
||||||
if(protocolStarted){
|
if(protocolStarted){
|
||||||
Gdx.app.debug(TAG, CLASS_NAME + ".pauseStreaming() :: Requesting protocol pause.");
|
Gdx.app.debug(TAG, CLASS_NAME + ".pauseStreaming() :: Requesting protocol pause.");
|
||||||
pauseProtocol = true;
|
//pauseProtocol = true;
|
||||||
}else
|
}else
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -124,7 +127,7 @@ public class VideoStreamingThread extends Thread {
|
|||||||
if(protocolStarted){
|
if(protocolStarted){
|
||||||
Gdx.app.debug(TAG, CLASS_NAME + ".resumeStreaming() :: Requesting protocol resume.");
|
Gdx.app.debug(TAG, CLASS_NAME + ".resumeStreaming() :: Requesting protocol resume.");
|
||||||
synchronized(protocolPauseMonitor){
|
synchronized(protocolPauseMonitor){
|
||||||
pauseProtocol = false;
|
//pauseProtocol = false;
|
||||||
protocolPauseMonitor.notifyAll();
|
protocolPauseMonitor.notifyAll();
|
||||||
}
|
}
|
||||||
}else
|
}else
|
||||||
@@ -134,7 +137,7 @@ public class VideoStreamingThread extends Thread {
|
|||||||
public void finishStreaming(){
|
public void finishStreaming(){
|
||||||
if(protocolStarted){
|
if(protocolStarted){
|
||||||
Gdx.app.debug(TAG, CLASS_NAME + ".finishStreaming() :: Requesting protocol end.");
|
Gdx.app.debug(TAG, CLASS_NAME + ".finishStreaming() :: Requesting protocol end.");
|
||||||
endProtocol = true;
|
//endProtocol = true;
|
||||||
}else
|
}else
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -312,7 +315,7 @@ public class VideoStreamingThread extends Thread {
|
|||||||
Gdx.app.debug(TAG, CLASS_NAME + ".run() :: Thread finished.");
|
Gdx.app.debug(TAG, CLASS_NAME + ".run() :: Thread finished.");
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
private void receiveImage(){
|
/*private void receiveImage(){
|
||||||
Object tmpMessage;
|
Object tmpMessage;
|
||||||
VideoFrameDataMessage dataMessage;
|
VideoFrameDataMessage dataMessage;
|
||||||
|
|
||||||
@@ -337,7 +340,7 @@ public class VideoStreamingThread extends Thread {
|
|||||||
}else{
|
}else{
|
||||||
Gdx.app.debug(TAG, CLASS_NAME + ".run() :: Received something unknown.");
|
Gdx.app.debug(TAG, CLASS_NAME + ".run() :: Received something unknown.");
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
private int byteArray2Int(byte[] array){
|
private int byteArray2Int(byte[] array){
|
||||||
int number = 0;
|
int number = 0;
|
||||||
@@ -349,63 +352,69 @@ public class VideoStreamingThread extends Thread {
|
|||||||
|
|
||||||
private void receiveUdp(){
|
private void receiveUdp(){
|
||||||
try{
|
try{
|
||||||
int intSize;
|
int intSize;
|
||||||
byte[] size = new byte[4];
|
byte[] size = new byte[4];
|
||||||
byte[] data;
|
byte[] data;
|
||||||
DatagramPacket packet;
|
DatagramPacket packet;
|
||||||
VideoFrameDataMessage dataMessage;
|
VideoFrameDataMessage dataMessage;
|
||||||
Object tmpMessage;
|
Object tmpMessage;
|
||||||
|
|
||||||
Gdx.app.debug(TAG, CLASS_NAME + ".receiveUdp() :: Reading message size from socket.");
|
Gdx.app.debug(TAG, CLASS_NAME + ".receiveUdp() :: Reading message size from socket.");
|
||||||
try{
|
try{
|
||||||
packet = new DatagramPacket(size, size.length);
|
packet = new DatagramPacket(size, size.length);
|
||||||
socket.receive(packet);
|
socket.receive(packet);
|
||||||
}catch(IOException io){
|
}catch(IOException io){
|
||||||
Gdx.app.error(TAG, CLASS_NAME + ".receiveUdp() :: IOException receiving size " + io.getMessage());
|
Gdx.app.error(TAG, CLASS_NAME + ".receiveUdp() :: IOException receiving size " + io.getMessage());
|
||||||
return;
|
lostFramesPerSecond += 1;
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
Gdx.app.debug(TAG, CLASS_NAME + ".receiveUdp() :: Creating buffers.");
|
|
||||||
intSize = byteArray2Int(size);
|
Gdx.app.debug(TAG, CLASS_NAME + ".receiveUdp() :: Creating buffers.");
|
||||||
data = new byte[intSize];
|
intSize = byteArray2Int(size);
|
||||||
|
data = new byte[intSize];
|
||||||
Gdx.app.debug(TAG, CLASS_NAME + ".receiveUdp() :: Reading message from socket.");
|
|
||||||
try{
|
Gdx.app.debug(TAG, CLASS_NAME + ".receiveUdp() :: Reading message from socket.");
|
||||||
packet = new DatagramPacket(data, data.length);
|
try{
|
||||||
socket.receive(packet);
|
packet = new DatagramPacket(data, data.length);
|
||||||
}catch(IOException io){
|
socket.receive(packet);
|
||||||
Gdx.app.error(TAG, CLASS_NAME + ".receiveUdp() :: IOException receiving data " + io.getMessage());
|
}catch(IOException io){
|
||||||
return;
|
Gdx.app.error(TAG, CLASS_NAME + ".receiveUdp() :: IOException receiving data " + io.getMessage());
|
||||||
}
|
lostFramesPerSecond += 1;
|
||||||
|
return;
|
||||||
ByteArrayInputStream bais = new ByteArrayInputStream(data);
|
}
|
||||||
|
|
||||||
Gdx.app.debug(TAG, CLASS_NAME + ".receiveUdp() :: Saving message in monitor.");
|
ByteArrayInputStream bais = new ByteArrayInputStream(data);
|
||||||
try{
|
|
||||||
ObjectInputStream ois = new ObjectInputStream(bais);
|
Gdx.app.debug(TAG, CLASS_NAME + ".receiveUdp() :: Saving message in monitor.");
|
||||||
tmpMessage = ois.readObject();
|
try{
|
||||||
|
ObjectInputStream ois = new ObjectInputStream(bais);
|
||||||
if(tmpMessage instanceof VideoFrameDataMessage){
|
tmpMessage = ois.readObject();
|
||||||
Gdx.app.debug(TAG, CLASS_NAME + ".receiveUdp() :: Received a data message.");
|
|
||||||
dataMessage = (VideoFrameDataMessage) tmpMessage;
|
if(tmpMessage instanceof VideoFrameDataMessage){
|
||||||
|
Gdx.app.debug(TAG, CLASS_NAME + ".receiveUdp() :: Received a data message.");
|
||||||
Gdx.app.debug(TAG, CLASS_NAME + ".receiveUdp() :: Received frame dimensions are: " +
|
dataMessage = (VideoFrameDataMessage) tmpMessage;
|
||||||
Integer.toString(dataMessage.imageWidth) + "x" + Integer.toString(dataMessage.imageHeight));
|
|
||||||
frameMonitor.setFrameDimensions(dataMessage.imageWidth, dataMessage.imageHeight);
|
Gdx.app.debug(TAG, CLASS_NAME + ".receiveUdp() :: Received frame dimensions are: " +
|
||||||
frameMonitor.setNewFrame(dataMessage.data);
|
Integer.toString(dataMessage.imageWidth) + "x" + Integer.toString(dataMessage.imageHeight));
|
||||||
|
frameMonitor.setFrameDimensions(dataMessage.imageWidth, dataMessage.imageHeight);
|
||||||
}else{
|
frameMonitor.setNewFrame(dataMessage.data);
|
||||||
Gdx.app.debug(TAG, CLASS_NAME + ".receiveUdp() :: Received something unknown.");
|
|
||||||
|
}else{
|
||||||
|
Gdx.app.debug(TAG, CLASS_NAME + ".receiveUdp() :: Received something unknown.");
|
||||||
|
lostFramesPerSecond += 1;
|
||||||
|
}
|
||||||
|
}catch(IOException io){
|
||||||
|
Gdx.app.error(TAG, CLASS_NAME + ".receiveUdp() :: IOException received deserializing message " + io.getMessage());
|
||||||
|
lostFramesPerSecond += 1;
|
||||||
|
return;
|
||||||
|
}catch(ClassNotFoundException cn){
|
||||||
|
Gdx.app.error(TAG, CLASS_NAME + ".receiveUdp() :: ClassNotFoundException received " + cn.getMessage());
|
||||||
|
lostFramesPerSecond += 1;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}catch(IOException io){
|
|
||||||
Gdx.app.error(TAG, CLASS_NAME + ".receiveUdp() :: IOException received deserializing message " + io.getMessage());
|
|
||||||
return;
|
|
||||||
}catch(ClassNotFoundException cn){
|
|
||||||
Gdx.app.error(TAG, CLASS_NAME + ".receiveUdp() :: ClassNotFoundException received " + cn.getMessage());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}catch(Exception e){
|
}catch(Exception e){
|
||||||
Gdx.app.error(TAG, CLASS_NAME + ".receiveUdp() :: Exception received " + e.getMessage());
|
Gdx.app.error(TAG, CLASS_NAME + ".receiveUdp() :: Exception received " + e.getMessage());
|
||||||
|
lostFramesPerSecond += 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -413,31 +422,42 @@ public class VideoStreamingThread extends Thread {
|
|||||||
public int getFps(){
|
public int getFps(){
|
||||||
return fps;
|
return fps;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getLostFrames(){
|
||||||
|
return lostFrames;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run(){
|
public void run(){
|
||||||
int frames = 0;
|
int frames = 0;
|
||||||
|
lostFrames = 0;
|
||||||
// Listen on the server socket until a client successfully connects.
|
// Listen on the server socket until a client successfully connects.
|
||||||
do{
|
/*do{
|
||||||
try{
|
try{
|
||||||
Gdx.app.debug(TAG, CLASS_NAME + ".run() :: Listening for client.");
|
Gdx.app.debug(TAG, CLASS_NAME + ".run() :: Listening for client.");
|
||||||
client = server.accept();
|
client = server.accept();
|
||||||
if(netListener != null)
|
if(netListener != null)
|
||||||
netListener.networkStreamConnected(THREAD_NAME);
|
netListener.networkStreamConnected(THREAD_NAME);
|
||||||
writer = new ObjectOutputStream(client.getOutputStream());
|
//writer = new ObjectOutputStream(client.getOutputStream());
|
||||||
reader = new ObjectInputStream(client.getInputStream());
|
reader = new ObjectInputStream(client.getInputStream());
|
||||||
toast("Client connected");
|
toast("Client connected");
|
||||||
}catch(IOException io){
|
}catch(IOException io){
|
||||||
Gdx.app.error(TAG, CLASS_NAME + ".run() :: Error accepting client: " + io.getMessage(), io);
|
Gdx.app.error(TAG, CLASS_NAME + ".run() :: Error accepting client: " + io.getMessage(), io);
|
||||||
client = null;
|
client = null;
|
||||||
}
|
}
|
||||||
}while(client != null && !client.isConnected());
|
}while(client != null && !client.isConnected());*/
|
||||||
|
|
||||||
then = System.currentTimeMillis();
|
then = System.currentTimeMillis();
|
||||||
|
|
||||||
while(!done){
|
while(!done){
|
||||||
//receiveImage();
|
synchronized (pauseMonitor) {
|
||||||
|
while(pause){
|
||||||
|
try{ pauseMonitor.wait(); }catch(InterruptedException ie){ }
|
||||||
|
}
|
||||||
|
}
|
||||||
Gdx.app.debug(TAG, CLASS_NAME + ".run() :: Receiving.");
|
Gdx.app.debug(TAG, CLASS_NAME + ".run() :: Receiving.");
|
||||||
|
if(netListener != null)
|
||||||
|
netListener.networkStreamConnected(THREAD_NAME);
|
||||||
receiveUdp();
|
receiveUdp();
|
||||||
frames++;
|
frames++;
|
||||||
now = System.currentTimeMillis();
|
now = System.currentTimeMillis();
|
||||||
@@ -445,6 +465,8 @@ public class VideoStreamingThread extends Thread {
|
|||||||
if(delta >= 1000){
|
if(delta >= 1000){
|
||||||
fps = frames;
|
fps = frames;
|
||||||
frames = 0;
|
frames = 0;
|
||||||
|
lostFrames = lostFramesPerSecond;
|
||||||
|
lostFramesPerSecond = 0;
|
||||||
then = now;
|
then = now;
|
||||||
delta = 0;
|
delta = 0;
|
||||||
}
|
}
|
||||||
@@ -459,4 +481,16 @@ public class VideoStreamingThread extends Thread {
|
|||||||
Gdx.app.debug(TAG, CLASS_NAME + ".run() :: Thread finished.");
|
Gdx.app.debug(TAG, CLASS_NAME + ".run() :: Thread finished.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void pause(){
|
||||||
|
synchronized (pauseMonitor){
|
||||||
|
pause = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void play(){
|
||||||
|
synchronized (pauseMonitor){
|
||||||
|
pause = false;
|
||||||
|
pauseMonitor.notifyAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,8 @@
|
|||||||
*/
|
*/
|
||||||
package ve.ucv.ciens.ccg.nxtar.utils;
|
package ve.ucv.ciens.ccg.nxtar.utils;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.controllers.mappings.Ouya;
|
||||||
|
|
||||||
public abstract class ProjectConstants {
|
public abstract class ProjectConstants {
|
||||||
public static final int SERVER_UDP_PORT = 8889;
|
public static final int SERVER_UDP_PORT = 8889;
|
||||||
public static final int SERVER_TCP_PORT_1 = 9989;
|
public static final int SERVER_TCP_PORT_1 = 9989;
|
||||||
@@ -24,4 +26,12 @@ public abstract class ProjectConstants {
|
|||||||
public static final int EXIT_FAILURE = 1;
|
public static final int EXIT_FAILURE = 1;
|
||||||
|
|
||||||
public static final boolean DEBUG = true;
|
public static final boolean DEBUG = true;
|
||||||
|
|
||||||
|
public static final int[] POWERS_OF_2 = {64, 128, 256, 512, 1024, 2048};
|
||||||
|
|
||||||
|
public static final float OVERSCAN;
|
||||||
|
|
||||||
|
static{
|
||||||
|
OVERSCAN = Ouya.runningOnOuya ? 0.9f : 1.0f;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user