go_away

Author Topic: scheduler.h  (Read 572 times)

0 Members and 1 Guest are viewing this topic.

Offline RifRafTopic starter

  • Jr. Member
  • **
  • Posts: 10
  • Helpful? 0
scheduler.h
« on: February 11, 2013, 03:24:37 PM »
hello am trying to use the scheduleJob function in webbotlibs to queue up tasks but when compiling am always getting an error as if the function is not there. any ideas on whats wrong?

have tryed #include <scheduler.h> but according to the docs i should not have to as the timer.h called from hardware.h does it? Also looking in the errors.c to see how scheduler.h is used to blink the led I notice its commented out.

This is the non compiling code, it does compile with lines 44 and 50 commented out

Code: [Select]
#include "hardware.h"
#include "armbotbuild.h"
//#include "scheduler.h"
#include <Gait/GaitRunner.h>

#define SCHEDULER_MAX_JOBS 8

int anim1AlreadyPlayed = 0;
int anim2AlreadyPlayed = 0;
int anim3AlreadyPlayed = 0;
int anim4AlreadyPlayed = 0;

int zeroAlreadyPressed = 0;
int oneAlreadyPressed = 0;
int twoAlreadyPressed = 0;

int distance = 0;
int speed = 0;
int lastTime = 0;
int data = 0;

ACTUATOR_LIST PROGMEM all[] = {&GripperGrabber.actuator,&GripperRotate.actuator,&GripperSideways.actuator,&GripperUpDown.actuator,&ElbowUpDown.actuator,&ShoulderUpDown.actuator,&ShoulderRotate.actuator };

G8_RUNNER gait = MAKE_G8_RUNNER(all, animations);

void appInitHardware(void) {
initHardware();
gaitRunnerInit(&gait);
}

TICK_COUNT appInitSoftware(TICK_COUNT loopStart){
rprintf("Robot Started\r\n");
//servosDisconnect(&gait);
gaitRunnerPlay(&gait, 2, 5000, 10, 1);
return 500000;
}

void checkSonar(void * data, TICK_COUNT lasttime, TICK_COUNT overflow){
// lasttime is the microsecond time of when I should have been called
// overflow is the number of microseconds of error between lasttime
// and when actually called
distanceRead(sonar);
rprintf("Distance=%u\r\n",sonar.distance.cm);
scheduleJob(&checkSonar,data,clockGetus(),1000000);
//scheduleJob(&marqueeUpdate,data,lastTime,delay);
}

TICK_COUNT appControl(LOOP_COUNT loopCount, TICK_COUNT loopStart) {

scheduleJob(&checkSonar,null,clockGetus(), 0);

//servosConnect(&gait);
gaitRunnerProcess(&gait);

if(SWITCH_pressed(&button0)){
gaitRunnerPlay(&gait, 0, 5000, 30, 2);
gaitRunnerProcess(&gait);
}

if(SWITCH_released(&button0)){
zeroAlreadyPressed = 0;
}

if(SWITCH_pressed(&button1)){
gaitRunnerPlay(&gait, 1, 5000, 75, 1);
gaitRunnerProcess(&gait);
}

if(SWITCH_released(&button1)){
oneAlreadyPressed = 0;
}

if(SWITCH_pressed(&button2)){
gaitRunnerPlay(&gait, 3, 5000, 22, 10);
gaitRunnerProcess(&gait);
}

if(SWITCH_released(&button2)){
twoAlreadyPressed = 0;
}

return 0;
}



the errors are currently;

gaitc.o: In function `checkSonar':
C:\Code\projects\mega168\gait-runner/gaitc.c:44: undefined reference to `schedul
eJob'
gaitc.o: In function `appControl':
C:\Code\projects\mega168\gait-runner/gaitc.c:50: undefined reference to `schedul
eJob'
make: *** [gaitc.elf] Error 1

Offline Webbot

  • Expert Roboticist
  • Supreme Robot
  • *****
  • Posts: 2,132
  • Helpful? 108
Re: scheduler.h
« Reply #1 on: February 12, 2013, 01:51:03 PM »
You need to use <> around the filename ie
your code has
Code: [Select]
#include "scheduler.h"but should be
Code: [Select]
#include <scheduler.h>
The difference is use "<>" when you are including a file that is not written by you or in your project folder (like scheduler.h) whereas use quotes if its part of your project like "armbotbuild.h".

