If you've been following Tom Pyke's progress on his impressive Gluonpilot
, you will have seen that he's implementing it with a realtime operating system (RTOS), rather than programming "straight to the iron" the way most autopilots are done, to gain maximum control over interrupts, timing and the like. He's using a relatively powerful dsPIC chip, which can handle the overhead of the RTOS (
I think he's using FreeRTOS, but I've pinged him to find out
UPDATE: yes, it's FreeRTOS. See below). Here, he makes the case for a RTOS:
"The main advantage of a real time OS is that you can use threads (which we will use tasks from now on). You don't need to bother anymore about the delay your telemetry processing can cause to your Kalman filter or PID control. No more need for timed loops or Timer interrupt routines. It looks perfect!
There are some things you need to keep in mind:
You need to prioritize every task
Every task has a separate stack. This stack is used for the task itself AND every interrupt routine that may be called during this task's execution
Thats about it! Let's take a look at the different tasks in gluonpilot:
--Telemetry: All the output needed for our groundstation
--ConsoleInput: Processing and answering all the commands you send to the autopilot
--Sensors: Gathers and processes (filters!) all the sensors (gyroscope, accelerometer, gps, pressure sensor) on our autopilot module
--Control: Sends the correct position to the servos! This handles both manual, stabilized and full autopilot modes."
The prioritization of the tasks is as follows:
Read on here
UPDATE: In an email, Tom explains more:
"Yes I'm using FreeRTOS. Whether you should need to consider it [I had asked him if it would work on a 16Mhz Atmega--chris] is not easy to answer. 16MHz doesn't seem a lot. The dsPic runs at 80MHz (40MIPS) and - I think - has more memory. Using an RTOS does not cause an extreme amount of overhead, but you can no longer push the
processor to its limits:
- You need more memory because interrupts can be executed (and use
the stack) of any running task/thread (and you need to assign a stack
size to every task)
- You need enough spare CPU cycles to make sure all tasks can always
be handled in time.
- And the RTOS needs memory, flash and CPU time of its own
It may sound contradictory, but I started using FreeRTOS to make sure people can easier add code to the autopilot. In the last version without it, the code became complex and critical to change, because of all the timing-critical code and timed loops. Now with the RTOS, people can add lower priority tasks and I'm sure the manual control and time-critical filtering still works. However, you need to keep the design as simple as possible.
The only features I'm currently using is the scheduler (because it's easier than a timed loop) and a queue mechanism for pushing data from an interrupt to a sleeping thread.
There are some RTOS pitfalls such as priority inversions. But it's really up to you how far you want to go. Replacing your timer interrupt routine by a threads wonn't give you any problems you didn't have already. If you use mutexes for mutual exclusion all over your code, than you're down to a more challenging task :-)
In the end, I can only suggest that you play with it for a day or two... port some existing code to FreeRTOS and see how comfortable you are using it. It's not really that complex."