MiniSumo, Subsumption & FreeRTOS

nobody wrote on Wednesday, June 07, 2006:

There is an interesting but not very specific article in the June 2006 edition of Servo where the author spends a lot of time on Subsumption Architecture and winds up suggesting it be implemented with FreeRTOS.  Yes!  A plug for FreeRTOS.

I have a BDMicro MAVRIC controller (ATmega128 with 64k of external RAM) and FreeRTOS is running.

What I would like is some suggestions on how to structure the FreeRTOS MiniSumo application:

Highest Priority: back away when front edge detectors sense the edge of the ring.

Next Priority: move forward when rear edge detectors sense the edge of the ring.

Presumably these two are mutually exclusive.

Next… Attack if opponent is directly in front of bot

Next… Turn left to counter opponent on left side

Next… Turn right to counter opponent on right side

Next… Turn around to counter opponent to the rear

These 4 are mutually exclusive, as well.

Next… Search by turning and trying to find opponent

Now, all that is fairly straight forward (I suppose) but I was thinking that the sensor inputs would be read in an interrupt routine, perhaps setting flags or semaphores.  Obviously, these are ‘volatile’ as they can be set and cleared at any time, for any reason.

So, I am looking for suggestions on  high level structure.  And, comments on the applicability of FreeRTOS to this project.


jwestmoreland wrote on Thursday, June 08, 2006:


I think FreeRTOS will work fine for this based on your target.

Do you know if you need hard real-time or soft real-time?

You’re asking for a high-level architecture.  If I were to supply a response - I’d need more details and it wouldn’t be, ahem, free.

John W.

nobody wrote on Thursday, June 08, 2006:

If you interrupt updates variables that indicate the sensor inputs value then these can be read from all the tasks with not problem, provided the data is the natural data width for the processor, and nothing else attempts to write to the variable.

Perhaps the sensor inputs could be used to suspend and resume tasks.  When the forward sensor was closed it would resume the forward task.  When the forward sensor was open again it would suspend the forward task.  It would not matter if more than one task was resumed at any one time as the task priority would dictate which was actually active.  In this case you could have one controller task that was highest priority that blocked on a queue.  The sensor interrupts would post the sensor values onto that queue to wake the controller task.  The controller task would then suspend or resume the other tasks depending on the sensor value, then go back to sleep to wait for the next state change.

Is this any good?

nobody wrote on Thursday, June 08, 2006:

Hard versus soft is an interesting question.  Response time is critical.  Particularly in terms of the edge detectors.  Driving off the edge is the easy way to lose a match.  So, response time should be in the very low number of milliseconds.

Yes, blocking a high priority task on a semaphore is a possibility.

One issue I am going to have to overcome: I am considering using an off-chip motor control system with rotational feedback.  This has the advantage of being able to produce predictable turns, etc.  The downside is the interface: either 115,200 baud serial or 400 kHz I2C.  So, there is this queue with pending commands, all of which need to be dumped, rather than executed, when the higher priority edge detection is triggered.  This may not be an issue, the transmission rate is quite fast.  But it is a consideration to be dealt with.

I don’t need an RTOS to implement subsumption architecture; it may even get in the way.  But, from an educational point of view, it is worth the time to make it work.


jwestmoreland wrote on Friday, June 09, 2006:


I don’t think FreeRTOS will ‘get in the way’.  I think the opposite - you can probably implement faster with FreeRTOS - and then tune as necessary.

John W.

nobody wrote on Friday, June 09, 2006:

The suspend/resume of tasks depending on sensor inputs is a good solution.  This has to be done from another task as you cannot call suspend( task ) and resume( task ) functions from within an interrupt. 

An alternative would be to make a small code change so suspend/resume can be performed from in an interrupt, or add SuspendFromISR and ResumeFromISR function equivalents.

Or use a semaphore to communicate between the interrupt routine and the tasks directly.

These alternatives remove the need for the described task that waits on the queue to receive the sensor inputs.