If you are using ProjectDesigner then you should edit the properties of the 'clock' device and tell it how many queued items it needs to work with. You can probably then drop the #define SCHEDULER_MAX_JOBS as ProjectDesigner takes care of this for you.

The led flashing is no longer done in the scheduler so as to not include all of the code for the scheduler just to flash the led. Keeps code files smaller if the user is not using the scheduler themselves.

For future reference: it would be very useful if you (and others !) could quote which version of WebbotLib you are using (see version.h), if you are using C or C++, and whether you are using ProjectDesigner or writing everything from the ground up.

Webbot Home: http://webbot.org.uk/
WebbotLib online docs: http://webbot.org.uk/WebbotLibDocs
If your in the neighbourhood: http://www.hovinghamspa.co.uk

Offline Webbot

  • Expert Roboticist
  • Supreme Robot
  • *****
  • Posts: 2,132
  • Helpful? 108
Re: scheduler.h
« Reply #2 on: February 12, 2013, 05:43:24 PM »
On a point of 'best practice' you probably shouldn't be using the scheduler to read the sonar anyway.
The scheduler works via interrupts to its work - ie in your case it will stop doing whatever its doing and go off and read the sonar every second.
This gets bad if you are also doing other time critical stuff - for example if you are using a software servo where the pulse is being generated by code. Interruptions from the scheduler could disturb this delicate timing.

Note also that webbotlib takes care of datasheet things - ie if the sonar datasheet says that you should leave say 100ms between readings to avoind ghost echoes then the device driver already enforces this and returns the previous reading if you are trying to read it too fast.

The scheduler should be used for things that really are time critical. In your case you only want to read the sonar every second - a few ms either way probably isn't going to make any difference.
So I would be tempted to use the clock value (TICK_COUNT loopStart ) passed into your main appControl loop. Your appControl could then do:

Code: [Select]
TICK_COUNT lastSonarRead = 0;

TICK_COUNT appControl(LOOP_COUNT loopCount, TICK_COUNT loopStart) {
    if (loopStart - lastSonarRead >= 1000000){
        lastSonarRead = loopStart;
        ---read the sonar ---
    }
}

If you prefer to continue using the scheduler then you need to a fix another bug:
The checkSonar code requeues itself - which is fine. But appControl also requeues it every time around the main loop - so you will quickly fill up the scheduler queue. To fix it: the call to initially schedule it should be done from appInitSoftware (which is only run once) rather than from appControl.
Webbot Home: http://webbot.org.uk/
WebbotLib online docs: http://webbot.org.uk/WebbotLibDocs
If your in the neighbourhood: http://www.hovinghamspa.co.uk

Offline RifRafTopic starter

  • Jr. Member
  • **
  • Posts: 10
  • Helpful? 0
Re: scheduler.h
« Reply #3 on: February 14, 2013, 03:03:11 AM »
cheers for reply, this is where i got to..  The code now compiles without any #include required for scheduler.h, the problem was me misunderstanding how to use the function(and still don't ).  I changed the use of the function and suddenly it compiles, but am sure its not being used correctly by me yet. I notice now in your second reply webbot that you have some code and will try this out this evening. 

Am using Project Manager to setup all the hardware, and used Board Designer to input my custom pcb.  The code editing is being done externally in editplus using the generated example code as a guide and am compiling from a command prompt using make and uploading the hex files using avrdude from command line.  The version of webbotlibs appears to be Version 2.09 21 April 2012 from version.h. 

Have been able to make a loop that delays about 1 second and checks sonar, can still interrupt with buttons durin that second so get what you mean about not using scheduler now for this task. So am getting somewhere thankfully. 

Since the scheduler will surely come in handy at some point now that I am this close would just let to know how to use it properly before moving on if thats ok.  When I include the line     //scheduleJob(&checkSonar,&data,lasttime, 0); am still getting Error1 generated, something to do with overloading the scheduler.  Have removed    #define SCHEDULER_MAX_JOBS 8   and modified the tasks to 8 for the timer in Project Designer. 

