Robobuilder task scheduler

Korean company maker of Robot kits and servos designed for of articulated robots. Re-incarnation of Megarobotics.
7 postsPage 1 of 1
7 postsPage 1 of 1

Robobuilder task scheduler

Post by badcommandorfilename » Fri Jan 29, 2010 12:30 am

Post by badcommandorfilename
Fri Jan 29, 2010 12:30 am

I want to write an embedded system (AVR) task scheduler in C to handle the operation of a variety of non-critical tasks which my robobuilder needs to perform. I'm looking for some advice on how to implement it so that it adds the lowest amount of overhead while giving it the most flexibility.

I'm also not trying to write a real time OS or anything - it just needs to be simple enough to keep a few core functions balanced. None of the tasks are time critical (I'm using interrupts for those), but I need a way to make sure that nothing is neglected for too long.

1) It needs to be able to schedule tasks for execution at a specific time.

This is mainly for scripted actions (it's a humanoid robot) like walking, etc as well as recharging the battery (which is trickle charged). Right now, I'm thinking of using an array of counters, which are decremented periodically, combined with a state machine in the main loop. This will simply switch the state to the overdue task when the current state expires.

2) It would be nice to have a method of forcing the execution of WAAAY overdue tasks.

Although it's no biggie if some actions are a few tens of milliseconds late, it would be nice if I could guarantee that a task would be executed in a reasonable time. I'm thinking of adding a watchdog interrupt which will perform the task if it's overdue.

3) Some tasks might take a long time to finish.

I'm trying to make this an extensible system, which allows for many tasks. However, if I use the state-machine system above I risk having long running tasks (like path planning/IK) postponing shorter and perhaps more critical tasks (like movement). Including the watchdog override would require the entire task to be run inside the interrupt, which is even worse.

4) A priority system would also be desirable.

In the case that a long task finishes and there are several overdue tasks to perform, the program should run the most critical ones first. Creative use of priorities could also help solve the problem of having a mix of long and short running functions.

5) I'd like a way to pass arguments to functions when the task is scheduled (not executed).

This is the one I really need help with. I'm almost certainly going to end up using function pointers, but unless all the functions take the same arguments I will have to have different data-types and handler functions. Also, how can I copy the argument(s) in their current state for execution later (in the generic case). I think I could do this in C using a sort of pseudo-stack if I can guarantee that each function will only end up in the task queue once, but I'm hoping a generic solution can be implemented if I am creative with assembly.

Has anyone had to do something like this before? I'm looking for a balance between execution overhead, complexity and versatility, so it's OK if there's no good way to get all these features working together. Also, I'm using C now but C++ is also an option.

Any input is appreciated. Thanks for your help!

More detailed information is available at my blog.
--------------
http://buildtherobot.blogspot.com - for robot builders and enthusiasts
I want to write an embedded system (AVR) task scheduler in C to handle the operation of a variety of non-critical tasks which my robobuilder needs to perform. I'm looking for some advice on how to implement it so that it adds the lowest amount of overhead while giving it the most flexibility.

I'm also not trying to write a real time OS or anything - it just needs to be simple enough to keep a few core functions balanced. None of the tasks are time critical (I'm using interrupts for those), but I need a way to make sure that nothing is neglected for too long.

1) It needs to be able to schedule tasks for execution at a specific time.

This is mainly for scripted actions (it's a humanoid robot) like walking, etc as well as recharging the battery (which is trickle charged). Right now, I'm thinking of using an array of counters, which are decremented periodically, combined with a state machine in the main loop. This will simply switch the state to the overdue task when the current state expires.

2) It would be nice to have a method of forcing the execution of WAAAY overdue tasks.

Although it's no biggie if some actions are a few tens of milliseconds late, it would be nice if I could guarantee that a task would be executed in a reasonable time. I'm thinking of adding a watchdog interrupt which will perform the task if it's overdue.

3) Some tasks might take a long time to finish.

I'm trying to make this an extensible system, which allows for many tasks. However, if I use the state-machine system above I risk having long running tasks (like path planning/IK) postponing shorter and perhaps more critical tasks (like movement). Including the watchdog override would require the entire task to be run inside the interrupt, which is even worse.

4) A priority system would also be desirable.

In the case that a long task finishes and there are several overdue tasks to perform, the program should run the most critical ones first. Creative use of priorities could also help solve the problem of having a mix of long and short running functions.

5) I'd like a way to pass arguments to functions when the task is scheduled (not executed).

This is the one I really need help with. I'm almost certainly going to end up using function pointers, but unless all the functions take the same arguments I will have to have different data-types and handler functions. Also, how can I copy the argument(s) in their current state for execution later (in the generic case). I think I could do this in C using a sort of pseudo-stack if I can guarantee that each function will only end up in the task queue once, but I'm hoping a generic solution can be implemented if I am creative with assembly.

Has anyone had to do something like this before? I'm looking for a balance between execution overhead, complexity and versatility, so it's OK if there's no good way to get all these features working together. Also, I'm using C now but C++ is also an option.

Any input is appreciated. Thanks for your help!

