From 6d6608bb67fa4a5f21fbbfd6a18eee3f13080ad8 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 10 Feb 2014 15:24:34 -0430 Subject: [PATCH] MotorControlThread receives and sends data. --- .../ciens/ccg/networkdata/MotorEventACK.java | 32 ++++++++++ src/ve/ucv/ciens/ccg/nxtcam/CamActivity.java | 14 ++++- src/ve/ucv/ciens/ccg/nxtcam/MainActivity.java | 2 +- .../nxtcam/network/MotorControlThread.java | 61 +++++++++++++++++-- .../nxtcam/network/SensorReportThread.java | 2 +- .../nxtcam/network/VideoStreamingThread.java | 6 +- .../nxtcam/robotcontrol/MotorEventQueue.java | 4 ++ .../ccg/nxtcam/utils/ProjectConstants.java | 10 +-- 8 files changed, 114 insertions(+), 17 deletions(-) create mode 100644 src/ve/ucv/ciens/ccg/networkdata/MotorEventACK.java diff --git a/src/ve/ucv/ciens/ccg/networkdata/MotorEventACK.java b/src/ve/ucv/ciens/ccg/networkdata/MotorEventACK.java new file mode 100644 index 0000000..a2911f9 --- /dev/null +++ b/src/ve/ucv/ciens/ccg/networkdata/MotorEventACK.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2014 Miguel Angel Astor Romero + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ve.ucv.ciens.ccg.networkdata; + +import java.io.Serializable; + +public class MotorEventACK implements Serializable { + private static final long serialVersionUID = 9989L; + + private boolean clientQueueIsFull; + + public MotorEventACK(boolean isQueueFull){ + this.clientQueueIsFull = isQueueFull; + } + + public boolean isClientQueueFull(){ + return this.clientQueueIsFull; + } +} diff --git a/src/ve/ucv/ciens/ccg/nxtcam/CamActivity.java b/src/ve/ucv/ciens/ccg/nxtcam/CamActivity.java index e02b331..6d28e8a 100644 --- a/src/ve/ucv/ciens/ccg/nxtcam/CamActivity.java +++ b/src/ve/ucv/ciens/ccg/nxtcam/CamActivity.java @@ -16,6 +16,7 @@ package ve.ucv.ciens.ccg.nxtcam; import ve.ucv.ciens.ccg.nxtcam.camera.CameraPreview; +import ve.ucv.ciens.ccg.nxtcam.network.MotorControlThread; import ve.ucv.ciens.ccg.nxtcam.network.VideoStreamingThread; import ve.ucv.ciens.ccg.nxtcam.network.LCPThread; import ve.ucv.ciens.ccg.nxtcam.utils.Logger; @@ -41,6 +42,7 @@ public class CamActivity extends Activity{ private CameraSetupTask camSetupTask; private VideoStreamingThread imThread; private LCPThread botThread; + private MotorControlThread motorThread; private String serverIp; /******************* @@ -56,6 +58,9 @@ public class CamActivity extends Activity{ serverIp = intent.getStringExtra("address"); imThread = new VideoStreamingThread(serverIp); imThread.start(); + + motorThread = new MotorControlThread(serverIp); + motorThread.start(); } @Override @@ -104,14 +109,17 @@ public class CamActivity extends Activity{ releaseCamera(); } } - + @Override public void onDestroy(){ super.onDestroy(); - // TODO: Destroy the network threads. + imThread.finish(); imThread = null; + + motorThread.finish(); + motorThread = null; } - + @Override public void onBackPressed(){ Intent result = new Intent(); diff --git a/src/ve/ucv/ciens/ccg/nxtcam/MainActivity.java b/src/ve/ucv/ciens/ccg/nxtcam/MainActivity.java index 31a5a1a..651062b 100644 --- a/src/ve/ucv/ciens/ccg/nxtcam/MainActivity.java +++ b/src/ve/ucv/ciens/ccg/nxtcam/MainActivity.java @@ -323,7 +323,7 @@ public class MainActivity extends Activity implements WifiOnDialogListener, Conn public ServiceDiscoveryTask(){ // Open a multicast socket and join the project's multicast group. try{ - udpSocket = new MulticastSocket(ProjectConstants.SERVER_UDP_PORT); + udpSocket = new MulticastSocket(ProjectConstants.SERVICE_DISCOVERY_PORT); InetAddress group = InetAddress.getByName(ProjectConstants.MULTICAST_ADDRESS); udpSocket.joinGroup(group); }catch(IOException io){ diff --git a/src/ve/ucv/ciens/ccg/nxtcam/network/MotorControlThread.java b/src/ve/ucv/ciens/ccg/nxtcam/network/MotorControlThread.java index d712060..12dcafb 100644 --- a/src/ve/ucv/ciens/ccg/nxtcam/network/MotorControlThread.java +++ b/src/ve/ucv/ciens/ccg/nxtcam/network/MotorControlThread.java @@ -2,9 +2,12 @@ package ve.ucv.ciens.ccg.nxtcam.network; import java.io.IOException; import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; import java.net.Socket; import ve.ucv.ciens.ccg.networkdata.MotorEvent; +import ve.ucv.ciens.ccg.networkdata.MotorEvent.motor_t; +import ve.ucv.ciens.ccg.networkdata.MotorEventACK; import ve.ucv.ciens.ccg.nxtcam.robotcontrol.MotorEventQueue; import ve.ucv.ciens.ccg.nxtcam.utils.Logger; import ve.ucv.ciens.ccg.nxtcam.utils.ProjectConstants; @@ -18,6 +21,7 @@ public class MotorControlThread extends Thread { private MotorEventQueue queue; private boolean done; private ObjectInputStream reader; + private ObjectOutputStream writer; private boolean connected; public MotorControlThread(String serverIp){ @@ -30,15 +34,59 @@ public class MotorControlThread extends Thread { @Override public void run(){ - if(!connected){ + Object msg; + MotorEvent event; + MotorEventACK ack; + + if(!connectToServer()){ Logger.log_e(TAG, CLASS_NAME + ".run() :: The thread is not connected to a server. Finishing."); return; }else{ while(!done){ - Object msg = readMessage(); - MotorEvent event = verifyMessage(msg); - if(event != null) + // Receive a message and enqueue it; + msg = readMessage(); + event = verifyMessage(msg); + if(event != null){ queue.addEvent(event); + Logger.log_i(TAG, CLASS_NAME + ".run() :: Motor control message enqueued."); + Logger.log_i(TAG, CLASS_NAME + ".run() :: Motor ID: " + (event.getMotor() == motor_t.MOTOR_A ? "MOTOR_A" : "MOTOR_C")); + Logger.log_i(TAG, CLASS_NAME + ".run() :: Motor power: " + Byte.toString(event.getPower())); + }else{ + Logger.log_i(TAG, CLASS_NAME + ".run() :: Message could not be verified;"); + } + + // Send corresponding ack; + ack = new MotorEventACK(queue.getSize() >= 10); + try{ + writer.writeObject(ack); + Logger.log_i(TAG, CLASS_NAME + ".run() :: First ACK sent."); + }catch(Exception ex){ + Logger.log_e(TAG, CLASS_NAME + ".run() :: Exception while sending first ACK: " + ex.getMessage()); + break; + } + + if(ack.isClientQueueFull()){ + while(queue.getSize() >= 10){ } + + ack = new MotorEventACK(false); + + try{ + writer.writeObject(ack); + }catch(Exception ex){ + Logger.log_i(TAG, CLASS_NAME + ".run() :: Second ACK sent."); + Logger.log_e(TAG, CLASS_NAME + ".run() :: Exception while sending second ACK: " + ex.getMessage()); + break; + } + } + + event = null; + ack = null; + msg = null; + } + try{ + socket.close(); + }catch(IOException io){ + Logger.log_e(TAG, CLASS_NAME + ".run() :: IOException while closing socket: " + io.getMessage()); } } } @@ -49,8 +97,9 @@ public class MotorControlThread extends Thread { public boolean connectToServer(){ try{ - socket = new Socket(serverIp, ProjectConstants.SERVER_TCP_PORT_3); + socket = new Socket(serverIp, ProjectConstants.MOTOR_CONTROL_PORT); reader = new ObjectInputStream(socket.getInputStream()); + writer = new ObjectOutputStream(socket.getOutputStream()); connected = true; }catch(IOException io){ Logger.log_e(TAG, CLASS_NAME + ".connectToServer() :: IOException caught: " + io.getMessage()); @@ -63,6 +112,7 @@ public class MotorControlThread extends Thread { Object message; try{ message = reader.readObject(); + Logger.log_i(TAG, CLASS_NAME + ".readMessage() :: Motor control message received."); }catch(ClassNotFoundException cn){ Logger.log_e(TAG, CLASS_NAME + ".readMessage() :: ClassNotFoundException caught: " + cn.getMessage()); message = null; @@ -75,6 +125,7 @@ public class MotorControlThread extends Thread { private MotorEvent verifyMessage(Object message){ if(message != null && message instanceof MotorEvent){ + Logger.log_i(TAG, CLASS_NAME + ".verifyMessage() :: Valid motor control message received."); return (MotorEvent)message; }else{ return null; diff --git a/src/ve/ucv/ciens/ccg/nxtcam/network/SensorReportThread.java b/src/ve/ucv/ciens/ccg/nxtcam/network/SensorReportThread.java index 4374b23..ec33ef8 100644 --- a/src/ve/ucv/ciens/ccg/nxtcam/network/SensorReportThread.java +++ b/src/ve/ucv/ciens/ccg/nxtcam/network/SensorReportThread.java @@ -36,7 +36,7 @@ public class SensorReportThread extends Thread{ public boolean connectToServer(){ boolean connected; try{ - socket = new Socket(serverIp, ProjectConstants.SERVER_TCP_PORT_3); + socket = new Socket(serverIp, ProjectConstants.SENSOR_REPORT_PORT); writer = new ObjectOutputStream(socket.getOutputStream()); connected = true; }catch(IOException io){ diff --git a/src/ve/ucv/ciens/ccg/nxtcam/network/VideoStreamingThread.java b/src/ve/ucv/ciens/ccg/nxtcam/network/VideoStreamingThread.java index 719189e..4c8c90f 100644 --- a/src/ve/ucv/ciens/ccg/nxtcam/network/VideoStreamingThread.java +++ b/src/ve/ucv/ciens/ccg/nxtcam/network/VideoStreamingThread.java @@ -260,10 +260,10 @@ public class VideoStreamingThread extends Thread{ size = int2ByteArray(bufferSize); try{ - packet = new DatagramPacket(size, 4, InetAddress.getByName(serverIp), ProjectConstants.SERVER_TCP_PORT_1); + packet = new DatagramPacket(size, 4, InetAddress.getByName(serverIp), ProjectConstants.VIDEO_STREAMING_PORT); udpSocket.send(packet); - packet = new DatagramPacket(buffer, buffer.length, InetAddress.getByName(serverIp), ProjectConstants.SERVER_TCP_PORT_1); + packet = new DatagramPacket(buffer, buffer.length, InetAddress.getByName(serverIp), ProjectConstants.VIDEO_STREAMING_PORT); udpSocket.send(packet); }catch(UnknownHostException uo){ @@ -323,7 +323,7 @@ public class VideoStreamingThread extends Thread{ private void connectToServer(){ try{ Logger.log_i(TAG, CLASS_NAME + ".connectToServer() :: Connecting to the server at " + serverIp); - socket = new Socket(InetAddress.getByName(serverIp), ProjectConstants.SERVER_TCP_PORT_1); + socket = new Socket(InetAddress.getByName(serverIp), ProjectConstants.VIDEO_STREAMING_PORT); /*writer = new ObjectOutputStream(socket.getOutputStream()); reader = new ObjectInputStream(socket.getInputStream());*/ Logger.log_i(TAG, CLASS_NAME + ".connectToServer() :: Connection successful."); diff --git a/src/ve/ucv/ciens/ccg/nxtcam/robotcontrol/MotorEventQueue.java b/src/ve/ucv/ciens/ccg/nxtcam/robotcontrol/MotorEventQueue.java index 8bc0cde..2e77cce 100644 --- a/src/ve/ucv/ciens/ccg/nxtcam/robotcontrol/MotorEventQueue.java +++ b/src/ve/ucv/ciens/ccg/nxtcam/robotcontrol/MotorEventQueue.java @@ -54,4 +54,8 @@ public class MotorEventQueue { motorEvents.add(event); notifyAll(); } + + public synchronized int getSize(){ + return motorEvents.size(); + } } diff --git a/src/ve/ucv/ciens/ccg/nxtcam/utils/ProjectConstants.java b/src/ve/ucv/ciens/ccg/nxtcam/utils/ProjectConstants.java index 1193c0e..d86dd31 100644 --- a/src/ve/ucv/ciens/ccg/nxtcam/utils/ProjectConstants.java +++ b/src/ve/ucv/ciens/ccg/nxtcam/utils/ProjectConstants.java @@ -21,10 +21,12 @@ import android.app.Activity; public abstract class ProjectConstants { // Network related constants. - public static final int SERVER_UDP_PORT = 8889; - public static final int SERVER_TCP_PORT_1 = 9989; - public static final int SERVER_TCP_PORT_2 = 9990; - public static final int SERVER_TCP_PORT_3 = 9991; + public static final int SERVICE_DISCOVERY_PORT = 9988; + public static final int VIDEO_STREAMING_PORT = 9989; + public static final int MOTOR_CONTROL_PORT = 9990; + public static final int SENSOR_REPORT_PORT = 9991; + public static final int APP_CONTROL_PORT = 9992; + public static final UUID SERIAL_PORT_SERVICE_CLASS_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); public static final String OUI_LEGO = "00:16:53"; public static final String MULTICAST_ADDRESS = "230.0.0.1";