View unanswered posts | View active topics It is currently Tue Jul 29, 2014 10:49 am






Reply to topic  [ 13 posts ] 
Events - where have I gone wrong? 
Author Message
Rookie

Joined: Sat Jun 21, 2008 5:50 pm
Posts: 7
Post Events - where have I gone wrong?
Hi all,

I'm new to RobotC and have picked it up from the samples given in the package. However, I cannot seem to grasp how to code for an event.

The example given seems to point to the code below, but while this compiles, it doesn't have the desired result: beeping when the touch sensor is pressed doesn't happen.

Can someone please point out where I have gone wrong?

Code:
const byte TouchEvent = 1;

void main()
{
  SetEvent(TouchEvent, EST_SENSOR_2, eventTypePressed);
  while (true)
  {
    monitor (EVENT_MASK(TouchEvent))
    {
    }
    catch (EVENT_MASK(TouchEvent))
    {
      PlaySound(soundBeepBeep);
    }
  }
}


Any help appreciated!

Cheers, Jase250.


Mon Jun 30, 2008 4:10 am
Profile
Rookie

Joined: Sat Jun 21, 2008 5:50 pm
Posts: 7
Post 
:oops:

Hangover from other languages...

hehe: void main, what was I thinking.


Mon Jun 30, 2008 7:48 am
Profile
Rookie

Joined: Sat Jun 21, 2008 5:50 pm
Posts: 7
Post 
Hmm... hungover or not, I obviously still don't grasp it... :|


Mon Jun 30, 2008 8:09 am
Profile
Guru
User avatar

Joined: Sat Mar 01, 2008 12:52 pm
Posts: 1030
Post 
task main,
I'd suggest... 8)
(but don't know, if that's the reason why it doesn't work with the listeners... :roll: )

_________________
regards,
HaWe aka Ford
#define S sqrt(t+2*i*i)<2
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;task main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PutPixel(x,y);}}}while(1)}


Mon Jun 30, 2008 8:49 am
Profile
Rookie
User avatar

Joined: Thu Jun 26, 2008 11:27 am
Posts: 21
Location: Johannesburg, South Africa
Post 
Hi

You need to add the following line before the SetEvents:
SensorType[S2] = sensorTouch;

I would also suggest you run this as a separate task rather than in main and add a wait1Sec(1) into the monitor part.
thus:
Code:
const byte TouchEvent = 1;

task Touch()
{
   SensorType[S2] = sensorTouch;
  SetEvent(TouchEvent, EST_SENSOR_2, eventTypePressed);
  while (true)
  {
    monitor (EVENT_MASK(TouchEvent))
    {
       wait1Msec(1);
    }
    catch (EVENT_MASK(TouchEvent))
    {
      PlaySound(soundBeepBeep);
    }
  }
}
task main()
{
   StartTask(Touch);
   while (true)
   {
      wait1Msec(100);
   }
}


It then seems to work fine.


Sun Jul 06, 2008 5:34 am
Profile WWW
Guru
User avatar

Joined: Sat Mar 01, 2008 12:52 pm
Posts: 1030
Post 
hmmmh...
I thought the sensor watchers induce background tasks by themselves - otherwise you won't need them, so why put them into an endless task?
(Or could this be another bug?)
Otherwise you just could pack your sensor value query and assignment into your extra task and forget about all the sensor watchers (that's the way I'm doing... :wink: )

(sorry for my English :oops: )

_________________
regards,
HaWe aka Ford
#define S sqrt(t+2*i*i)<2
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;task main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PutPixel(x,y);}}}while(1)}


Sun Jul 06, 2008 6:09 am
Profile
Rookie
User avatar

Joined: Thu Jun 26, 2008 11:27 am
Posts: 21
Location: Johannesburg, South Africa
Post 
Hi

Quite right, you don't need another task
This would be better

Code:
const byte TouchEvent = 1;

task main()
{
  SensorType[S2] = sensorTouch;
  SetEvent(TouchEvent, EST_SENSOR_2, eventTypePressed);
  while (true)
  {
    monitor (EVENT_MASK(TouchEvent))
    {
         while (true)
         {
        // Do other things
          wait1Msec(1000);
       }
    }
    catch (EVENT_MASK(TouchEvent))
    {
      PlaySound(soundBeepBeep);
    }


  }
}


Sun Jul 06, 2008 7:40 am
Profile WWW
Guru
User avatar

Joined: Sat Mar 01, 2008 12:52 pm
Posts: 1030
Post 
I wonder if the monitor-while-loop is really needed.
There are similar constructs in LeJos and NQC, and there you use it in a different way:
- you once start the Sensor listener, maybe at the program start; this causes a hidden endless task;
- you ask anywhere in any subroutine or different task, if there has happend a sensor event, e.g., in this case maybe in a while loop...;
- you react to the event if there was one, otherwise do sth else("try...catch...")

or am I completely wrong?
BTW: isn't there any a code example source ?

_________________
regards,
HaWe aka Ford
#define S sqrt(t+2*i*i)<2
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;task main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PutPixel(x,y);}}}while(1)}


Last edited by Ford Prefect on Sun Jul 06, 2008 3:55 pm, edited 2 times in total.



Sun Jul 06, 2008 8:45 am
Profile
Rookie
User avatar

Joined: Thu Jun 26, 2008 11:27 am
Posts: 21
Location: Johannesburg, South Africa
Post 
Actually you don't need the while loop inside the monitor block, at least not for this simple example.

Code:
const byte TouchEvent = 1;

