From aff56cc8bdae15b52d0c599385b19c4c378e62b7 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 31 Mar 2014 11:47:46 -0430 Subject: [PATCH 1/6] Testing full duplex BT communications. --- src/ve/ucv/ciens/ccg/nxtarbot/NxtAR_bot.java | 42 ++++++++++++++-- .../ciens/ccg/nxtarbot/threads/CommRecv.java | 42 ++++++++++++++++ .../ciens/ccg/nxtarbot/threads/CommSend.java | 50 +++++++++++++++++++ 3 files changed, 131 insertions(+), 3 deletions(-) create mode 100644 src/ve/ucv/ciens/ccg/nxtarbot/threads/CommRecv.java create mode 100644 src/ve/ucv/ciens/ccg/nxtarbot/threads/CommSend.java diff --git a/src/ve/ucv/ciens/ccg/nxtarbot/NxtAR_bot.java b/src/ve/ucv/ciens/ccg/nxtarbot/NxtAR_bot.java index 81b0cb6..6568c2a 100644 --- a/src/ve/ucv/ciens/ccg/nxtarbot/NxtAR_bot.java +++ b/src/ve/ucv/ciens/ccg/nxtarbot/NxtAR_bot.java @@ -15,11 +15,47 @@ */ package ve.ucv.ciens.ccg.nxtarbot; -import lejos.nxt.Button; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import lejos.nxt.comm.Bluetooth; +import lejos.nxt.comm.NXTConnection; +import ve.ucv.ciens.ccg.nxtarbot.threads.CommRecv; +import ve.ucv.ciens.ccg.nxtarbot.threads.CommSend; public class NxtAR_bot{ + private static DataOutputStream dataOutputStream; + private static DataInputStream dataInputStream; + private static NXTConnection bluetoothConnection; + private static CommRecv recv; + private static CommSend send; + public static void main(String[] args){ - System.out.println("Hello, world!"); - Button.waitForAnyPress(); + bluetoothConnection = Bluetooth.waitForConnection(); + bluetoothConnection.setIOMode(NXTConnection.RAW); + dataOutputStream = bluetoothConnection.openDataOutputStream(); + dataInputStream = bluetoothConnection.openDataInputStream(); + + System.out.println("Connected"); + + send = new CommSend(dataOutputStream); + recv = new CommRecv(dataInputStream); + + recv.start(); + send.start(); + + try{ + recv.join(); + send.join(); + }catch(InterruptedException i){ } + + try{ + dataOutputStream.close(); + dataInputStream.close(); + }catch(IOException io){ + System.out.println(io.getMessage()); + } + bluetoothConnection.close(); } } diff --git a/src/ve/ucv/ciens/ccg/nxtarbot/threads/CommRecv.java b/src/ve/ucv/ciens/ccg/nxtarbot/threads/CommRecv.java new file mode 100644 index 0000000..7813df5 --- /dev/null +++ b/src/ve/ucv/ciens/ccg/nxtarbot/threads/CommRecv.java @@ -0,0 +1,42 @@ +/* + * 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.nxtarbot.threads; + +import java.io.DataInputStream; +import java.io.IOException; + +public class CommRecv extends Thread { + private boolean done; + private byte msg; + private DataInputStream iStream; + + public CommRecv(DataInputStream iStream){ + done = false; + this.iStream = iStream; + } + + @Override + public void run(){ + while(!done){ + try{ + msg = iStream.readByte(); + System.out.println("Byte: " + Byte.toString(msg)); + }catch(IOException io){ + done = true; + } + } + } +} diff --git a/src/ve/ucv/ciens/ccg/nxtarbot/threads/CommSend.java b/src/ve/ucv/ciens/ccg/nxtarbot/threads/CommSend.java new file mode 100644 index 0000000..779ab07 --- /dev/null +++ b/src/ve/ucv/ciens/ccg/nxtarbot/threads/CommSend.java @@ -0,0 +1,50 @@ +/* + * 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.nxtarbot.threads; + +import java.io.DataOutputStream; +import java.io.IOException; + +import lejos.nxt.LightSensor; +import lejos.nxt.SensorPort; + +public class CommSend extends Thread { + private boolean done; + private byte msg; + private LightSensor light; + private DataOutputStream oStream; + + public CommSend(DataOutputStream oStream){ + light = new LightSensor(SensorPort.S1); + done = false; + msg = 0; + this.oStream = oStream; + } + + @Override + public void run(){ + while(!done){ + try{ + if((msg = (byte)light.getLightValue()) < 40){ + oStream.writeByte(msg); + oStream.flush(); + } + }catch(IOException io){ + done = true; + } + } + } +} From 0ebcbb3ce3841dc16e8220c0f21806637c11d0a0 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 1 Apr 2014 15:43:59 -0430 Subject: [PATCH 2/6] Added light sensor calibration and motor control. --- src/ve/ucv/ciens/ccg/nxtarbot/NxtAR_bot.java | 75 +++++++++++---- .../MotorMasks.java} | 32 ++----- .../nxtarbot/threads/MotorControlThread.java | 92 +++++++++++++++++++ ...{CommSend.java => SensorReportThread.java} | 29 +++--- 4 files changed, 174 insertions(+), 54 deletions(-) rename src/ve/ucv/ciens/ccg/nxtarbot/{threads/CommRecv.java => protocol/MotorMasks.java} (54%) create mode 100644 src/ve/ucv/ciens/ccg/nxtarbot/threads/MotorControlThread.java rename src/ve/ucv/ciens/ccg/nxtarbot/threads/{CommSend.java => SensorReportThread.java} (66%) diff --git a/src/ve/ucv/ciens/ccg/nxtarbot/NxtAR_bot.java b/src/ve/ucv/ciens/ccg/nxtarbot/NxtAR_bot.java index 6568c2a..834c601 100644 --- a/src/ve/ucv/ciens/ccg/nxtarbot/NxtAR_bot.java +++ b/src/ve/ucv/ciens/ccg/nxtarbot/NxtAR_bot.java @@ -19,19 +19,58 @@ import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; +import lejos.nxt.Button; +import lejos.nxt.ButtonListener; +import lejos.nxt.LightSensor; +import lejos.nxt.Motor; +import lejos.nxt.SensorPort; import lejos.nxt.comm.Bluetooth; import lejos.nxt.comm.NXTConnection; -import ve.ucv.ciens.ccg.nxtarbot.threads.CommRecv; -import ve.ucv.ciens.ccg.nxtarbot.threads.CommSend; +import ve.ucv.ciens.ccg.nxtarbot.threads.MotorControlThread; +import ve.ucv.ciens.ccg.nxtarbot.threads.SensorReportThread; public class NxtAR_bot{ private static DataOutputStream dataOutputStream; private static DataInputStream dataInputStream; private static NXTConnection bluetoothConnection; - private static CommRecv recv; - private static CommSend send; + private static MotorControlThread recvThread; + private static SensorReportThread sendThread; + + private static void quit(){ + if(recvThread != null) recvThread.finish(); + if(sendThread != null) sendThread.finish(); + + if(bluetoothConnection != null){ + try{ + dataOutputStream.close(); + dataInputStream.close(); + }catch(IOException io){ + System.out.println(io.getMessage()); + } + bluetoothConnection.close(); + } + } public static void main(String[] args){ + Motor.A.resetTachoCount(); + Motor.B.resetTachoCount(); + Motor.C.resetTachoCount(); + + LightSensor lightSensor = new LightSensor(SensorPort.S1); + lightSensor.setFloodlight(false); + + System.out.println("Point at dark and press ENTER"); + Button.ENTER.waitForPress(); + lightSensor.calibrateLow(); + System.out.println("--/--"); + + System.out.println("Point at light and press ENTER"); + Button.ENTER.waitForPress(); + lightSensor.calibrateHigh(); + System.out.println("--/--"); + + Button.ESCAPE.addButtonListener(new QuitButtonListener()); + bluetoothConnection = Bluetooth.waitForConnection(); bluetoothConnection.setIOMode(NXTConnection.RAW); dataOutputStream = bluetoothConnection.openDataOutputStream(); @@ -39,23 +78,27 @@ public class NxtAR_bot{ System.out.println("Connected"); - send = new CommSend(dataOutputStream); - recv = new CommRecv(dataInputStream); + sendThread = new SensorReportThread(dataOutputStream, lightSensor); + recvThread = new MotorControlThread(dataInputStream); - recv.start(); - send.start(); + recvThread.start(); + sendThread.start(); try{ - recv.join(); - send.join(); + recvThread.join(); + sendThread.join(); }catch(InterruptedException i){ } - try{ - dataOutputStream.close(); - dataInputStream.close(); - }catch(IOException io){ - System.out.println(io.getMessage()); + quit(); + } + + private static class QuitButtonListener implements ButtonListener{ + @Override + public void buttonPressed(Button b) { + quit(); } - bluetoothConnection.close(); + + @Override + public void buttonReleased(Button b){ } } } diff --git a/src/ve/ucv/ciens/ccg/nxtarbot/threads/CommRecv.java b/src/ve/ucv/ciens/ccg/nxtarbot/protocol/MotorMasks.java similarity index 54% rename from src/ve/ucv/ciens/ccg/nxtarbot/threads/CommRecv.java rename to src/ve/ucv/ciens/ccg/nxtarbot/protocol/MotorMasks.java index 7813df5..61c0b33 100644 --- a/src/ve/ucv/ciens/ccg/nxtarbot/threads/CommRecv.java +++ b/src/ve/ucv/ciens/ccg/nxtarbot/protocol/MotorMasks.java @@ -13,30 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package ve.ucv.ciens.ccg.nxtarbot.threads; +package ve.ucv.ciens.ccg.nxtarbot.protocol; -import java.io.DataInputStream; -import java.io.IOException; - -public class CommRecv extends Thread { - private boolean done; - private byte msg; - private DataInputStream iStream; - - public CommRecv(DataInputStream iStream){ - done = false; - this.iStream = iStream; - } - - @Override - public void run(){ - while(!done){ - try{ - msg = iStream.readByte(); - System.out.println("Byte: " + Byte.toString(msg)); - }catch(IOException io){ - done = true; - } - } - } +public abstract class MotorMasks { + public static final byte MOTOR_A = (byte)0x01; + public static final byte MOTOR_B = (byte)0x02; + public static final byte MOTOR_C = (byte)0x04; + public static final byte DIRECTION = (byte)0x08; + public static final byte RECENTER = (byte)0xF0; } diff --git a/src/ve/ucv/ciens/ccg/nxtarbot/threads/MotorControlThread.java b/src/ve/ucv/ciens/ccg/nxtarbot/threads/MotorControlThread.java new file mode 100644 index 0000000..c732522 --- /dev/null +++ b/src/ve/ucv/ciens/ccg/nxtarbot/threads/MotorControlThread.java @@ -0,0 +1,92 @@ +/* + * 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.nxtarbot.threads; + +import java.io.DataInputStream; +import java.io.IOException; + +import lejos.nxt.BasicMotorPort; +import lejos.nxt.Battery; +import lejos.nxt.Motor; +import ve.ucv.ciens.ccg.nxtarbot.protocol.MotorMasks; + +public class MotorControlThread extends Thread{ + private boolean done; + private DataInputStream inputStream; + + public MotorControlThread(DataInputStream inputStream){ + done = false; + this.inputStream = inputStream; + } + + public void finish(){ + done = true; + } + + @Override + public void run(){ + boolean motorA, motorB, motorC, recenterMotorB; + int direction, rotation, tacho; + byte[] message = new byte[2]; + + while(!done){ + try{ + message[0] = inputStream.readByte(); + message[1] = inputStream.readByte(); + + recenterMotorB = (message[0] & MotorMasks.RECENTER) > 0 ? true : false; + motorA = (message[0] & MotorMasks.MOTOR_A) > 0 ? true : false; + motorB = (message[0] & MotorMasks.MOTOR_B) > 0 ? true : false; + motorC = (message[0] & MotorMasks.MOTOR_C) > 0 ? true : false; + direction = (message[0] & MotorMasks.DIRECTION) > 0 ? BasicMotorPort.FORWARD : BasicMotorPort.BACKWARD; + + if(motorA){ + Motor.A.setSpeed(message[1] * Battery.getVoltage()); + if(direction == BasicMotorPort.FORWARD) + Motor.A.forward(); + else if(direction == BasicMotorPort.BACKWARD) + Motor.A.backward(); + } + + if(motorB){ + Motor.B.setSpeed(message[1] * Battery.getVoltage()); + if(direction == BasicMotorPort.FORWARD) + Motor.B.forward(); + else if(direction == BasicMotorPort.BACKWARD) + Motor.B.backward(); + } + + if(motorC){ + Motor.C.setSpeed(message[1] * Battery.getVoltage()); + if(direction == BasicMotorPort.FORWARD) + Motor.C.forward(); + else if(direction == BasicMotorPort.BACKWARD) + Motor.C.backward(); + } + + if(recenterMotorB){ + tacho = Motor.B.getTachoCount() % 360; + rotation = tacho > 180 ? 360 - tacho : -(tacho); + Motor.B.rotate(rotation); + Motor.B.resetTachoCount(); + } + + }catch(IOException io){ + done = true; + } + } + } +} diff --git a/src/ve/ucv/ciens/ccg/nxtarbot/threads/CommSend.java b/src/ve/ucv/ciens/ccg/nxtarbot/threads/SensorReportThread.java similarity index 66% rename from src/ve/ucv/ciens/ccg/nxtarbot/threads/CommSend.java rename to src/ve/ucv/ciens/ccg/nxtarbot/threads/SensorReportThread.java index 779ab07..c3e48c8 100644 --- a/src/ve/ucv/ciens/ccg/nxtarbot/threads/CommSend.java +++ b/src/ve/ucv/ciens/ccg/nxtarbot/threads/SensorReportThread.java @@ -19,29 +19,32 @@ import java.io.DataOutputStream; import java.io.IOException; import lejos.nxt.LightSensor; -import lejos.nxt.SensorPort; -public class CommSend extends Thread { +public class SensorReportThread extends Thread{ private boolean done; - private byte msg; - private LightSensor light; - private DataOutputStream oStream; + private LightSensor lightSensor; + private DataOutputStream outputStream; - public CommSend(DataOutputStream oStream){ - light = new LightSensor(SensorPort.S1); + public SensorReportThread(DataOutputStream outputStream, LightSensor lightSensor){ + this.lightSensor = lightSensor; done = false; - msg = 0; - this.oStream = oStream; + this.outputStream = outputStream; + } + + public void finish(){ + done = true; } @Override public void run(){ + byte message = 0; + while(!done){ try{ - if((msg = (byte)light.getLightValue()) < 40){ - oStream.writeByte(msg); - oStream.flush(); - } + message = (byte)lightSensor.getLightValue(); + outputStream.writeByte(message); + outputStream.flush(); + }catch(IOException io){ done = true; } From c4662c212757764a01884bf41c8526f472d45277 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 1 Apr 2014 16:00:55 -0430 Subject: [PATCH 3/6] Minor bugfixes when quitting. --- src/ve/ucv/ciens/ccg/nxtarbot/NxtAR_bot.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/ve/ucv/ciens/ccg/nxtarbot/NxtAR_bot.java b/src/ve/ucv/ciens/ccg/nxtarbot/NxtAR_bot.java index 834c601..89bd2ee 100644 --- a/src/ve/ucv/ciens/ccg/nxtarbot/NxtAR_bot.java +++ b/src/ve/ucv/ciens/ccg/nxtarbot/NxtAR_bot.java @@ -49,9 +49,13 @@ public class NxtAR_bot{ } bluetoothConnection.close(); } + + System.exit(0); } public static void main(String[] args){ + Button.ESCAPE.addButtonListener(new QuitButtonListener()); + Motor.A.resetTachoCount(); Motor.B.resetTachoCount(); Motor.C.resetTachoCount(); @@ -59,18 +63,16 @@ public class NxtAR_bot{ LightSensor lightSensor = new LightSensor(SensorPort.S1); lightSensor.setFloodlight(false); - System.out.println("Point at dark and press ENTER"); + System.out.println("Point at dark\nand press ENTER"); Button.ENTER.waitForPress(); lightSensor.calibrateLow(); System.out.println("--/--"); - System.out.println("Point at light and press ENTER"); + System.out.println("Point at light\nand press ENTER"); Button.ENTER.waitForPress(); lightSensor.calibrateHigh(); System.out.println("--/--"); - Button.ESCAPE.addButtonListener(new QuitButtonListener()); - bluetoothConnection = Bluetooth.waitForConnection(); bluetoothConnection.setIOMode(NXTConnection.RAW); dataOutputStream = bluetoothConnection.openDataOutputStream(); From f6737172d82b82f4b7b6c95652791aad12f25c76 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 1 Apr 2014 17:17:58 -0430 Subject: [PATCH 4/6] Added documentation. --- src/ve/ucv/ciens/ccg/nxtarbot/NxtAR_bot.java | 29 ++++++++++++++ .../nxtarbot/threads/MotorControlThread.java | 40 ++++++++++++++++++- .../nxtarbot/threads/SensorReportThread.java | 26 +++++++++++- 3 files changed, 92 insertions(+), 3 deletions(-) diff --git a/src/ve/ucv/ciens/ccg/nxtarbot/NxtAR_bot.java b/src/ve/ucv/ciens/ccg/nxtarbot/NxtAR_bot.java index 89bd2ee..638a535 100644 --- a/src/ve/ucv/ciens/ccg/nxtarbot/NxtAR_bot.java +++ b/src/ve/ucv/ciens/ccg/nxtarbot/NxtAR_bot.java @@ -29,6 +29,9 @@ import lejos.nxt.comm.NXTConnection; import ve.ucv.ciens.ccg.nxtarbot.threads.MotorControlThread; import ve.ucv.ciens.ccg.nxtarbot.threads.SensorReportThread; +/** + * Core class for the robot module of NxtAR. + */ public class NxtAR_bot{ private static DataOutputStream dataOutputStream; private static DataInputStream dataInputStream; @@ -36,6 +39,10 @@ public class NxtAR_bot{ private static MotorControlThread recvThread; private static SensorReportThread sendThread; + /** + *

Finishes the communication threads anc closes the Bluetooth data streams, + * then quits the application.

+ */ private static void quit(){ if(recvThread != null) recvThread.finish(); if(sendThread != null) sendThread.finish(); @@ -53,13 +60,23 @@ public class NxtAR_bot{ System.exit(0); } + /** + *

Application entry point.

+ *

Resets the motors, calibrates the light sensor and starts the + * networking threads.

+ * + * @param args Command line arguments. + */ public static void main(String[] args){ + // Set a listener to force quit if the ESCAPE button is pressed. Button.ESCAPE.addButtonListener(new QuitButtonListener()); + // Reset the rotation counts of the motors. Motor.A.resetTachoCount(); Motor.B.resetTachoCount(); Motor.C.resetTachoCount(); + // Start the light sensor and calibrate it. LightSensor lightSensor = new LightSensor(SensorPort.S1); lightSensor.setFloodlight(false); @@ -73,6 +90,8 @@ public class NxtAR_bot{ lightSensor.calibrateHigh(); System.out.println("--/--"); + // Connect with a Bluetooth device in raw mode. Then get the connection + // streams. bluetoothConnection = Bluetooth.waitForConnection(); bluetoothConnection.setIOMode(NXTConnection.RAW); dataOutputStream = bluetoothConnection.openDataOutputStream(); @@ -80,6 +99,7 @@ public class NxtAR_bot{ System.out.println("Connected"); + // Start the networking threads and wait for them to finish. sendThread = new SensorReportThread(dataOutputStream, lightSensor); recvThread = new MotorControlThread(dataInputStream); @@ -94,12 +114,21 @@ public class NxtAR_bot{ quit(); } + /** + *

Force quit button listener.

+ */ private static class QuitButtonListener implements ButtonListener{ + /** + * Force quit. + */ @Override public void buttonPressed(Button b) { quit(); } + /** + * Do nothing. + */ @Override public void buttonReleased(Button b){ } } diff --git a/src/ve/ucv/ciens/ccg/nxtarbot/threads/MotorControlThread.java b/src/ve/ucv/ciens/ccg/nxtarbot/threads/MotorControlThread.java index c732522..046a46a 100644 --- a/src/ve/ucv/ciens/ccg/nxtarbot/threads/MotorControlThread.java +++ b/src/ve/ucv/ciens/ccg/nxtarbot/threads/MotorControlThread.java @@ -23,19 +23,49 @@ import lejos.nxt.Battery; import lejos.nxt.Motor; import ve.ucv.ciens.ccg.nxtarbot.protocol.MotorMasks; +/** + *

Class to control the motors on the robot based on isntructions received via + * Bluetooth.

+ * + *

The instructions are codified on a very simple protocol:

+ *

    + *
  • Every protocol packet is exactly two bytes long.
  • + *
  • The lowest order byte codifies the motor to control and the rotation + * direction of the same on it's highest four bits. The lower four bits + * indicate that the central motor should return to it's position of + * origin. This four bits can also be used for future expansions. + *
  • The highest order byte, a number between 0 and 100, contains the + * power to send to the motor.
  • + *
+ */ public class MotorControlThread extends Thread{ private boolean done; private DataInputStream inputStream; - public MotorControlThread(DataInputStream inputStream){ + /** + * Create a new MotorControlThread. + * + * @param inputStream The stream to receive motor commands from. + * @throws NullPointerException If inputStream is null. + */ + public MotorControlThread(DataInputStream inputStream) throws NullPointerException{ + if(inputStream == null) + throw new NullPointerException("Input stream is null."); + done = false; this.inputStream = inputStream; } + /** + *

Marks this thread as ready to finish cleanly.

+ */ public void finish(){ done = true; } + /** + *

Receive and process motor control instructions via Bluetooth.

+ */ @Override public void run(){ boolean motorA, motorB, motorC, recenterMotorB; @@ -44,9 +74,11 @@ public class MotorControlThread extends Thread{ while(!done){ try{ + // Read the two bytes indicated by the protocol. message[0] = inputStream.readByte(); message[1] = inputStream.readByte(); + // Decode the instruction parameters. recenterMotorB = (message[0] & MotorMasks.RECENTER) > 0 ? true : false; motorA = (message[0] & MotorMasks.MOTOR_A) > 0 ? true : false; motorB = (message[0] & MotorMasks.MOTOR_B) > 0 ? true : false; @@ -54,6 +86,7 @@ public class MotorControlThread extends Thread{ direction = (message[0] & MotorMasks.DIRECTION) > 0 ? BasicMotorPort.FORWARD : BasicMotorPort.BACKWARD; if(motorA){ + // Set motor A to run at specified speed. Motor.A.setSpeed(message[1] * Battery.getVoltage()); if(direction == BasicMotorPort.FORWARD) Motor.A.forward(); @@ -62,6 +95,7 @@ public class MotorControlThread extends Thread{ } if(motorB){ + // Set motor B to run at specified speed. Motor.B.setSpeed(message[1] * Battery.getVoltage()); if(direction == BasicMotorPort.FORWARD) Motor.B.forward(); @@ -70,6 +104,7 @@ public class MotorControlThread extends Thread{ } if(motorC){ + // Set motor C to run at specified speed. Motor.C.setSpeed(message[1] * Battery.getVoltage()); if(direction == BasicMotorPort.FORWARD) Motor.C.forward(); @@ -78,6 +113,8 @@ public class MotorControlThread extends Thread{ } if(recenterMotorB){ + // Return motor B to it's origin. Rotate in the direction + // that implies less movement. tacho = Motor.B.getTachoCount() % 360; rotation = tacho > 180 ? 360 - tacho : -(tacho); Motor.B.rotate(rotation); @@ -85,6 +122,7 @@ public class MotorControlThread extends Thread{ } }catch(IOException io){ + // If disconnection terminate. done = true; } } diff --git a/src/ve/ucv/ciens/ccg/nxtarbot/threads/SensorReportThread.java b/src/ve/ucv/ciens/ccg/nxtarbot/threads/SensorReportThread.java index c3e48c8..bb31c08 100644 --- a/src/ve/ucv/ciens/ccg/nxtarbot/threads/SensorReportThread.java +++ b/src/ve/ucv/ciens/ccg/nxtarbot/threads/SensorReportThread.java @@ -20,21 +20,43 @@ import java.io.IOException; import lejos.nxt.LightSensor; +/** + *

Class to report the values read from the different sensors through a + * Bluetooth stream.

+ */ public class SensorReportThread extends Thread{ private boolean done; private LightSensor lightSensor; private DataOutputStream outputStream; - public SensorReportThread(DataOutputStream outputStream, LightSensor lightSensor){ + /** + *

Create a new SensorReportThread.

+ * + * @param outputStream The stream to send the data to. + * @param lightSensor An initialized and calibrated light sensor. + */ + public SensorReportThread(DataOutputStream outputStream, LightSensor lightSensor) throws NullPointerException{ + if(outputStream == null) + throw new NullPointerException("Output stream is null."); + + if(lightSensor == null) + throw new NullPointerException("Sensor is null."); + this.lightSensor = lightSensor; done = false; this.outputStream = outputStream; } + /** + *

Marks this thread as ready to finish cleanly.

+ */ public void finish(){ done = true; } + /** + *

Writes the values read from the light sensor to the output stream.

+ */ @Override public void run(){ byte message = 0; @@ -44,8 +66,8 @@ public class SensorReportThread extends Thread{ message = (byte)lightSensor.getLightValue(); outputStream.writeByte(message); outputStream.flush(); - }catch(IOException io){ + // If disconnection terminate. done = true; } } From 1481ebe3493d6225e50b74c16c010d77e08633ba Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 3 Apr 2014 08:49:08 -0430 Subject: [PATCH 5/6] Added missing documentation. --- .../ccg/nxtarbot/protocol/MotorMasks.java | 18 +++++++++++++----- .../nxtarbot/threads/MotorControlThread.java | 2 +- .../nxtarbot/threads/SensorReportThread.java | 2 +- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/ve/ucv/ciens/ccg/nxtarbot/protocol/MotorMasks.java b/src/ve/ucv/ciens/ccg/nxtarbot/protocol/MotorMasks.java index 61c0b33..505f301 100644 --- a/src/ve/ucv/ciens/ccg/nxtarbot/protocol/MotorMasks.java +++ b/src/ve/ucv/ciens/ccg/nxtarbot/protocol/MotorMasks.java @@ -15,10 +15,18 @@ */ package ve.ucv.ciens.ccg.nxtarbot.protocol; +/** + *

Bit masks used to code/decode the control instructions sent by NxtAR-cam to + * NxtAR-bot.

+ *

Expansions 1-3 are currently unused.

+ */ public abstract class MotorMasks { - public static final byte MOTOR_A = (byte)0x01; - public static final byte MOTOR_B = (byte)0x02; - public static final byte MOTOR_C = (byte)0x04; - public static final byte DIRECTION = (byte)0x08; - public static final byte RECENTER = (byte)0xF0; + public static final byte MOTOR_A = (byte)0x01; + public static final byte MOTOR_B = (byte)0x02; + public static final byte MOTOR_C = (byte)0x04; + public static final byte DIRECTION = (byte)0x08; + public static final byte RECENTER = (byte)0x10; + public static final byte EXPANSION_1 = (byte)0x20; + public static final byte EXPANSION_2 = (byte)0x20; + public static final byte EXPANSION_3 = (byte)0x20; } diff --git a/src/ve/ucv/ciens/ccg/nxtarbot/threads/MotorControlThread.java b/src/ve/ucv/ciens/ccg/nxtarbot/threads/MotorControlThread.java index 046a46a..7d59a6d 100644 --- a/src/ve/ucv/ciens/ccg/nxtarbot/threads/MotorControlThread.java +++ b/src/ve/ucv/ciens/ccg/nxtarbot/threads/MotorControlThread.java @@ -122,7 +122,7 @@ public class MotorControlThread extends Thread{ } }catch(IOException io){ - // If disconnection terminate. + // On disconnection terminate. done = true; } } diff --git a/src/ve/ucv/ciens/ccg/nxtarbot/threads/SensorReportThread.java b/src/ve/ucv/ciens/ccg/nxtarbot/threads/SensorReportThread.java index bb31c08..0920e2b 100644 --- a/src/ve/ucv/ciens/ccg/nxtarbot/threads/SensorReportThread.java +++ b/src/ve/ucv/ciens/ccg/nxtarbot/threads/SensorReportThread.java @@ -67,7 +67,7 @@ public class SensorReportThread extends Thread{ outputStream.writeByte(message); outputStream.flush(); }catch(IOException io){ - // If disconnection terminate. + // On disconnection terminate. done = true; } } From 50278109eb74e2446293da2315c0069f21c9ae61 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 4 Apr 2014 10:32:29 -0430 Subject: [PATCH 6/6] Fixed some bugs when recentering the camera. --- src/ve/ucv/ciens/ccg/nxtarbot/NxtAR_bot.java | 5 +++-- .../ccg/nxtarbot/threads/MotorControlThread.java | 12 ++++++------ 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/ve/ucv/ciens/ccg/nxtarbot/NxtAR_bot.java b/src/ve/ucv/ciens/ccg/nxtarbot/NxtAR_bot.java index 638a535..51a1331 100644 --- a/src/ve/ucv/ciens/ccg/nxtarbot/NxtAR_bot.java +++ b/src/ve/ucv/ciens/ccg/nxtarbot/NxtAR_bot.java @@ -122,8 +122,9 @@ public class NxtAR_bot{ * Force quit. */ @Override - public void buttonPressed(Button b) { - quit(); + public void buttonPressed(Button b){ + System.exit(0); + //quit(); } /** diff --git a/src/ve/ucv/ciens/ccg/nxtarbot/threads/MotorControlThread.java b/src/ve/ucv/ciens/ccg/nxtarbot/threads/MotorControlThread.java index 7d59a6d..a6e4503 100644 --- a/src/ve/ucv/ciens/ccg/nxtarbot/threads/MotorControlThread.java +++ b/src/ve/ucv/ciens/ccg/nxtarbot/threads/MotorControlThread.java @@ -79,7 +79,7 @@ public class MotorControlThread extends Thread{ message[1] = inputStream.readByte(); // Decode the instruction parameters. - recenterMotorB = (message[0] & MotorMasks.RECENTER) > 0 ? true : false; + recenterMotorB = (message[0] & MotorMasks.RECENTER) > 0 ? true : false; motorA = (message[0] & MotorMasks.MOTOR_A) > 0 ? true : false; motorB = (message[0] & MotorMasks.MOTOR_B) > 0 ? true : false; motorC = (message[0] & MotorMasks.MOTOR_C) > 0 ? true : false; @@ -113,12 +113,12 @@ public class MotorControlThread extends Thread{ } if(recenterMotorB){ - // Return motor B to it's origin. Rotate in the direction - // that implies less movement. + System.out.println("RECENTER"); + // Return motor B to it's origin. + Motor.B.setSpeed(50 * Battery.getVoltage()); tacho = Motor.B.getTachoCount() % 360; - rotation = tacho > 180 ? 360 - tacho : -(tacho); - Motor.B.rotate(rotation); - Motor.B.resetTachoCount(); + rotation = -(tacho); + Motor.B.rotate(rotation, false); } }catch(IOException io){