Using Lejos to program an FTC style robot

My mentor has tasked me along with a few other students to build an FTC style robot (tetrix build kit with an NXT brain) to show off to students in the area for recruiting. We no longer have an FTC team but we think its something simple that will spark people’s interests in robotics without having to lug our FRC bot around. The only problem is that we no longer have an active RobotC license and our mentor doesn’t think its worth it to purchase one and wants us to think outside of the box and challenge ourselves. I have decided to use the Lejos NXJ library for Java because it seems to suit our purposes and I think it will be good practice for myself and some newer members for this upcoming season. It seems simple enough to write an autonomous program but I was wondering if anybody could give me some help with writing a program for driver control using a joystick controller (Logitech F310 Gamepad) through bluetooth. Any help would be greatly appreciated even if its just about using Lejos in general and other helpful tips.

TL;DR: I need help to write a Lejos NXJ program using a joystick controller through bluetooth.

I did some Bluetooth control with LeJos and Lego robots I will try and dig up my code for you.

I know that there’s a lot of sample material you can essentially cut and paste on with the Bluetooth connections (as it can be somewhat code intensive but fairly redundant). For the joystick you could use a library like Jinput.

Here’s some simple code I rooted up from like 2 years ago. This was just an experiment to see how the Bluetooth worked. It allowed me to drive my robot with the WASD keys.

There is both computer (client) and robot (server) side code here:

ShooterClient.java


package control.client.shooterBot;

import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.DataOutputStream;

import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JTextPane;

import lejos.pc.comm.NXTConnector;

public class ShooterClient extends JFrame implements KeyListener {

	private static final long serialVersionUID = -1955110733792225783L;

	//COMMANDS
	public static final int 
		TURN_LEFT = 1,
		TURN_RIGHT = 2,
		FWD = 3,
		BWD = 4,
		SHOOT = 5,
		STOP = 6,
		STOPSHOOT = 7,
		TERMINATE = 99;
	
	//KEYBOARD INPUTS
	public static final int
		FORWARD = 87, //W
		BACKWARD = 83, //S
		LEFT = 65, //A
		RIGHT = 68, //D
		FIRE = 32, //SPACEBAR
		QUIT = 81; //Q
	
	boolean steerReleased = true;
	boolean driveReleased = true;
	
	NXTConnector bt;
	DataOutputStream out;
	
	JTextField text = new JTextField(15);
	
	public ShooterClient (String title) {
		
		super(title);
		
		this.setDefaultCloseOperation(EXIT_ON_CLOSE);
		this.setSize(500, 300);
		
		text.setEnabled(false);
		
		Container pane = this.getContentPane();
		pane.setLayout(new FlowLayout());
		pane.add(text);
		
		this.setVisible(true);
		
		bt = new NXTConnector();
		boolean connected = bt.connectTo("btspp://");
		
		if (!connected) {
			
			System.err.println("Failed to connect to NXT!");
			text.setText("Failed to connect to NXT!");
		} else {	
			out = new DataOutputStream(bt.getOutputStream());
			this.addKeyListener(this);
		}
	}
	
	public static void main(String] args) {
		
		new ShooterClient("Enter Commands");
	}
	
	public void keyTyped(KeyEvent e) {
		
		;
	}
	
	public void keyPressed(KeyEvent e) {
		
		switch (e.getKeyCode()) {
			
			case FORWARD:
				if (driveReleased) {
					giveCmd(FWD);
					text.setText("Forward");
					driveReleased= false;
				}
				break;
			
			case BACKWARD:
				if (driveReleased) {
					giveCmd(BWD);
					text.setText("Backward");
					driveReleased= false;
				}
				break;
			
			case LEFT:
				if (steerReleased) {
					giveCmd(TURN_LEFT);
					text.setText("Left");
					steerReleased= false;
				}
				break;
			
			case RIGHT:
				if (steerReleased) {
					giveCmd(TURN_RIGHT);
					text.setText("Right");
					steerReleased= false;
				}
				break;
			
			case FIRE:
				giveCmd(SHOOT);
				text.setText("Shoot");
				break;
		}
	}
	
	public void keyReleased(KeyEvent e) {
		
		switch (e.getKeyCode()) {
			
			case FORWARD:	
			case BACKWARD:
				giveCmd(STOP);
				driveReleased= true;
				text.setText("Stopped");
				break;
				
			case LEFT:
			case RIGHT:
				giveCmd(STOP);
				steerReleased= true;
				text.setText("Stopped");
				break;
				
			case FIRE:
				giveCmd(STOPSHOOT);
				text.setText("Stopped Shooting");
				break;
				
			case QUIT:
				giveCmd(TERMINATE);
				text.setText("Quitting");
				System.exit(1);
				break;
		}
	}
	
	public void giveCmd(int cmd) {
		try {
			
			out.writeInt(cmd);
			out.flush();
		
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}
}