task main()
{
  SensorType[S2] = sensorTouch;
  SetEvent(TouchEvent, EST_SENSOR_2, eventTypePressed);
   int ctr;
  while (true)
  {
     monitor (EVENT_MASK(TouchEvent))
     {
         // Do other things
           nxtDisplayTextLine(2, "%d ", ctr++);
           wait1Msec(1000);
     }
     catch (EVENT_MASK(TouchEvent))
     {
       PlaySound(soundBeepBeep);
       ctr = 0;
     }
   }
}


There is a sample program called 'NXT Event Sample.c'


Sun Jul 06, 2008 11:24 am
Profile WWW
Guru
User avatar

Joined: Sat Mar 01, 2008 12:52 pm
Posts: 1030
Post 
my fault: I misunderstood "monitor", I thought it was for starting the monitoring thread, not for "if no event", and I was used to "catch" for the exception, not for "if event", now this seems to me kind of other way around...

so:
setEvent once,
monitor...catch inside the loop (like: if no event ...else if event)

so there were just 2 mistakes in the code posted by jase250 at the top :
"task main" instead of "void main", and
"SensorType[S2] = sensorTouch" missing

right? does it work now?

_________________
regards,
HaWe aka Ford
#define S sqrt(t+2*i*i)<2
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;task main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PutPixel(x,y);}}}while(1)}


Last edited by Ford Prefect on Mon Jul 07, 2008 4:30 pm, edited 2 times in total.



Sun Jul 06, 2008 2:22 pm
Profile
Rookie

Joined: Sat Jun 21, 2008 5:50 pm
Posts: 7
Post 
Thanks for your contributions, people. True, in attempting to figure out the events I neglected to assign the sensor.

So let me see if I have this straight, because the event monitoring seems a little pointless in the way I understand it now. It seems that if you want to be monitoring an event, then the main body of your program must either be inside the code for this, or be a routine called from here.

This is what I mean:
Code:
task main()
{
  SetEvent(TouchEvent, EST_SENSOR_2, eventTypePressed);
  while (true)
  {
    monitor (EVENT_MASK(TouchEvent))
    {     
          //main body of program or a call to it
          // do this while there is no event
    }
    catch (EVENT_MASK(TouchEvent))
    {
      PlaySound(soundBeepBeep);
      // do this when there is an event
    }
  }
}

It makes more sense to me to be able to initialise the monitoring code, then just leave it alone until the event triggers, as such:

Code:
task main()
{
  SetEvent(TouchEvent, EST_SENSOR_2, eventTypePressed);
    monitor (EVENT_MASK(TouchEvent))
    {     

    }
    catch (EVENT_MASK(TouchEvent))
    {
      PlaySound(soundBeepBeep);
    }
    while (true)
  {
    //main body of program
  }
}

I must be missing the point, but would appreciate having it shown to me. I can only assume that it must be started in a separate task, but as Ford stated, why have another task to look after a task...?

If this is the way to use an event, surely this code is simpler and just as effective (sonar mounted on motor - monitors for it being knocked by an object the sonar missed, eg sound absorbant material):
Code:
#define bHeadBump() (abs(nHeadMove) > 2 )

task headMonitor()
{
  int nLastEncoder;

  nLastEncoder = nMotorEncoder[mHead];
  while (true)
  {
    wait1Msec(1);
    nHeadMove = (nMotorEncoder[mHead] - nLastEncoder);
  }
}

task main()
{
StartTask(headMonitor);

while (true)
{
   if bHeadBump() //do something appropriate
}
}


Thoughts?


Sun Jul 06, 2008 7:14 pm
Profile
Guru
User avatar

Joined: Sat Mar 01, 2008 12:52 pm
Posts: 1030
Post 
hi,
I doubt if it's possible to leave both the listener initialization and the event checking outside any loop.
As I understand this issue, the initialization indeed has to be started once.
But anywhere there has to be made a decision what to do, either if this event has happened ("behavior 1)", or not ("behavior 2"). This could happen in your motor steering routine. Sure, if you want to react only once in your program at all, there doesn't have to be a loop, but if you want to do this maybe several times or each time during run time, this
monitor...catch switch
surely will have to be queried in a loop.

If the "event-behavior" is additional to the standard behavior, you may do it by an extra task. In case of an event then both behaviors are running simultaneously.
And if there isn't anything to do in case of no event (no behavior 1), you may let the program or task wait until there will be one.

Otherwise, if you have 2 "excluding" behaviors and you want to put them into 2 different routines, you will have to program a sort of "behavior handling". I myself did this before using a subsumtion (subsumption) architecture. By this one the "higher level task" is idle if no event happens, so the lower task got the control; if the event happens, the other, higher level tasks takes the control and the lower one becomes inactive - I can't imagine how to do it by an other way...

But, to be honest: I think that the event listeners are made for people who wish to avoid to write their own multi tasking programs. If you want to handle sensor events in different tasks, I'll suggest to write the sensor checking routines by your own.

(sorry for my English, I might have explained this in a better way in my native language)

_________________
regards,
HaWe aka Ford
#define S sqrt(t+2*i*i)<2
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;task main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PutPixel(x,y);}}}while(1)}


Mon Jul 07, 2008 2:58 am
Profile
Rookie

Joined: Sat Jun 21, 2008 5:50 pm
Posts: 7
Post 
Hi again,

Yes, I think we are on the same path. I don't know the fancy terminology, but I have a hiearchy of 'modes' which the robot steps through, depending on the result of an attempt to complete the previous task. I think this is similar to your subsumption architecture.

Of course, I do want my sensors to be monitored continuously, but I want this to happen in the main part of my program, not in the 'monitor' or 'catch' bit of the event code.

Thanks for your input. I will be ditching events and stick to monitoring the sensors through my own tasks.

Cheers, Jase.


Mon Jul 07, 2008 3:42 am
Profile
Display posts from previous:  Sort by  
Reply to topic   [ 13 posts ] 

Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  



Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.