import josx.platform.rcx.*;
/**
* Classe principale.
* Questo programma d'esempio permette al robot di seguire una pista a gradiente.
* Il robot si ferma se incontra un ostacolo o se gli viene ordinato tramite il tasto RUN.
* Quando il robot è fermo accende la lampada.
* Per uscire premere il tasto PRGM.
* Commenti nel formato javadoc per produrre l'help del package/classe in HTML
* (Project --> "Generate Javadoc", specificare il percorso all'eseguibile javadoc.exe)
* e avere i tooltip dei metodi/campi entro il codice.
* @author Toni Greco
* @version 1.0 (15/04/2007)
*/
public class PathFinder implements ButtonListener {
/**
* Identificatore del pulsante RUN dell'RCX.
*/
public static final int BUTTON_RUN = 1;
/**
* Identificatore del pulsante PRGM dell'RCX.
*/
public static final int BUTTON_PRGM = 4;
/**
* Booleano che determina se al robot è concesso avanzare o meno.
*/
public boolean go = true;
/**
* Riferimento al sensore di luce anteriore.
*/
public Sensor forwardLight = Sensor.S1;
/**
* Metodo realtivi alla gestione dell'evento "Pressione" dei pulsanti dell'RCX.
* E' inutilizzato.
* @param b Riferimento al pulsante che ha generato l'evento.
*/
public void buttonPressed(Button b) {}
/**
* Metodo realtivi alla gestione dell'evento "Rilascio" dei pulsanti dell'RCX.
* @param b Riferimento al pulsante che ha generato l'evento.
*/
public void buttonReleased(Button b) {
if (b.getId()==BUTTON_RUN) {
go = !go; // Comando toggle.
if (go)
TextLCD.print("RUN ");
else
TextLCD.print("STOP ");
}
else if (b.getId()==BUTTON_PRGM) {
forwardLight.passivate(); // Spegne la luce del sensore.
System.exit(0); // Termina il programma.
}
}
/**
* Costruttore della classe.
*/
PathFinder(){
// Definizione di alcune delle variabili che faranno riferimento
// ai sensori e agli attuatori.
// Questa scelta permette di ottenere un codice più leggibile.
Sensor twoTouch = Sensor.S2;
//Sensor rightLight = Sensor.S3; // Non utilizzato in questo esempio.
Motor leftMotor = Motor.A;
Motor forwardLamp = Motor.B;
Motor rightMotor = Motor.C;
// Variabili locali ausiliarie (in questo esempio è solo una).
int forwardLightValue; // Intensità luminosa del sensore anteriore.
// Impostazione del tipo e della modalità di lavoro dei sensori.
// Per poterli utilizzare i sensori alimentati vengono anche attivati.
forwardLight.setTypeAndMode(SensorConstants.SENSOR_TYPE_LIGHT,
SensorConstants.SENSOR_MODE_PCT);
forwardLight.activate();
/*rightLight.setTypeAndMode(SensorConstants.SENSOR_TYPE_LIGHT,
SensorConstants.SENSOR_MODE_PCT);
rightLight.activate();*/
twoTouch.setTypeAndMode(SensorConstants.SENSOR_TYPE_TOUCH,
SensorConstants.SENSOR_MODE_RAW);
//twoTouch.activate(); // Non serve, è un sensore passivo.
// Verificare se cambia qualcosa nei valori letti!
// Imposta la potenza dei motori al massimo.
// Più che in questo caso è utile se si mantengono i motori costantemente in
// rotazione per un periodo di tempo superiore a quello necessario perché siano
// a regime.
leftMotor.setPower(7);
rightMotor.setPower(7);
// Aggiunge i Listener per due pulsanti dell'RCX.
Button.RUN.addButtonListener(this);
Button.PRGM.addButtonListener(this);
// Si parte...
LCD.clear(); // Elimina anche l'icona.
//LCD.refresh(); // Superfluo?
TextLCD.print("START");
Wait(1000);
TextLCD.print("RUN ");
//Ciclo del controllo in real-time.
while(true) {
// Se incontra un ostacolo o se l'utente ha impartito il comando di stop
// si ferma, altrimenti continua a seguire la pista.
if (twoTouch.readRawValue()<55 || !go) {
// Ferma il robot.
leftMotor.stop();
rightMotor.stop();
forwardLamp.forward(); // Accende la lampada.
Sound.beep(); // Beep a ripetizione :-).
}
else {
forwardLamp.stop(); // Spegne la lampada.
// Cerca di mantenere il gradiente più chiaro della pista alla
// propria destra.
// Se il verso del gradiente s'inverte (ad esempio girando di
// 180° il robot o per inversione della pista) vi sono tre possibilità:
// 1) Se il sensore è prevalentamente sulla banda più scura
// o all'esterno di essa il robot cercherà di restare sulla
// pista.
// 2) Se il sensore è prevalentamente sulla banda più chiara
// o all'esterno di essa il robot invertirà il senso di marcia.
// 3) Se il sensore è al centro della banda proseguirà in avanti
// fino al verificarsi del caso 1 o del caso 2.
//**************Calibrare per tutti i tipi di curve.**************
forwardLightValue = forwardLight.readValue(); // Rileva la luminosità della pista.
// Pista scura: gira a destra.
if (forwardLightValue<44) {
leftMotor.forward();
rightMotor.backward();
}
// Pista chiara (o fuori pista): gira a sinistra.
else if (forwardLightValue>49) {
leftMotor.backward();
rightMotor.forward();
}
// Pista entro il range: prosegue dritto.
else {
leftMotor.forward();
rightMotor.forward();
}
}
}
}
/**
* Metodo per fermare il programma (thread chiamante) per un periodo di tempo.
* @param time Tempo espresso in millisecondi.
*/
public void Wait(long time) {
// Thread.sleep(time); // Così lo si può utilizzare così solo nel main()!
try { Thread.sleep(time); } catch (InterruptedException ie) {}
}
/**
* Metodo di partenza del programma, in questo esempio si limita a creare la classe.
* @param arg Argomenti (sono inutilizzati, ma il parametro non può essere eliminato per leJOS).
* @throws Exception (le eccezioni non gestite in main sono lasciate alla gestione del chiamante,
* non è obbligatorio).
*/
public static void main (String[] arg) throws Exception {
new PathFinder();
}
}