HomeDigital EditionSys-Con RadioSearch Java Cd
Advanced Java AWT Book Reviews/Excerpts Client Server Corba Editorials Embedded Java Enterprise Java IDE's Industry Watch Integration Interviews Java Applet Java & Databases Java & Web Services Java Fundamentals Java Native Interface Java Servlets Java Beans J2ME Libraries .NET Object Orientation Observations/IMHO Product Reviews Scalability & Performance Security Server Side Source Code Straight Talking Swing Threads Using Java with others Wireless XML
 

"A Storm in a Coffee Cup"
Vol. 6, Issue 10, p. 82

	


Listing 1 

/** 
  * Controls a JCX with a light sensor and two motors to follow a line. 
  * The line follower has two guiding rules.  First if it crosses the line, 
  * it will change the direction to find the line again.  Second, 
  * if it doesn't cross the line after a specified amount of time, 
  * it is probably in error and will again flip to find the line. 
  */ 

package linefollower; 

import com.ajile.jcx.*; 
import com.ajile.components.OneShotTimer; 
import com.ajile.events.*; 

public class LineFollower implements TriggerEventListener { 
   // Create left hand side motor 
   Motor leftMotor = new Motor(Motor.MOTOR_PORT_0); 
   // Create right hand side motor 
   Motor rightMotor = new Motor(Motor.MOTOR_PORT_1); 
   // Create the light sensor 
   LightSensor lightSensor = new LightSensor(LightSensor.SENSOR_PORT_2); 
   // Create one shot timer 
   OneShotTimer timer = new OneShotTimer(); 

   // Indicates last turn direction. 
   public static final int LEFT = 0; 
   public static final int RIGHT = 1; 
   int direction = RIGHT; 

   /** 
    * Main entry point.  Creates one instance of this class 
    */ 
   public static void main(String[] args) { 
     LineFollower instance = new LineFollower(); 
   } 

   /** 
    * Initializes all JCX components and registers event handlers 
    */ 
   public LineFollower() { 

     // turn motors on 
     leftMotor.setState(Motor.MOTOR_FORWARD); 
     rightMotor.setState(Motor.MOTOR_FORWARD); 

     // initialize light sensor so on the line is in range (0-2000) 
     lightSensor.setLowerLimit(0); 
     lightSensor.setUpperLimit(1000); 

     // initialize the timer for a .5 second delay 
     timer.setIntervalMillis(500); 

     // register the flip triggerEvent method when a timeout occurs 
     timer.addTimerListener(this); 

     // use inner class to register the leavingLine method when the 
     // light sensor moves out of range 
     lightSensor.addOutOfRangeListener( new TriggerEventListener() { 
       public void triggerEvent() { 
         leavingLine(); 
       } 
     }); 

     // use inner class to register the enteringLine method when the 
     // light sensor moves in range 
     lightSensor.addInRangeListener( new TriggerEventListener() { 
       public void triggerEvent() { 
         enteringLine(); 
       } 
     }); 

   } 

   /** 
    * Called by the light sensor when light intensity 
    * increases past the upper threshold indicating that we 
    * are moving from dark to light. We lost a line. 
    */ 
   void leavingLine() { 
     // the line has been lost, so reverse turn 
     triggerEvent(); 
     // reset the timer in case line is not refound 
     timer.start(); 
   } 

   /** 
    * Called by the light sensor when light intensity 
    * decreases past the upper threshold indicating that we 
    * are moving from light to dark.  We found a line 
    */ 
   void enteringLine() { 
     // stop the timer 
     timer.stop(); 
     // Line found, move forward 
     leftMotor.setState(Motor.MOTOR_FORWARD); 
     rightMotor.setState(Motor.MOTOR_FORWARD); 
   } 

   /** 
    * Causes the JCX to turn in the opposite direction. 
    * If the JCX is presently going straght, this routine 
    * will still cause it to turn in the opposite direction 
    * as last time this routine was called. 
    */ 
   synchronized public void triggerEvent() { 
     if (direction == LEFT) { 
       direction = RIGHT; 
       leftMotor.setState(Motor.MOTOR_REVERSE); 
       rightMotor.setState(Motor.MOTOR_FORWARD); 
     } else { 
       direction = LEFT; 
       leftMotor.setState(Motor.MOTOR_FORWARD); 
       rightMotor.setState(Motor.MOTOR_REVERSE); 
     } 
   } 

} 

  
 
 

All Rights Reserved
Copyright ©  2004 SYS-CON Media, Inc.
  E-mail: [email protected]

Java and Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries. SYS-CON Publications, Inc. is independent of Sun Microsystems, Inc.