1   package real;
2   
3   import interfaces.*;
4   
5   import josx.platform.rcx.*;
6   import java.util.*;
7   import josx.util.*;
8   
9   /**
10  * This class implements the simple commands provided by AbstractRobot with
11  * real lejos commands, allowing the simple commands to be run on the 
12  * real RCX.
13  *
14  * @author Graham Ritchie
15  */
16  public class RealRCX extends Thread implements AbstractRobot, SensorConstants
17  {
18          private int[] sensors;
19      public static int MOTOR_POWER;
20          private Controller controller1;
21          private Vector timerList = new  Vector();
22          private Vector lightList = new Vector();
23          private Vector toughList = new Vector();
24                  
25      public void run(){}
26      
27      /**
28      * Initialises necessary variables, and sets up sensors, currently fixed to:
29      *
30      * @param controller the Controller associated with this RCX 
31      */
32      public RealRCX(Controller controller)
33      {
34          MOTOR_POWER=2;
35          Motor.A.setPower(MOTOR_POWER);
36          Motor.B.setPower(MOTOR_POWER);
37          Motor.C.setPower(MOTOR_POWER);
38          
39          // set up sensors as specified in controller
40          sensors=controller.getSensors();
41                  controller1 = controller;
42          
43          if(sensors[0]==Controller.SENSOR_TYPE_LIGHT)
44          {
45              Sensor.S1.setTypeAndMode (SensorConstants.SENSOR_TYPE_LIGHT, SensorConstants.SENSOR_MODE_PCT);
46              //Sensor.S1.activate();
47                          Sensor.S1.addSensorListener(new LListener(controller1,1));
48          }
49          else if(sensors[0]==Controller.SENSOR_TYPE_TOUCH)
50          {
51              Sensor.S1.setTypeAndMode (SensorConstants.SENSOR_TYPE_TOUCH, SensorConstants.SENSOR_MODE_PCT);
52              //Sensor.S1.activate();
53                          Sensor.S1.addSensorListener(new SListener(controller1,1));
54          }
55          
56          if(sensors[1]==Controller.SENSOR_TYPE_LIGHT)
57          {
58              Sensor.S2.setTypeAndMode (SensorConstants.SENSOR_TYPE_LIGHT, SensorConstants.SENSOR_MODE_PCT);
59              //Sensor.S2.activate();
60                          Sensor.S2.addSensorListener(new LListener(controller1,2));
61          }
62          else if(sensors[1]==Controller.SENSOR_TYPE_TOUCH)
63          {
64              Sensor.S2.setTypeAndMode (SensorConstants.SENSOR_TYPE_TOUCH, SensorConstants.SENSOR_MODE_PCT);
65              //Sensor.S2.activate();
66                          Sensor.S2.addSensorListener(new SListener(controller1,2));
67          }
68          
69          if(sensors[2]==Controller.SENSOR_TYPE_LIGHT)
70          {
71              Sensor.S3.setTypeAndMode (SensorConstants.SENSOR_TYPE_LIGHT, SensorConstants.SENSOR_MODE_PCT);
72              //Sensor.S3.activate();
73                          Sensor.S3.addSensorListener(new LListener(controller1,3));
74          }
75          else if(sensors[2]==Controller.SENSOR_TYPE_TOUCH)
76          {
77              Sensor.S3.setTypeAndMode (SensorConstants.SENSOR_TYPE_TOUCH, SensorConstants.SENSOR_MODE_PCT);
78              //Sensor.S3.activate();
79                          Sensor.S3.addSensorListener(new SListener(controller1,3));
80          }
81                  
82                  
83      }
84          
85      /*******************************************************************
86                      Methods required by AbstractRobot
87      *******************************************************************/
88      
89          public void activate(){
90              Sensor.S1.activate();
91              Sensor.S2.activate();
92              Sensor.S3.activate();
93          }
94      /**
95      * Sets the robot moving forwards, this will continue until some other 
96      * method is called to stop it.
97      */
98      public void forward()
99      {
100         Motor.A.stop();
101         Motor.C.stop();
102 
103                 Motor.A.backward();
104         Motor.C.backward();
105     }
106     
107     /**
108     * Makes the robot move forwards for the given amount of time
109     *
110     * @param time the time in milliseconds
111     */
112     public void forward(int time)
113     {
114         Motor.A.stop();
115         Motor.C.stop();
116                 
117         Motor.A.backward();
118         Motor.C.backward();
119         try{sleep(time);}catch(Exception e){}
120         Motor.A.stop();
121         Motor.C.stop();
122     }
123     
124     /**
125     * Sets the robot moving backwards, this will continue until some other 
126     * method is called to stop it.
127     */
128     public void backward()
129     {
130             Motor.A.stop();
131         Motor.C.stop();
132 
133             Motor.A.forward();
134             Motor.C.forward();
135     }
136     
137     /**
138     * Makes the robot move backwards for the given amount of time
139     *
140     * @param time the time in milliseconds
141     */
142     public void backward(int time)
143     {
144             Motor.A.stop();
145             Motor.C.stop();
146             
147             Motor.A.forward();
148             Motor.C.forward();
149             try{sleep(time);}catch(Exception e){}
150             Motor.A.stop();
151             Motor.C.stop();
152     }
153     
154     /**
155     * Sets the robot spinning right, this will continue until some other 
156     * method is called to stop it.
157     */
158     public void right()
159     {
160         Motor.A.stop();
161         Motor.C.stop();
162                 
163         Motor.A.backward();
164         Motor.C.forward();
165     }
166     
167     /**
168     * Spins the robot right for the given amount of time
169     *
170     * @param time the time in milliseconds
171     */
172     public void right(int time)
173     {
174             Motor.A.stop();
175             Motor.C.stop();
176             
177             Motor.A.backward();
178             Motor.C.forward();
179             try{sleep(time);}catch(Exception e){}
180             Motor.A.stop();
181             Motor.C.stop();
182     }
183     
184     /**
185     * Sets the robot spinning left, this will continue until some other 
186     * method is called to stop it.
187     */
188     public void left()
189     {
190             Motor.A.stop();
191             Motor.C.stop();
192             
193             Motor.A.forward();
194             Motor.C.backward();
195     }
196     
197     /**
198     * Spins the robot left for the given amount of time
199     *
200     * @param time the time in milliseconds
201     */
202     public void left(int time)
203     {
204             Motor.A.stop();
205             Motor.C.stop();
206             
207             Motor.A.forward();
208             Motor.C.backward();
209             
210             try{sleep(time);}catch(Exception e){}
211             Motor.A.stop();
212             Motor.C.stop();
213     }
214         
215         /**
216     * Sets a single Motor moving, this will continue until some other 
217     * method is called to stop it
218         *
219     * @param motor the motor number (AbstractRobot.MOTOR_A or AbstractRobot.MOTOR_C);
220         * @param direction, the direction number (AbstractRobot.BACKWARDS or AbstractRobot.FORWARDS
221     */
222         public void singleMotor(int motor, int direction) {
223             Motor.A.stop();
224             Motor.C.stop();
225             
226             if(motor == this.MOTOR_A){
227                 if(direction == this.FORWARD) Motor.A.backward();
228                 else if(direction == this.BACKWARD) Motor.A.forward();
229             }
230             else if(motor == this.MOTOR_C){
231                 if(direction == this.FORWARD) Motor.C.backward();
232                 else if(direction == this.BACKWARD) Motor.C.forward();
233             }
234         }
235        
236          /**
237     * Sets a single Motor moving for the given amount of time
238     *
239     * @param motor the motor number (AbstractRobot.MOTOR_A or AbstractRobot.MOTOR_C);
240         * @param direction, the direction number (AbstractRobot.BACKWARDS or AbstractRobot.FORWARDS
241         * @param time the time in milliseconds 
242     */
243         public void singleMotor(int motor, int direction, int time) {
244             this.singleMotor(motor,direction);
245             try{sleep(time);}catch(Exception e){}
246             Motor.A.stop();
247             Motor.C.stop();
248         } 
249     
250     /**
251     * Stops all motors immediately
252     */
253     public void stopMoving()
254     {
255             Motor.A.stop();
256             Motor.C.stop();
257     }
258     
259     /**
260     * Makes the robot beep
261     */
262     public void beep()
263     {
264             Sound.beep();
265     }
266     
267     /**
268     * Get the current reading of this sensor
269     *
270     * @return the current value
271     */
272     public int getSensor1()
273     {
274         return Sensor.S1.readValue();
275     }
276     
277     /**
278     * Get the current reading of this sensor
279     *
280     * @return the current value
281     */
282     public int getSensor2()
283     {
284         return Sensor.S2.readValue();
285     }
286     
287     /**
288     * Get the current reading of this sensor
289     *
290     * @return the current value
291     */
292     public int getSensor3()
293     {
294         return Sensor.S3.readValue();
295     }
296         
297         /** Display numbers on the LCD
298          *
299          *Modified by: Simon Zienkiewicz
300          *
301          */
302         public void displayNumberLCD(int num) {
303             this.clearLCD();
304             LCD.showNumber(num);
305             LCD.refresh();
306         }
307         
308         /** Clears the display on the LCD
309          *
310          * Modified by: Simon Zienkiewicz
311          *
312          */
313         public void clearLCD() {
314             LCD.clear();
315         }        
316         
317         /**
318     * Display text on the LCD
319     *
320     * Modified by: Simon Zienkiewicz
321     */
322         public void displayTextLCD(String word) {
323             String newWord = word;
324             this.clearLCD();
325             TextLCD.print(newWord);
326         } 
327         
328         /**
329     * Sets the power of the motors for the robot
330         * Modified by: Simon Zienkiewicz
331     */
332         public void setMotorPower(int power){
333             
334             if(power >= 7){
335                 MOTOR_POWER=7;
336             }
337             else if(power<=0){
338                 MOTOR_POWER=0;
339             }
340             else{
341                 MOTOR_POWER=power;
342             }
343             
344             Motor.A.setPower(MOTOR_POWER);
345             Motor.B.setPower(MOTOR_POWER);
346             Motor.C.setPower(MOTOR_POWER);
347         }
348         
349         /**
350     * Gets the power of the motors for the robot
351         * Modified by: Simon Zienkiewicz
352         *
353         * @return the power of the motor 0-7
354     */
355         public int getMotorPower() {
356             return Motor.C.getPower();
357         }
358                 
359         /**
360     * Gets an array of boolean values for the touch sensors
361         * Modified by: Simon Zienkiewicz
362         *
363         * @return boolean values of the status of the sensors
364     */
365         public boolean[] getTouchSensorStatus() {
366             boolean[] touchStatus = new boolean[3];
367             
368             for(int a=0;a<3;a++){
369                 if(sensors[a]==Controller.SENSOR_TYPE_TOUCH){
370                     touchStatus[a]= Sensor.S2.readBooleanValue();
371                 }
372             }
373             return touchStatus;
374         }
375         
376         /**
377     * Gets the voltage of the RCX battery in MilliVolts
378         * Modified by: Simon Zienkiewicz
379         *
380         * @return int voltage in the battery of the RCX
381     */
382         public int getVoltage() {
383             return Battery.getVoltageMilliVolt();
384         }
385         
386         public int createTimer(int time) {
387             josx.util.Timer timer = new josx.util.Timer(time, new TListener(controller1,timerList.size()));
388             timerList.addElement(timer);
389             return timerList.indexOf(timer);
390         }
391         
392         public void startTimer(int num) {
393             try{((josx.util.Timer)timerList.elementAt(num)).start();} catch(Exception e){}
394         }
395         
396         public void stopTimer(int num) {
397             try{((josx.util.Timer)timerList.elementAt(num)).stop();} catch(Exception e){}
398         }
399         
400         public void stopAllTimers(){
401              for(int i=0;i<this.timerList.size();i++){
402                 ((josx.util.Timer)timerList.elementAt(i)).stop();
403             }
404         }
405         
406         public int getDelay(int num) {
407             try{return((josx.util.Timer)timerList.elementAt(num)).getDelay();} catch(Exception e){}
408             return 911;
409         }
410         
411         public void setDelay(int num, int time) {
412             try{((josx.util.Timer)timerList.elementAt(num)).setDelay(time);} catch(Exception e){}
413         }
414          
415         public void pause(int num) {
416             try{Thread.sleep(num);}
417             catch(Exception e){};
418         }
419         
420         /**
421     * Plays a sound
422         * Created by: Simon Zienkiewicz
423         *
424         * @param frequency, the sound frequency
425         * @param duration, the duration of the sound in milliseconds
426     */
427         public void playTune(int frequency, int duration) {
428             josx.platform.rcx.Sound.playTone(frequency, duration);
429          }
430         
431         //time listener
432         private class TListener implements TimerListener {
433   
434             private int index;
435             private Controller controller;
436             
437             public TListener(Controller c, int num){
438                 controller = c;
439                 index = num;
440             
441             }
442             public void timedOut() {
443                 controller.setTimerExecution(index);
444             }
445         }
446         
447         //sensor listener
448         private class SListener implements SensorListener {
449             
450             private int index;
451             private Controller controller;
452             
453             public SListener(Controller c,int i){
454                 controller = c;
455                 index = i;
456             }
457             public void stateChanged(Sensor aSource, int aOldValue, int aNewValue) {
458                 controller.touchSensorListener(index);
459             }
460         }
461         
462         private class LListener implements SensorListener {
463             
464             private int index;
465             private Controller controller;
466             
467             public LListener(Controller c,int i){
468                 controller = c;
469                 index = i;
470             }
471             public void stateChanged(Sensor aSource, int aOldValue, int aNewValue) {
472                 controller.lightSensorListener(index);
473             }
474         }
475         
476         
477 }
478