Society of Robots - Robot Forum

Software => Software => Topic started by: Hasan999 on March 27, 2010, 07:30:10 AM

Title: How to use delays in appControl loop !?
Post by: Hasan999 on March 27, 2010, 07:30:10 AM
It must be a stupid question... but I just can't get it !!

In WebbotLib... when I use delay_ms(5000); or clockWaitms(5000); in the main loop .... it delays for 5 seconds in the beginning itself, and continues with the programming without any delays.

That actually makes sense to me because appControl loop, loops continuously no matter what the code is... so whenever I use delays, it adds up, and delays when I switch the Axon On.

If that is normal, then how to use delays in order to do programming step by step having different delays in between, for example:

Code: [Select]
act_setSpeed(&S1,p1);
act_setSpeed(&S2,p2);

p1 = 50;

delay_ms(2000);

p1 = 0;

delay_ms(1000);

p2 = 50;

//etc..

I have been improvising all this time by using the clockGetus time ...I am doing it through 'commands at specific time' ...but now its getting complicated and I need to use 'delays' in between commands.

Thanks.



Title: Re: How to use delays in appControl loop !?
Post by: Webbot on March 27, 2010, 10:08:54 AM
First of all you will notice that appControl can return a delay (in microseconds) ie
void appControl(.....){
 ... do something ....
  return 10000;
}

Will mean that when appControl finishes the library will wait for 10ms - the length of time it to 'do something'. In other words your appControl will get called every 10ms.

However: there is nothing to stop you returning different numbers depending on situations.

Alternatively you need to think more about the current 'state' of your robot and make appControl behave differently according to the state.

As an example: lets say we want to go fwds until we hit something, then reverse for 2 seconds, then turn for 1/2 a second and then go fwds again:
Code: [Select]
// Define constants - one for each state:-
#define STATE_FORWARDS 1
#define STATE_REVERSE 2
#define STATE_TURN 3

// Have a global variable to store the current state
int state;

// In appInitSoftware - set the state to its initial value:-
state  = STATE_FORWARDS;

// Have a global variable to record WHEN a state changed
TICK_COUNT since;

// Then in appControl - behave differently for each state:
TICK_COUNT appControl(LOOP_COUNT loopCount, TICK_COUNT loopStart){
  switch(state){
    case STATE_FORWARDS:
    use act_setSpeed to make motors go forwards
    if( I have hit something){
       state = STATE_BACKWARDS;
       since = loopStart;  // record time when I started reversing
    }
    break;

    case STATE_BACKWARDS:
        if(clockHasElapsed(since,2000000)){
            // We have been reversing for 2seconds so start turning
            state = STATE_TURN;
            since = loopStart;
        }else{
            // We are still going backwards
            use act_setSpeed to go backwards
        }
    break;

    case STATE_TURN:
        // we are turning
        if(clockHasElapsed(since,500000)){
            // We have been turning for half a second so go forwards again
            state = STATE_FORWARDS;
        }else{
            // We are still turning
            use act_setSpeed to turn
        }
    break;
 }
 return 10000; // call every 10ms
}

Thats just a 'quick and dirty' example ie you should also be checking to see if you've hit things whilst reversing and turning. Perhaps you should randomise whether it turns clockwise or anti-clockwise, and may be even randomise how long it reverses for and how long it turns for.

So think about all the states that are needed and what causes it to change from one state into another state.