QuadBow wrote:So, my question is:
Has already someone done some research in order to get rid of the trigonometric functions with float precision?
I could imagine that a trigonometric table would give the same result with better performance.
Since nobody has answered my question I did some modifications by my own.
Firstly, I inserted a look-up table of 91 entries at the begin of the file Multiwii.cpp.
Code: Select all
#if defined(OPTIMISE_SINCOS)
float SINUS_TABLE[91] = {0.000000,0.017452,0.034899,0.052336,0.069756,0.087156,0.104528,0.121869,0.139173,0.156434,
0.173648,0.190809,0.207912,0.224951,0.241922,0.258819,0.275637,0.292372,0.309017,0.325568,
0.342020,0.358368,0.374607,0.390731,0.406737,0.422618,0.438371,0.453990,0.469472,0.484810,
0.500000,0.515038,0.529919,0.544639,0.559193,0.573576,0.587785,0.601815,0.615662,0.629320,
0.642788,0.656059,0.669131,0.681998,0.694658,0.707107,0.719340,0.731354,0.743145,0.754710,
0.766044,0.777146,0.788011,0.798635,0.809017,0.819152,0.829038,0.838671,0.848048,0.857167,
0.866025,0.874620,0.882948,0.891007,0.898794,0.906308,0.913545,0.920505,0.927184,0.933580,
0.939693,0.945519,0.951057,0.956305,0.961262,0.965926,0.970296,0.974370,0.978148,0.981627,
0.984808,0.987688,0.990268,0.992546,0.994522,0.996195,0.997564,0.998630,0.999291,0.999848,1.000000};
#endif
Then I replaced the current headfree code within the function annexCode() of the file Multiwii.cpp.
Code: Select all
#if defined(HEADFREE)
if(f.HEADFREE_MODE) { //to optimize
float cosDiff, sinDiff;
int16_t rcCommand_PITCH;
#if defined(OPTIMISE_SINCOS)
int16_t degDiff = att.heading - headFreeModeHold;
if (degDiff <= - 180) degDiff += 360;
if (degDiff >= + 180) degDiff -= 360;
if (degDiff > 0){
if (degDiff <= 90){ // 0°..90°
sinDiff = SINUS_TABLE[degDiff];
cosDiff = SINUS_TABLE[90 - degDiff];
}
else{ // 90°..180°
sinDiff = SINUS_TABLE[180 - degDiff];
cosDiff = -SINUS_TABLE[-90 + degDiff];
}
}
else {
if (degDiff >= -90){ // 0°..-90°
sinDiff = -SINUS_TABLE[-degDiff];
cosDiff = SINUS_TABLE[90 + degDiff];
}
else{ // -90°..-180°
sinDiff = -SINUS_TABLE[180 + degDiff];
cosDiff = -SINUS_TABLE[-90 - degDiff];
}
}
#else // not defined OPTIMISE_SINCOS => original code with long lasting trigonometric functions from math library
float radDiff = (att.heading - headFreeModeHold) * 0.0174533f; // where PI/180 ~= 0.0174533
cosDiff = cos(radDiff);
sinDiff = sin(radDiff);
#endif
rcCommand_PITCH = rcCommand[PITCH]*cosDiff + rcCommand[ROLL]*sinDiff;
rcCommand[ROLL] = rcCommand[ROLL]*cosDiff - rcCommand[PITCH]*sinDiff;
rcCommand[PITCH] = rcCommand_PITCH;
}
#endif
Now, I can run the optimised code saving the two long lasting trigonometric functions via the following definition in the file config.h.
Recall that the resolution of heading is just one degree. Therefore, this small look-up table is sufficient and the results are the same as for the former non-optimised code.
As the attached image shows, the time required for the function annexCode() has been lowered from 850us to 750us as shown in the field debug3.
- Time required with optimisation for HEADFREE
But, it is still more than the magical 650us, we are aiming for. Further optimisation did not succeed up to now. So,the next step was to optimise the similar trigonometric functions within the function loop().