We are back from the 25c3 - The 25. Chaos Computer Club Congress in Berlin.
This years CCC Congress took place in Berlin at the BCC Congress Center from december 27 to 30. Some of the NG developers joined the congress to present our project's work and to meet in person for a developer meeting with a lot of hacking, talk and fun.
In the last days before the congress we finally found the time to look into axis decoupling.
Having had a big discussion with Tensor, a bright guy also hacking on IMU algorithms, who confirmed that my formulas were correct and who even showed me a new way to calculate them without hitting the poles of the formulas, I implemented the no-poles solution as well as the solution with poles in my NG controller. Short test flights in my living room showed no degradation in normal hoovering flight and further tests showed the big improvements the formulas brought with them.
Taarek and I did three small movies to demonstrate the new behavior!
The test is quite simple: Taarek shakes the NG around multiple axises at the same time and he does this using large angles. This makes sure that the integration without axis de-coupling will misbehave and the NG suddenly does no longer know where it's horizontal position is. After a while of forceful shaking Taarek let's the NG free so that it can take the position it thinks is horizontal. That's the moment one is able to see very good what the NG thinks to be horizontal.
In the first test, without axis de-coupling activated you see the error very well. Furthermore you see how the Kalman filter corrects the quite heavy error within some seconds. That's one of the reasons we fix this so late...
In the following second and third test, we switched the axis de-coupling on. As you can see there is no visible error anymore.
In the following third test Taarek shakes the NG a while longer.
As you can see, this works out very well!
We did several test flights in the living room (outside it's simply to cold) and it all performed well, so we did our flights at the 25c3 all with activated axis de-coupling.
He's one of them, where I test our new kernel concept we implemented:
Here's another 25c3 movie showing some flights our friends of the MK team did. I wouldn't let you miss those flights! Some of the MK pilots are very good and show off in the big conference room. The movie was created by Ingo (der_oschni) who seems to have missed everything pointing to the NG project. Can you spot us? ;)
All in all it was a very cool congress (as every year) with a lot of progress, talk and networking. Besides testing the new axis de-coupling one of our developers started digging the deeper magic of the ARM RISC CPU.
User, System and IRQ mode: We have a real kernel now!
Axel, as every year searching for a topic he can solve at the 25c3 investigated our sensor and actor busses using his logic analyzer. In the progress of that, he discovered something which we were all aware of, but which started to bitch us as soon as we saw it printed on the screen!
Up to then our closed-loop control worked inside a timer interrupt. Because that and because we do not do nested interrupts, all other operations cease to function until the closed-loop step has finished. This is not the best behavior in a system where Input/Output is only lightly coupled with processing. We specially want to use the ability to continue acquiring sensor data and to output actor control commands while we calculate the next step of the closed-loop control.
One of the solutions to that would be to use nested interrupts. Digging the internals of the ARM RISC CPU deeper, we remembered the different operating modes the ARM CPU can use! The ARM CPU has user, system as well as IRQ contexts. Privileged opcodes can't be used in user mode, which makes sure a user process will never switch uncontrolled to one of the other operating modes.
Having remembered these features we immediately saw the prefect solution: We move our non real time tasks into the user mode and let the timer interrupt, which executed our closed-loop control step until now, switch from IRQ to system context, enable nested interrupt and then execute the closed-loop control step. That way all interrupts are still able to interrupt the closed-loop control step! User context processes like our shells have to use system calls to get into the system context to use privileged opcodes.
Axel did great work and rewrote our NGOS through the 25c3 according to these ideas. We now have all the above implemented and looking at the sensor and actor busses it all works now a lot smother! Actors and sensors get accessed while the closed-loop control step takes place and so our output/input/process closed-loop control can operate lightly coupled together with the IO drivers.
As you can see in the above movie, the NG flew wonderful using these changes, through no immediate differences in flight behavior were visible... as expected it did not change much, to handle the 1ms tick smother since 1000Hz are enough anyway for the closed-loop control.
Exception handlers & crash logs
Being hacking all this low-level stuff Axel implemented exception handlers for all exceptions. We now store the exception data in non-resettable memory and do a reset. That way we are able to log into the NG and check the crash-data should there ever be a exception! This works wonderful as well.
Hardware Abstraction Layer
Since this blog article starts to get very long, I will elaborate in my next article on our new Hardware Abstraction Layer (HAL) which allows us to use up to 16 motors in arbitrary physical configurations.