import java.io.DataInputStream;
import java.io.IOException;
// Lejos imports
import lejos.nxt.*;
import lejos.nxt.comm.*;
// Collect commands, write to screen
public class MainCtrlMTh {
//Defines the buttons
private static final Button button_left = Button.LEFT;
private static final Button button_right = Button.RIGHT;
private static final Button button_enter = Button.ENTER;
// Defines variables used for the managing bluetooth connection
private static BTConnection connection;
private static DataInputStream inputStream;
public static void main(String[] args) throws InterruptedException{
executionMenu();
}
//Aims to establish a conection over Bluetooth
private static void connect(){
writeToScreen("Trying to connect", 7);
// Wait until connected
connection = Bluetooth.waitForConnection();
writeToScreen("Connected", 7);
inputStream = connection.openDataInputStream();
writeToScreen("Connection Opened", 7);
}
//Handles collecting the messages from the server over Bluetooth
private static void collectMessage() throws InterruptedException{
boolean atend = false;
long numoftwos = 0;
long prevval = 0;
int messageno = 0;
while(atend == false){
try {
// Parse if there are any messages
long inlen = inputStream.available();
if((inlen>=4) && (inlen%4 == 0)){
writeToScreen("Got message no:"+Integer.toString(messageno),7);
if (inlen > 4){
inputStream.skip( ((int) (inlen / 4)) * 4);
}
int message = inputStream.readInt();
// Do specific action
if (message == 65535){
atend = true;
writeToScreen(Integer.toString(message),7);
} else if (message != 65535){
if (Movement.getThreadsRunning() == 0){
writeToScreen(Integer.toString(message),6);
parseMessage(message);
}
}
inputStream.close();
inputStream = connection.openDataInputStream();
} else {
writeToScreen("inlen = "+Long.toString(inlen),7);
if (prevval == inlen){
numoftwos++;
} else {
numoftwos = 0;
}
if (numoftwos > 30){
inputStream.close();
inputStream = connection.openDataInputStream();
}
prevval = inlen;
}
} catch (IOException e) {
writeToScreen("Error",7);
atend = true;
}
}
writeToScreen("Exit While",7);
}
//Parses integer messages
private static void parseMessage(int message){
int threadCount = 0;
int reset = message & 1;
int kick = (message >> 1) & 1;
int motor_dleft = (message >> 2) & 7;
int motor_dright = (message >> 5) & 7;
int motor_sleft = (message >> 8) & 7;
int motor_sright = (message >> 11) & 7;
Movement.setThreadsRunning(5);
Thread thread1 = new KickThread(kick);
Thread thread2 = new SteeringLeftThread(motor_sleft);
Thread thread3 = new SteeringRightThread(motor_sright);
Thread thread4 = new DriveLeftThread(motor_dleft);
Thread thread5 = new DriveRightThread(motor_dright);
thread1.start();
thread2.start();
thread3.start();
thread4.start();
thread5.start();
}
// Writes a message to the brick's screen on a particular line if valid
private static void writeToScreen(String message, int line){
if ((line >= 0)&&(line <=7)){
LCD.drawString(" ", 0, line);
LCD.drawString(message, 0, line);
LCD.refresh();
}
}
// Defines the function to provide the menu for choosing execution mode of the program
private static void executionMenu(){
int selectedchoice = 0;
int numchoices = 3;
boolean enterselected = false;
boolean haschanged = false;
writeToScreen("Select Execution Mode",0);
switch (selectedchoice){
case 0:
writeToScreen("1. Standard Exc.", 1);
break;
case 1:
writeToScreen("2. Test +BT", 1);
break;
case 2:
writeToScreen("3. Test -BT", 1);
break;
}
while (enterselected == false){
//enumerates the list item when the right button is pressed
if (button_right.isPressed()){
if(selectedchoice < (numchoices -1)){
++selectedchoice;
} else {
selectedchoice = 0;
}
haschanged = true;
}
//denumerates the list item when the left button is pressed
if (button_left.isPressed()){
if(selectedchoice > 0){
--selectedchoice;
} else {
selectedchoice = (numchoices - 1);
}
haschanged = true;
}
//deals with the enter key being pressed
if (button_enter.isPressed()){
enterselected = true;
}
//if the menu item has been changed this updates the screen
if (haschanged == true){
switch (selectedchoice){
case 0:
writeToScreen("1. Standard Exc.", 1);
break;
case 1:
writeToScreen("2. Test +BT", 1);
break;
case 2:
writeToScreen("3. Test -BT", 1);
break;
}
}
haschanged = false;
}
//executes the relevant routines based on selection
switch (selectedchoice){
case 0:
writeToScreen("1. Standard Exc.", 0);
writeToScreen("",1);
executeStandard();
break;
case 1:
writeToScreen("2. Test +BT", 0);
writeToScreen("",1);
executeTestPlusBT();
break;
case 2:
writeToScreen("3. Test -BT", 1);
writeToScreen("",1);
executeTestMinBT();
break;
}
}
// Standard execution path
private static void executeStandard(){
connect();
Movement.motor_right.resetTachoCount();
Movement.motor_left.resetTachoCount();
Movement.motor_right.regulateSpeed(true);
Movement.motor_left.regulateSpeed(true);
Movement.motor_left.resetTachoCount();
Movement.motor_right.resetTachoCount();
Movement.motor_right.smoothAcceleration(true);
Movement.motor_left.smoothAcceleration(true);
Movement.port_comlight.setPowerType(Movement.port_comlight.POWER_RCX9V);
try{
collectMessage();
} catch (InterruptedException e){
writeToScreen("Msg Col Interupt",7);
}
}
// Test execution with Bluetooth
private static void executeTestPlusBT(){
}
// Test execution without Bluetooth
private static void executeTestMinBT(){
}
}
class Movement {
//Defines the motors used for steering the right and left wheels
public static final Motor motor_left = Motor.A;
public static final Motor motor_right = Motor.B;
//Defines the motor used for the kicker
public static final Motor motor_kick = Motor.C;
//Defines the number of motor turns to wheel turns
public static final double rotConstant = 2.375;
//Defines the sensor port used to power the communication light
public static final SensorPort port_comlight = SensorPort.S1;
// Defines the variable used to make sure no two movement command combinations are executed at once
private static int threadsRunning = 0;
public static int getThreadsRunning(){
return threadsRunning;
}
public synchronized static void setThreadsRunning(int totalThreads){
if (threadsRunning == 0){
threadsRunning = totalThreads;
}
}
public synchronized static void decrementThreadsRunning(){
if (threadsRunning > 0){
threadsRunning--;
}
}
}
// Activate kicker
class KickThread extends Thread {
int control = 0;
public KickThread(int control) {
this.control = control;
}
public void run() {
if (control == 1){
Movement.motor_kick.setSpeed(900);
Movement.motor_kick.rotate(720);
Movement.decrementThreadsRunning();
} else {
Movement.decrementThreadsRunning();
}
}
}
class SteeringLeftThread extends Thread{
private int control = 0;
public SteeringLeftThread(int control){
this.control = control;
}
public void run(){
switch(control){
case 0:
Movement.motor_left.stop();
break;
case 4:
Movement.motor_left.stop();
break;
case 1:
Movement.motor_left.setSpeed(300);
Movement.motor_left.backward();
break;
case 2:
Movement.motor_left.setSpeed(600);
Movement.motor_left.backward();
break;
case 3:
Movement.motor_left.setSpeed(900);
Movement.motor_left.backward();
break;
case 5:
Movement.motor_left.setSpeed(300);
Movement.motor_left.forward();
break;
case 6:
Movement.motor_left.setSpeed(600);
Movement.motor_left.forward();
break;
case 7:
Movement.motor_left.setSpeed(900);
Movement.motor_left.forward();
break;
}
Movement.decrementThreadsRunning();
}
}
class SteeringRightThread extends Thread{
private int control = 0;
public SteeringRightThread(int control){
this.control = control;
}
public void run(){
switch (control){
case 0:
Movement.motor_right.stop();
break;
case 4:
Movement.motor_right.stop();
break;
case 1:
Movement.motor_right.setSpeed(300);
Movement.motor_right.backward();
break;
case 2:
Movement.motor_right.setSpeed(600);
Movement.motor_right.backward();
break;
case 3:
Movement.motor_right.setSpeed(900);
Movement.motor_right.backward();
break;
case 5:
Movement.motor_right.setSpeed(300);
Movement.motor_right.forward();
break;
case 6:
Movement.motor_right.setSpeed(600);
Movement.motor_right.forward();
break;
case 7:
Movement.motor_right.setSpeed(900);
Movement.motor_right.forward();
break;
}
Movement.decrementThreadsRunning();
}
}
class DriveLeftThread extends Thread {
private int control = 0;
public DriveLeftThread(int control) {
this.control = control;
}
public void run(){
switch(control){
case 0:
Movement.port_comlight.passivate();
break;
case 4:
Movement.port_comlight.passivate();
break;
case 1:
Movement.port_comlight.activate();
break;
case 2:
Movement.port_comlight.activate();
break;
case 3:
Movement.port_comlight.activate();
break;
case 5:
Movement.port_comlight.activate();
break;
case 6:
Movement.port_comlight.activate();
break;
case 7:
Movement.port_comlight.activate();
break;
}
Movement.decrementThreadsRunning();
}
}
class DriveRightThread extends Thread {
private int control = 0;
public DriveRightThread(int control) {
this.control = control;
}
public void run(){
switch(control){
case 0:
Movement.port_comlight.passivate();
break;
case 4:
Movement.port_comlight.passivate();
break;
case 1:
Movement.port_comlight.activate();
break;
case 2:
Movement.port_comlight.activate();
break;
case 3:
Movement.port_comlight.activate();
break;
case 5:
Movement.port_comlight.activate();
break;
case 6:
Movement.port_comlight.activate();
break;
case 7:
Movement.port_comlight.activate();
break;
}
Movement.decrementThreadsRunning();
}
}