Problems with Pilot and waitForPressAndRelease()

This is where you talk about the NXJ software itself, installation issues, and programming talk.

Moderators: 99jonathan, roger, imaqine

Problems with Pilot and waitForPressAndRelease()

Postby jkob » Mon Jan 28, 2008 9:09 am

Hi,

I encountered a problem with following code

Code: Select all
Pilot pilot = new Pilot(5.6f, 15.5f, Motor.C, Motor.A, true);

synchronized(this){
  pilot.forward();
  wait();
  pilot.stop();
  pilot.rotate(60);
}


which causes the robot to move forward for a while and to rotate but without stopping rotating. (BTW: notify() has been called in an EventListener)
I thought it was a problem with the Pilot class and started creating my own class until I run in the same error. But then I recognized that it seems to be a problem with the usage of Thread.yield(). Therefore, I replaced all Thread.yield() with Thread.sleep(80) in the Pilot class. Now it works as expected, but I'm not sure why and if there is a better way to deal with.

My second problem is the usage of waitForPressAndRelease(). I thought this method would wait until the button is pressed and released, but it seems press and release events are queued and the method will not wait if the button has already been pressed and released before. Is there a way to empty this queue before calling waitForPressAndRelease()?

Thanks and regards.
Jakob
Last edited by jkob on Tue Jan 29, 2008 2:12 pm, edited 1 time in total.
jkob
New User
 
Posts: 2
Joined: Mon Jan 28, 2008 8:42 am
Location: Hamburg

Postby jkob » Mon Jan 28, 2008 2:36 pm

Here is a full not working program.

Code: Select all
package nxj;

import lejos.nxt.*;
import lejos.navigation.*;

public class Main implements ButtonListener{
   
   private Pilot pilot;
   
   public static void main(String[] arg){
      Main m = new Main();
      m.doTask();
   }
   
   public void doTask(){
      pilot = new Pilot(5.6f, 15.5f, Motor.A, Motor.C, true);

      Button.RIGHT.addButtonListener(this);
      startAction();
      
      try {
         Button.LEFT.waitForPressAndRelease();
      } catch(Exception e){
      }
   } // doTask
   
   public void startAction() {
      pilot.forward();
   }   
   
   public void buttonAction() {
      pilot.stop();
      pilot.rotate(60);
   }

   public void buttonPressed(Button arg0) {
   }

   public void buttonReleased(Button arg0) {
      buttonAction();
   }
   
} // Main


Also interesting: the program doesn't terminate when left button gets pressed.
jkob
New User
 
Posts: 2
Joined: Mon Jan 28, 2008 8:42 am
Location: Hamburg

Postby roger » Wed Jan 30, 2008 1:07 am

Hi Jkob,
Sorry to be slow in getting back to you on this. After some testing, I find that the problem is not with the pilot class. It is in the interaction between the buttton listener thread and the motor regulator thread. As you know, pilot.rotate calls motor.rotate on both motors. This happens in the button listener thread, which blocks until both motors complete their rotations. For reasons I do not understand, the button listener thread while blocked prevents the motor regulator thread from detecting the end of rotation. Looks like a bug to me.

Your observation that your code worked when inserting Thread.sleep() in the pilot code was a useful clue. While the listener thread was sleeping, the motor regulator thread could do its job.

In general, the code that is executed within a listener thread should exit quickly, because blocking the listener thread is not usually a good idea.
Until we get this sorted out, use the button listener with care. Perhaps not al all.
Roger
roger
Moderator
 
Posts: 350
Joined: Fri Jun 01, 2007 4:31 am
Location: Berkeley, CA


Return to NXJ Software

Who is online

Users browsing this forum: 9guquaox, Baidu [Spider] and 1 guest

cron
more stuff