More detailed information is available at my blog.
--------------
http://buildtherobot.blogspot.com - for robot builders and enthusiasts
badcommandorfilename offline
Robot Builder
Robot Builder
Posts: 12
Joined: Fri Dec 11, 2009 11:34 am

Post by l3v3rz » Fri Jan 29, 2010 12:58 pm

Post by l3v3rz
Fri Jan 29, 2010 12:58 pm

You might want to look at http://www.freertos.org/ I was thinking about trying to port to robobuilder myself. It has a simple task scheduler. Nice explanation of how it works as well.
You might want to look at http://www.freertos.org/ I was thinking about trying to port to robobuilder myself. It has a simple task scheduler. Nice explanation of how it works as well.
l3v3rz offline
Savvy Roboteer
Savvy Roboteer
Posts: 473
Joined: Fri Jul 18, 2008 2:34 pm

Post by badcommandorfilename » Sat Jan 30, 2010 3:19 am

Post by badcommandorfilename
Sat Jan 30, 2010 3:19 am

I might give that a try - if it's easy enough to use, then it will be less effort than trying to do the task scheduling myself. I think I could make it work pretty well, but it wouldn't be reliable if there was a heavy processor load.

I was thinking about just allowing some tasks to run inside the interrupt - at the discretion of the user. That way higher priority tasks would still run when they were supposed to, but hopefully not hog the processor for too long. Does the AVR support priorities for interrupts? I know the PIC does.
I might give that a try - if it's easy enough to use, then it will be less effort than trying to do the task scheduling myself. I think I could make it work pretty well, but it wouldn't be reliable if there was a heavy processor load.

I was thinking about just allowing some tasks to run inside the interrupt - at the discretion of the user. That way higher priority tasks would still run when they were supposed to, but hopefully not hog the processor for too long. Does the AVR support priorities for interrupts? I know the PIC does.
badcommandorfilename offline
Robot Builder
Robot Builder
Posts: 12
Joined: Fri Dec 11, 2009 11:34 am

Post by l3v3rz » Sat Jan 30, 2010 2:48 pm

Post by l3v3rz
Sat Jan 30, 2010 2:48 pm

See http://web.engr.oregonstate.edu/~traylo ... rrupts.pdf
interrupt priority is dependent on position in vector table.
See http://web.engr.oregonstate.edu/~traylo ... rrupts.pdf
interrupt priority is dependent on position in vector table.
l3v3rz offline
Savvy Roboteer
Savvy Roboteer
Posts: 473
Joined: Fri Jul 18, 2008 2:34 pm

Post by Felix » Fri Feb 12, 2010 4:24 pm

Post by Felix
Fri Feb 12, 2010 4:24 pm

I am tempted to try putting FreeRTOS on my robobuilder, but does anyone know if it's possible for me to ruin the controller's ability to receive further downloads? If it's simply a case of putting the original code back on that's fine but I don't want to permanently damage my controller! :O
I am tempted to try putting FreeRTOS on my robobuilder, but does anyone know if it's possible for me to ruin the controller's ability to receive further downloads? If it's simply a case of putting the original code back on that's fine but I don't want to permanently damage my controller! :O
Felix offline
Robot Builder
Robot Builder
Posts: 12
Joined: Wed Jun 17, 2009 12:24 pm

Post by l3v3rz » Fri Feb 12, 2010 6:00 pm

Post by l3v3rz
Fri Feb 12, 2010 6:00 pm

I think if you use the supplied RBCupgrade tool then you should always be able to recover, the bootloader requires you write to a special area of Flash to overwrite. I've certainly used it (RBCupgrade) a lot in writing the homebrew OS and never had a problem reverting it back to standard build. If you do go for it I hope you'll post the source so others can try it (i.e. me !)
I think if you use the supplied RBCupgrade tool then you should always be able to recover, the bootloader requires you write to a special area of Flash to overwrite. I've certainly used it (RBCupgrade) a lot in writing the homebrew OS and never had a problem reverting it back to standard build. If you do go for it I hope you'll post the source so others can try it (i.e. me !)
l3v3rz offline
Savvy Roboteer
Savvy Roboteer
Posts: 473
Joined: Fri Jul 18, 2008 2:34 pm

Post by i-Bot » Sat Feb 13, 2010 11:51 am

Post by i-Bot
Sat Feb 13, 2010 11:51 am

I have changed the code in the RBC many many times using RBCupgrade without any problems and always been able to restore original code and function.

The only caution I have heard is if your new code overwrites the EEPROM. The EEPROM contains the RBC serial number. If you want to use the EEPROM in your program, read out the contents and restore them before reloading original Robobuilder code. The EEPROM should not be corrupted if you do not specifically write to it.
I have changed the code in the RBC many many times using RBCupgrade without any problems and always been able to restore original code and function.

The only caution I have heard is if your new code overwrites the EEPROM. The EEPROM contains the RBC serial number. If you want to use the EEPROM in your program, read out the contents and restore them before reloading original Robobuilder code. The EEPROM should not be corrupted if you do not specifically write to it.
i-Bot offline
Savvy Roboteer
Savvy Roboteer
User avatar
Posts: 1142
Joined: Wed May 17, 2006 1:00 am


7 postsPage 1 of 1
7 postsPage 1 of 1
cron