Will now try study the next post, sorry it took me a while to get through the first but learning lots.

Current Code:

Code: [Select]
#include "hardware.h"
#include "armbotbuild.h"
#include <Gait/GaitRunner.h>
     
int zeroAlreadyPressed = 0;
int oneAlreadyPressed = 0;
int twoAlreadyPressed = 0;
 
//int lasttime = 0;
//int * data = 0;
//int i = 0;
 
ACTUATOR_LIST PROGMEM all[] = {&GripperGrabber.actuator,&GripperRotate.actuator,&GripperSideways.actuator,&GripperUpDown.actuator,&ElbowUpDown.actuator,&ShoulderUpDown.actuator,&ShoulderRotate.actuator };
 
G8_RUNNER gait = MAKE_G8_RUNNER(all, animations);
 
void appInitHardware(void) {
initHardware();
gaitRunnerInit(&gait);
}

//void checkSonar(void * data, TICK_COUNT lasttime, TICK_COUNT overflow){
//        rprintf("about to check sonar\r\n");
//        distanceRead(sonar);
//        rprintf("about to display sonar\r\n");
//        rprintf("Distance=%u\r\n",sonar.distance.cm);
//        scheduleJob(&checkSonar,data,lasttime,1000000);
//        rprintf("sonar rescheduled for 1 second\r\n");
//}

TICK_COUNT lastSonarRead = 0;

TICK_COUNT appInitSoftware(TICK_COUNT loopStart){

rprintf("Robot Started\r\n");
gaitRunnerPlay(&gait, 2, 5000, 10, 1);
//scheduleJob(&checkSonar,&data,lasttime, 0);

return 0;
}
 

TICK_COUNT appControl(LOOP_COUNT loopCount, TICK_COUNT loopStart) {

if (loopStart - lastSonarRead >= 1000000){
        lastSonarRead = loopStart;
        distanceRead(sonar);
rprintf("Distance=%u\r\n",sonar.distance.cm);
    }
 
// if( i >=10000) {
// distanceRead(sonar);
// rprintf("Distance=%u\r\n",sonar.distance.cm);
// i = 0;
//    }
// i++;
 
if(SWITCH_pressed(&button0)){
if (zeroAlreadyPressed == 0) {
rprintf("Button 0 Pressed\r\n");
distanceRead(sonar);
rprintf("Distance=%u\r\n",sonar.distance.cm);
gaitRunnerPlay(&gait, 0, 5000, 30, 2);
gaitRunnerProcess(&gait);
zeroAlreadyPressed = 1;
}
}
   
if(SWITCH_released(&button0)){
zeroAlreadyPressed = 0;
}

if(SWITCH_pressed(&button1)){
if (oneAlreadyPressed == 0) {
rprintf("Button 1 Pressed\r\n");
distanceRead(sonar);
rprintf("Distance=%u\r\n",sonar.distance.cm);
gaitRunnerPlay(&gait, 1, 5000, 75, 1);
gaitRunnerProcess(&gait);
oneAlreadyPressed = 1;
}
}

if(SWITCH_released(&button1)){
oneAlreadyPressed = 0;
}

if(SWITCH_pressed(&button2)){
if (twoAlreadyPressed == 0) {
rprintf("Button 2 Pressed\r\n");
distanceRead(sonar);
rprintf("Distance=%u\r\n",sonar.distance.cm);
gaitRunnerPlay(&gait, 3, 5000, 22, 10);
gaitRunnerProcess(&gait);
twoAlreadyPressed = 1;
}
}
   
if(SWITCH_released(&button2)){
twoAlreadyPressed = 0;
}

return 0;
}

Edit a little later: ok things are great, did get the scheduler working when I put it into the appInitSoftware as you suggested and that fixed the queue overflowing, so happy.  after that changed to using the clock value as also suggested and was able to achieve the same result so extra happy, my issues are obviously a lack of coding skills but please bear with me, now to start messing with a new little accelerometer to try keeping the head stable on this thing.  The code above is the current working solution, with other working alternatives commented out so i can refer to them still later. Thanks again
« Last Edit: February 14, 2013, 04:24:50 AM by RifRaf »

 


Get Your Ad Here

data_list