package de.otto.roborace.controller; import java.io.FileInputStream; import java.io.IOException; import java.util.Properties; import de.otto.roborace.model.RacingState; import lejos.hardware.motor.Motor; import de.otto.roborace.connection.ServerController; import de.otto.roborace.connection.WebSocketListener; import de.otto.roborace.model.DataModel; import de.otto.roborace.model.Steering; import org.json.JSONException; import org.json.JSONObject; /** * Created by luca on 06.03.15. */ public class RacerController { DataModel dataModel; ServerController serverController; SpeedController motorController; CourseController courseController; private Properties properties; private EventLoop eventLoop = new EventLoop(); private AudioVideoController audioVideoController; public RacerController() { properties = loadProperties(); dataModel = new DataModel(); System.out.println("start event loop"); audioVideoController = new AudioVideoController(); eventLoop.register(new SpeedController(dataModel, RacerController.this)); eventLoop.register(new SteeringController(Motor.C, dataModel)); eventLoop.register(new CourseController(dataModel, RacerController.this)); eventLoop.register(audioVideoController); eventLoop.start(); establishConnection(); // motorController = new MotorController(dataModel); // courseController = new CourseController(dataModel); } private Properties loadProperties() { Properties properties = new Properties(); try { properties.load(new FileInputStream("racerRobo.properties")); } catch (IOException e) { throw new RuntimeException(e); } return properties; } private void establishConnection() { serverController = new ServerController(properties.getProperty("serverIp"), properties.getProperty("serverPort", "8888")); serverController.connect(new WebSocketListener() { @Override public void connectionEstablished() { System.out.println("connected"); String connectMessage = "{\"eventType\": \"connect\", \"data\": {\"clientType\": \"robo\", \"name\": \"" + properties.getProperty("roboName") + "\", \"ready\": \"false\" }}"; System.out.println("sending conntect message: " + connectMessage); serverController.sendMsg(connectMessage); } @Override public void messageReceived(JSONObject message) { System.out.println("MESSAGE REVEIVED: " + message.toString()); handleJsonMsg(message); } @Override public void connectionEstablishmentFailed(String reason) { System.out.println("CONNECTION FAILED: " + reason); } @Override public void connectionClosed(String reason) { System.out.println("CONNECTION CLOSED: " + reason); } }); } private void handleJsonMsg(JSONObject json) { String eventType = null; try { eventType = json.get("eventType").toString(); System.out.println("EVENTTYPE: " + eventType); switch (eventType) { case "move": moveMessageReceived(json.getJSONObject("data")); break; case "startRace": startMessageReceived(); break; case "results": resultsMessageReceived(); break; default: System.out.println("Invalid eventType: " + eventType); } } catch (JSONException e) { e.printStackTrace(); } } private void resultsMessageReceived() { // when this message is received, the race is over for this roboter dataModel.setRacingState(RacingState.NORACE); } private void startMessageReceived() { dataModel.setRacingState(RacingState.RACE); audioVideoController.raceStarting(); } public void courseBoundaryReached() { serverController.sendBoundaryReachedMessage(); audioVideoController.trackLost(); } public void finishLineReached() { serverController.sendFinishLineReachedMessage(); audioVideoController.raceFinished(); } public void speedChangeDetected() { serverController.sendSpeedMessage(dataModel.getTargetSpeed()); } private void changeSteerDirection(Steering direction) { dataModel.setDesiredSteeringDirection(direction); } private void changeSpeed(int speed) { dataModel.setTargetSpeed(speed); } private void moveMessageReceived(JSONObject data) throws JSONException { if(data.has("speed")) { String speedString = data.getString("speed"); changeSpeed(Integer.parseInt(speedString)); } else { String direction = data.getString("direction"); switch (direction) { case "LEFT": changeSteerDirection(Steering.LEFT); break; case "RIGHT": changeSteerDirection(Steering.RIGHT); break; case "NONE": changeSteerDirection(Steering.NONE); break; default: System.out.println("no viable direction detected"); } } } }