import lejos.navigation.ZPilot;
import lejos.nxt.Motor;
import lejos.nxt.SensorPort;
import lejos.nxt.UltrasonicSensor;
import de.nordakademie.lejos.statemachine.AbstractState;
import de.nordakademie.lejos.statemachine.AbstractTransition;
import de.nordakademie.lejos.statemachine.EndState;
import de.nordakademie.lejos.statemachine.IState;
import de.nordakademie.lejos.statemachine.ITransition;
import de.nordakademie.lejos.statemachine.LCDChangeListener;
import de.nordakademie.lejos.statemachine.StateChangeListener;
import de.nordakademie.lejos.statemachine.Statemachine;
public class CatChaser extends Statemachine {
public CatChaser() {
this(null);
}
public CatChaser(Statemachine parent) {
super(parent);
setUpSonic.setImplicitTransitions(new ITransition[]{
new AbstractTransition(setUpSonic) {
public int getDelay() {
return 200;
}
}
});
welcomeDance.setImplicitTransitions(new ITransition[]{
new AbstractTransition(fullScanForCat) {
}
});
fullScanForCat.setImplicitTransitions(new ITransition[]{
new AbstractTransition(endState) {
public boolean guard() {
return min >= farAway;
}
}, new AbstractTransition(headToCat) {
}
});
headToCat.setImplicitTransitions(new ITransition[]{
new AbstractTransition(jumpAttack) {
public boolean guard() {
return dist < nearBy + 5;
}
public int getDelay() {
return 2500;
}
}, new AbstractTransition(endState) {
public boolean guard() {
return dist >= farAway;
}
}, new AbstractTransition(sneakApproach) {
}
});
sneakApproach.setTransitions(new ITransition[]{catDisappeared,
catNearBy});
closeScanForCat.setImplicitTransitions(new ITransition[]{
new AbstractTransition(headToCat) {
}
});
jumpAttack.setImplicitTransitions(new ITransition[]{
new AbstractTransition(closeScanForCat) {
}
});
jumpAttack.setTransitions(new ITransition[]{catDestroyed});
haHaHaHaHa.setImplicitTransitions(new ITransition[]{
new AbstractTransition(fullScanForCat) {
public int getDelay() {
return 1000;
}
}
});
setStartTransitions(new ITransition[]{new ITransition() {
final public boolean guard() {
return true;
}
final public IState getTarget() {
return setUpSonic;
}
final public int getDelay() {
return 100;
}
}, new ITransition() {
final public boolean guard() {
return true;
}
final public IState getTarget() {
return welcomeDance;
}
final public int getDelay() {
return 0;
}
}
});
}
/**
* Variables of the statemachine
*
**/
private int min = 255;
private int dist = 255;
private UltrasonicSensor sonic = new UltrasonicSensor(SensorPort.S4);
private ZPilot pilot = new ZPilot(5.3f, 11.5f, Motor.A, Motor.C);
private int farAway = 60;
private int nearBy = 10;
private int catHeading = 0;
/**
* Internal states of the statemachine including exit, excluding initial states
*
**/
public IState setUpSonic = new AbstractState(this) {
public void doMethod() throws InterruptedException {
dist = sonic.getDistance();
}
public void exitMethod() {
if (dist < min) {
min = dist;
catHeading = pilot.getAngle();
}
}
final public String getName() {
return "SetUpSonic";
}
};
public IState welcomeDance = new AbstractState(this) {
public void doMethod() throws InterruptedException {
pilot.rotate(180);
pilot.rotate(-180);
}
public void entryMethod() {
pilot.setSpeed(320);
}
final public String getName() {
return "WelcomeDance";
}
};
public IState fullScanForCat = new AbstractState(this) {
public void doMethod() throws InterruptedException {
pilot.setSpeed(150);
pilot.rotate(360);
}
public void entryMethod() {
pilot.resetTachoCount();
catHeading = 0;
min = 255;
}
final public String getName() {
return "FullScanForCat";
}
};
public IState endState = new EndState(this);
public IState headToCat = new AbstractState(this) {
private int fullTurn = 360;
public void doMethod() throws InterruptedException {
int sweep = pilot.getAngle() - catHeading;
if (sweep > 180)
sweep -= fullTurn;
pilot.rotate(-sweep);
Thread.sleep(200);
}
final public String getName() {
return "HeadToCat";
}
};
public IState sneakApproach = new AbstractState(this) {
public void doMethod() throws InterruptedException {
pilot.forward();
}
public void exitMethod() {
pilot.stop();
}
public void entryMethod() {
pilot.setSpeed(120);
}
final public String getName() {
return "SneakApproach";
}
};
public IState closeScanForCat = new AbstractState(this) {
public void doMethod() throws InterruptedException {
pilot.rotate(30);
pilot.rotate(-60);
}
public void entryMethod() {
pilot.resetTachoCount();
catHeading = 0;
min = 255;
}
final public String getName() {
return "CloseScanForCat";
}
};
public IState jumpAttack = new AbstractState(this) {
public void doMethod() throws InterruptedException {
pilot.travel(2 * nearBy);
}
public void exitMethod() {
pilot.stop();
}
public void entryMethod() {
pilot.setSpeed(600);
}
final public String getName() {
return "JumpAttack";
}
};
public IState haHaHaHaHa = new AbstractState(this) {
final public String getName() {
return "HaHaHaHaHa";
}
};
/**
* Transtions of the statemachine including transitions from start state
*
**/
public ITransition catDisappeared = new AbstractTransition(fullScanForCat) {
final public boolean guard() {
return dist > farAway;
}
final public static String NAME = "CatDisappeared";
};
public ITransition catNearBy = new AbstractTransition(closeScanForCat) {
final public boolean guard() {
return dist < nearBy;
}
final public static String NAME = "CatNearBy";
};
public ITransition catDestroyed = new AbstractTransition(haHaHaHaHa) {
final public boolean guard() {
return dist > farAway;
}
final public static String NAME = "CatDestroyed";
};
/**
* Set he Listeners thru the complete statemachine hierarchy
*
**/
public void setListener(StateChangeListener[] listeners) {
super.setListener(listeners);
}
/**
* Main method to make the statemachine startable from outside
*
**/
public static void main(String[] args) {
CatChaser catChaser = new CatChaser();
StateChangeListener[] allListeners = new StateChangeListener[]{new LCDChangeListener()};
catChaser.setListener(allListeners);
try {
catChaser.doMethod();
} catch (InterruptedException i) {
}
for (StateChangeListener l : allListeners) {
l.stop();
}
}
final public String getName() {
return "CatChaser";
}
}