ShooterServer.java


package control.server.shooterBot;

import java.io.DataInputStream;

import lejos.nxt.Motor;
import lejos.nxt.Sound;
import lejos.nxt.comm.Bluetooth;
import lejos.nxt.comm.NXTConnection;
import lejos.robotics.navigation.DifferentialPilot;

public class ShooterServer {
	
	//COMMANDS
	public static final int
		LEFT = 1,
		RIGHT = 2,
		FWD = 3,
		BWD = 4,
		SHOOT = 5,
		STOP = 6,
		STOPSHOOT = 7,
		QUIT = 99;
	
	public static boolean
		isLeft = false,
		isRight = false,
		isFwd = false,
		isBwd = false;
	
	private static double radius = 0;
	private static double distance = 0;
	
	public static DifferentialPilot robot;
	
	public static WaitForThread WFT;
	
	public static void main(String] args) {
		
		Motor.A.setSpeed(900);
		
		robot = new DifferentialPilot(3.8, 13.1, Motor.C, Motor.B, false);
		
		WFT = new WaitForThread();
		
		WFT.start();
		
		while(true) {
			
			System.out.println("Waiting for Connection...");
			NXTConnection bt = Bluetooth.waitForConnection();
			DataInputStream stream = bt.openDataInputStream();
			System.out.println("Connected");
			
			Sound.beepSequenceUp();
			
			int input = 0;
			
			do {
				try {
					
					input = stream.readInt();
					System.out.println("Command: "+input);
					
				} catch (Exception e) {
					;
				}
				
				giveCmd(input);
			} while(input != QUIT);
			
			try {
				
				stream.close();
				Thread.sleep(100);
				bt.close();
				
				Sound.beepSequence();
				
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	private static void giveCmd(int cmd) {
		
		switch (cmd) {
		
			case LEFT:
				robot.rotateLeft();
				break;
				
			case RIGHT:
				robot.rotateRight();
				break;
				
			case FWD:
				robot.forward();
				break;
				
			case BWD:
				robot.backward();
				break;
				
			case SHOOT:
				Motor.A.forward();
				break;
				
			case STOP:
				robot.stop();
				break;
				
			case STOPSHOOT:
				Motor.A.stop();
				break;
		}
	}
}

WaitForThread.java


package control.server.shooterBot;
import lejos.nxt.SensorPort;
import lejos.nxt.TouchSensor;
import lejos.nxt.UltrasonicSensor;

public class WaitForThread extends Thread {
	
	public TouchSensor TS;
	public UltrasonicSensor US;
	
	public WaitForThread() {
		
		TS = new TouchSensor(SensorPort.S2);
		US = new UltrasonicSensor(SensorPort.S4);
	}
	
	public void run() {
		
		try {
			sleep(500);
		} catch (InterruptedException e) {
			
			e.printStackTrace();
		}
		
		while (true) {
			
			if (TS.isPressed()) break;
		}
		
		System.exit(1);
	}
}

Thanks. This is really helpful. If anyone has any experience with JInput, tips for that would be helpful too. I considered using it but I didn’t know if there was any better option. I don’t have much experience using it but I think I can figure it out.

I’m glad this is helpful! I’m really glad I found these files. They were in some obscure location on my computer. XD

I suppose I could just Google it, but what is a Lejo?

Java for the LEGO Mindstorms controllers.

leJOS stands for Lego Java Operating System