To LUGNET HomepageTo LUGNET News HomepageTo LUGNET Guide Homepage
 Help on Searching
 
Post new message to lugnet.robotics.rcx.nqcOpen lugnet.robotics.rcx.nqc in your NNTP NewsreaderTo LUGNET News Traffic PageSign In (Members)
 Robotics / RCX / NQC / 848
847  |  849
Subject: 
Re: Monitor() and Event()
Newsgroups: 
lugnet.robotics.rcx.nqc
Date: 
Thu, 26 Oct 2000 09:37:43 GMT
Viewed: 
2089 times
  
In lugnet.robotics.rcx.nqc, Camus Lai writes:
Can someone teach me more on Monitor() and Event()?

The "monitor" control structure (as well as "acquire") is a very useful
supplement of the existing control structures, such as  "if", "while", "until",
etc. Dave Baum already gave an example and with the following I also want to
point out a benefit of it: immediate interrupts.

Assume that a robot has 2 motors (OUT_A and OUT_C) and a touch sensor at
SENSOR_1. The task of it is to drive forward and backward 5 times, each
direction for 2 seconds:

repeat (5)
{
  OnFwd (OUT_A + OUT_C);
  Wait (200);
  OnRev (OUT_A + OUT_C);
  Wait (200);
}

Now, as soon as the touch sensor is pressed, the robot should stop  i m m e d i
a t e l y, play a sound and afterwards do something else (e.g. turning around
for 3 seconds).

One question is, where within the program sequence you check the touch sensor.
The true problem is the Wait (200) statement (i.e. the robot is moving) that
cannot be interrupted unless you use parallel working tasks.

This means that the essential action is done in a separate task (e.g. "drive"),
the main task starts this task, checks the sensor and stops the task and the
motors as soon as the touch sensor is pressed:

start drive;             // execute code for standard action
until (SENSOR_1 == 1);   // check, if SENSOR_1 pressed (Event 1)
{
  stop drive;            // if so, interrupt standard action
  Off (OUT_A + OUT_C);
  PlaySound (4);
  Wait (100);
}
// further code after complete standard action or handled interrupt
// ...


task drive ()            // code for standard action that can be interrupted
{
  repeat (5)
  {
    OnFwd (OUT_A + OUT_C);
    Wait (200);
    OnRev (OUT_A + OUT_C);
    Wait (200);
  }
}

This seems fine at a first glance and the driving is really interrupted
immediately when pressing the touch sensor 20 seconds after the robot started.
But if no pressing takes place, the program wouldn't continue to the further
code after doing the back and forward cycle.  It will stay at the "until"
statement. So we need a variable (e.g. continue_flag) that will be set to 1 if
the essential task is completed. This variable will be checked continously:

Int continue_flag = 0;
start drive;             // execute code for standard action
while (continue_flag == 0)
{
  if (SENSOR_1 == 1)       // check, if SENSOR_1 pressed (Event 1)
  {
    stop drive;            // if so, interrupt standard action
    Off (OUT_A + OUT_C);
    PlaySound (4);
    Wait (100);
  }
}
// further code after complete standard action or handled interrupt
// ...


task drive ()            // code for standard action that can be interrupted
{
  repeat (5)
  {
    OnFwd (OUT_A + OUT_C);
    Wait (200);
    OnRev (OUT_A + OUT_C);
    Wait (200);
  }
continue_flag = 1;       // standard action completed
}

The result of the above:

If a certain program sequence needs to be interrupted immediately,

- the sequence must be performed in an additional separate task
- you will need an additional variable.

Using the "monitor" statement will give you the following benefits:

- a more "structured" appearance of the code
- no addtional tasks
- no additional variables.

SetSensor (SENSOR_1, SENSOR_TOUCH);
SetEvent (1, SENSOR_1, EVENT_TYPE_PRESSED);
ClearSensor (SENSOR_1);

  monitor (EVENT_MASK (1))
  {
    repeat (5)
    {
      OnFwd (OUT_A + OUT_C);
      Wait (200);
      OnRev (OUT_A + OUT_C);
      Wait (200);
    }
  }
  catch
  {
    Off (OUT_A + OUT_C);
    PlaySound (4);
    Wait (100);
  }
// further code to be executed
// after interrupt or complete driving task

For convenience I put both programs which both do the same under this text. The
same considerations are also valid for the "acquire" statement. I hope that my
English was good enough to transport the essential ideas of the above. I also
posted a subject to Lugnet "True interrupts" where I tried to simulate the
behaviour of standard interrupts, i.e. after the interrupt was handled, the
program continues where it has been interrupted. In the above example that
would mean that the robot will complete his moving cycle. If it had been
interrupted at 1.2 seconds after starting to drive forward, it will handle the
interrupt and complete the movement (i.e. drive anotehr 0.8 seconds forward).

Bernd

// Program with immediate interrupt without "monitor"
//
int continue_flag = 0;

task main ()
{
  SetSensor (SENSOR_1, SENSOR_TOUCH);
  ClearSensor (SENSOR_1);

  start drive;                //execute code for standard action
  while (continue_flag == 0)
  {
    if (SENSOR_1 == 1)       // check, if SENSOR_1 pressed (Event 1)
    {
      stop drive;            // if so, interrupt standard action
      Off (OUT_A + OUT_C);
      PlaySound (4);
      Wait (100);
      continue_flag = 1;
    }
  }
// further code after complete standard action or handled interrupt
  OnFwd (OUT_A);
  OnRev (OUT_C);
  Wait (300);
  StopAllTasks ();
}

task drive ()                // code for standard action that can be
interrupted
{
  repeat (5)
  {
    OnFwd (OUT_A + OUT_C);
    Wait (200);
    OnRev (OUT_A + OUT_C);
    Wait (200);
  }
  continue_flag = 1;        // standard action completed
}

--------------------------
// the same with "monitor"
//
  SetSensor (SENSOR_1, SENSOR_TOUCH);
  SetEvent (1, SENSOR_1, EVENT_TYPE_PRESSED);

  ClearSensor (SENSOR_1);

  monitor (EVENT_MASK (1))
  { // code for standard action,       //
    // will be interrupted immediately //
    // when event happens              //
    repeat (5)                         //
    {                                  //
      OnFwd (OUT_A + OUT_C);           //
      Wait (200);                      //
      OnRev (OUT_A + OUT_C);           //
      Wait (200);                      //
    }                                  //
  }//----------------------------------//
  catch
  { // code for event situation,       //
    // will be executed immediately    //
    // when event happens              //
    Off (OUT_A + OUT_C);               //
    PlaySound (4);                     //
    Wait (100);                        //
  } //---------------------------------//

  // further code,                     //
  // will be executed after standard   //
  // action was completed or interrupt //
  // was handled                       //
  OnFwd (OUT_A);
  OnRev (OUT_C);
  Wait (300);
  StopAllTasks ();
}
---------------



Message is in Reply To:
  Monitor() and Event()
 
Can someone teach me more on Monitor() and Event()? Does the Monitor() check the event status repeatly or we have to make a repeat task to activate the monitoring job? If it is not checking the event status repeatly, why we cannot just read the (...) (24 years ago, 23-Oct-00, to lugnet.robotics.rcx.nqc)

4 Messages in This Thread:



Entire Thread on One Page:
Nested:  All | Brief | Compact | Dots
Linear:  All | Brief | Compact
    

Custom Search

©2005 LUGNET. All rights reserved. - hosted by steinbruch.info GbR