Preface
In my post about architecture of Orbital AP, which I developed during preparation for Operation “Silent Giant” simulated space mission, I mentioned that I faced a need to develop an algorithms for control of DeltaGlider spaceplane attitude.
During this development I faced a strange trap, roots of which I don’t understand till now. It seems important to tell about it and about ways of walk-around.
The problem
The problem seems simple. We have two coordinate systems (Velocity-Normal-Binormal) and (Forward-Up-Right) with origins in the center of masses of simulated spacecraft.
is a coordinate system, linked with orbital plane. Axis lays in vector of orbital velocity, is normal to orbit, and
is a coordinate system, linked with spacecraft. Axis points where nose of a spacecraft points, points upwards, and points to the right.
We know representation of unit vectors , and in coordinate system as , and .
Now, say, we have vector of direction of acceleration we need to apply to spacecraft for maneuver, given in system:
How it should be presented in coordinate system, say, to let us know to where we need to aim spacecraft for applying the burn (relatively to spacecraft itself)?
You would say “it’s easy!” and offer something like:
And I will agree, that this is correct, logical and easy!.. But in Orbiter 2016 it will not work.
When angle between and grew greater than 90°, precision of representation of drastically falls – the vector tended to turn towards (180°).
I will explain my understanding of this phenomena later, but before this I will give you some ideas about what I tried during the fight with it.
Error in implementation?
Most obvious explanation – error in my implementation of quaternion math in LUA.
But that was wrong guess.
I checked multiple formulas for computation of quaternion operations (from Wikipedia, from math literature, including Korn, Wertz, Hamilton, and from different software). Not all of them were correct, but reliable sources on tests provided working, reliable results.
Using ChatGPT I made a test suite (676 tests) checking matches between my LUA quaternion implementation and Unity3D quaternion implementation (which by definition worked OK). Outside Orbiter 2016 everything worked fine.
In simulation – no.
Wrong quaternions?
In despair, I wrote to Mr. David Vallado. He supposed that I faced specific kick of quaternions math application for ADCS (earlier described by Malcolm Shuster), and kindly sent to me perfect article “ROTATIONS, TRANSFORMATIONS, LEFT QUATERNIONS, RIGHT QUATERNIONS?” written by Renato Zanetti.
In the article Mr. Zanetty in details described that actually quaternions can be used for two types of rotation – common rotation, typically used in CG and gamedev (when we rotating an object in external coordinate system, like on the scene in game engine) and so-called transformation, widely used in aerospace and especially in ADCS.
The transformation is a type of rotation when we by sense rotating a coordinate system around object, representing its own turn how it is visible from the object.
Being an ex-gamedev expert, I, of course, never faced transformations (they just never used in gamedev practice). Encouraged, I returned to the code.
Implementation of transformation quaternions was simple. By sense it is:
But in Orbiter 2016 nothing changed. This was also a wrong guess.
Numeric instability?
That was my next “suspect”. It is known, that on low-grade computation systems quaternions, which calculation is based on trigonometric formulas. Typically this effect can be exist at cases when the angles are very close to extreme values. In that case, if system has low floating point precision, quaternions can glitch.
I did not expect this from LUA… But – who knows, what we can face in an old app? I tried to check this and returned to tests… But they still return same results – “everything is fine”.
Solution
During testing, I tried to use Rodrigues’ vector rotation formula:
and then, just in case, added it to ADCS aiming algorithm, implemented it for turn the vector around vertical and horizontal axes (like a gun barrel in naval turret).
Imagine my surprise when everything started to work!
Conclusion
I still can not understand, why quaternion approach did not work inside Orbiter simulator. Now, after very long thoughts, my assumption is that this is a program glitch of simulator.
In the end of this story – just watch the video of aiming of DeltaGlider towards maneuver. Elegant, isn’t it?

