/* Author: Jason Johns, Sallie Hutchinson
* Project: COS 399 Line Follower 1
* Date: 1-23-2013
* Description:
* This class executes the requirements for the Line Follower 1 project
* for COS 399 Robotics using the Lejos API.
*
* Final Solution for Project 1
*
*/
package com.cos399.LineFollower;
import lejos.nxt.*;
import lejos.robotics.subsumption.*;
import lejos.robotics.navigation.*;
import lejos.robotics.RegulatedMotor;
import lejos.util.PilotProps;
import java.lang.Math;
public class LineFollower {
public static void main(String[] args) throws Exception {
// Instanciate PilotProperties instance and save wheel diameter, track
// width, motor connections
final PilotProps pilotProperties = new PilotProps();
pilotProperties.loadPersistentValues();
float wheelDiameter = Float.parseFloat(pilotProperties.getProperty(
PilotProps.KEY_WHEELDIAMETER, "2.2"));
float trackWidth = Float.parseFloat(pilotProperties.getProperty(
PilotProps.KEY_TRACKWIDTH, "6.6875"));
RegulatedMotor leftMotor = PilotProps.getMotor(pilotProperties
.getProperty(PilotProps.KEY_LEFTMOTOR, "A"));
RegulatedMotor rightMotor = PilotProps.getMotor(pilotProperties
.getProperty(PilotProps.KEY_RIGHTMOTOR, "C"));
final RotateMoveController pilot = new DifferentialPilot(wheelDiameter,
trackWidth, leftMotor, rightMotor, false);
pilot.setRotateSpeed(180);
final LightSensor sensor = new LightSensor(SensorPort.S1);
final int threshold = 45;
// Takes control when the sensor sees the line
Behavior driveForward = new Behavior() {
@Override
public boolean takeControl() {
return sensor.readValue() <= threshold;
}
@Override
public void action() {
while (sensor.readValue() <= threshold) {
Thread.yield();
LCD.clearDisplay();
LCD.drawString("Sensor: " + sensor.readValue(), 1, 2);
pilot.forward();
}
}
@Override
public void suppress() {
pilot.stop();
}
};
// takes control when no line is visible
Behavior offLine = new Behavior() {
private boolean suppress = false;
@Override
public boolean takeControl() {
return sensor.readValue() > threshold;
}
@Override
public void suppress() {
suppress = true;
while (suppress)
Thread.yield();
}
@Override
public void action() {
// set initial sweep angle to hunt for new line
int sweepAngle = 10;
// indicator if robot should continue in one direction during
// turning
boolean sweep = false;
if (sensor.readValue() <= threshold) {
sweep = true;
sweepAngle = Math.abs(sweepAngle);
}
while (!suppress) {
pilot.rotate(sweepAngle, true);
while (!suppress && pilot.isMoving())
Thread.yield();
if (sensor.readValue() <= threshold) {
sweep = false;
sweepAngle = Math.abs(sweepAngle);
}
if (sweep)
sweepAngle *= 2;
else
sweepAngle *= -2;
LCD.clear();
LCD.drawString("SweepAngle: " + sweepAngle, 0, 0);
LCD.drawString("Sensor Value: " + sensor.readValue(), 0, 1);
}
pilot.stop();
suppress = false;
}
};
Behavior[] array = { offLine, driveForward };
LCD.drawString("Line Follower 1", 0, 1);
Button.waitForAnyPress();
(new Arbitrator(array)).start();
}
}