/Silverware/src/stickvector.c

https://github.com/silver13/BoldClash-BWHOOP-B-03 · C · 161 lines · 101 code · 43 blank · 17 comment · 20 complexity · e2ab196d6d79c1398e15e035bc19b01a MD5 · raw file

  1. #include "config.h"
  2. #include "util.h"
  3. #include <math.h>
  4. #include <string.h>
  5. extern float GEstG[3];
  6. extern float Q_rsqrt( float number );
  7. extern char aux[];
  8. // error vector between stick position and quad orientation
  9. // this is the output of this function
  10. float errorvect[3];
  11. // cache the last result so it does not get calculated everytime
  12. float last_rx[2] = {13.13f , 12.12f};
  13. float stickvector[3] = { 0 , 0 , 1};
  14. void stick_vector( float rx_input[] , float maxangle)
  15. {
  16. // only compute stick rotation if values changed
  17. if ( last_rx[0] == rx_input[0] && last_rx[1] == rx_input[1] )
  18. {
  19. }
  20. else
  21. {
  22. last_rx[0] = rx_input[0];
  23. last_rx[1] = rx_input[1];
  24. float pitch, roll;
  25. // rotate down vector to match stick position
  26. pitch = rx_input[1] * LEVEL_MAX_ANGLE * DEGTORAD + (float) TRIM_PITCH * DEGTORAD;
  27. roll = rx_input[0] * LEVEL_MAX_ANGLE * DEGTORAD + (float) TRIM_ROLL * DEGTORAD;
  28. stickvector[0] = fastsin( roll );
  29. stickvector[1] = fastsin( pitch );
  30. stickvector[2] = fastcos( roll ) * fastcos( pitch );
  31. float mag2 = (stickvector[0] * stickvector[0] + stickvector[1] * stickvector[1]);
  32. if ( mag2 > 0.001f )
  33. {
  34. mag2 = Q_rsqrt( mag2 / (1 - stickvector[2] * stickvector[2]) );
  35. }
  36. else mag2 = 0.707f;
  37. stickvector[0] *=mag2;
  38. stickvector[1] *=mag2;
  39. #ifdef INVERTED_ENABLE
  40. extern int pwmdir;
  41. if ( pwmdir==REVERSE )
  42. {
  43. stickvector[0] = - stickvector[0];
  44. stickvector[1] = - stickvector[1];
  45. stickvector[2] = - stickvector[2];
  46. }
  47. #endif
  48. }
  49. // find error between stick vector and quad orientation
  50. // vector cross product
  51. errorvect[1]= -((GEstG[1]*stickvector[2]) - (GEstG[2]*stickvector[1]));
  52. errorvect[0]= (GEstG[2]*stickvector[0]) - (GEstG[0]*stickvector[2]);
  53. // some limits just in case
  54. limitf( &errorvect[0] , 1.0);
  55. limitf( &errorvect[1] , 1.0);
  56. // fix to recover if triggered inverted
  57. // the vector cross product results in zero for opposite vectors, so it's bad at 180 error
  58. // without this the quad will not invert if angle difference = 180
  59. #ifdef INVERTED_ENABLE
  60. static int flip_active_once = 0;
  61. static int flipaxis = 0;
  62. static int flipdir = 0;
  63. int flip_active = 0;
  64. #define rollrate 2.0f
  65. #define g_treshold 0.125f
  66. #define roll_bias 0.25f
  67. if ( aux[FN_INVERTED] && (GEstG[2] > g_treshold) )
  68. {
  69. flip_active = 1;
  70. // rotate around axis with larger leaning angle
  71. if ( flipdir )
  72. {
  73. errorvect[flipaxis] = rollrate;
  74. }
  75. else
  76. {
  77. errorvect[flipaxis] = -rollrate;
  78. }
  79. }
  80. else if ( !aux[FN_INVERTED] && (GEstG[2] < -g_treshold) )
  81. {
  82. flip_active = 1;
  83. if ( flipdir )
  84. {
  85. errorvect[flipaxis] = -rollrate;
  86. }
  87. else
  88. {
  89. errorvect[flipaxis] = rollrate;
  90. }
  91. }
  92. else
  93. flip_active_once = 0;
  94. // set common things here to avoid duplication
  95. if ( flip_active )
  96. {
  97. if ( !flip_active_once )
  98. {
  99. // check which axis is further from center, with a bias towards roll
  100. // because a roll flip does not leave the quad facing the wrong way
  101. if( fabsf(GEstG[0])+ roll_bias > fabsf(GEstG[1]) )
  102. {
  103. // flip in roll axis
  104. flipaxis = 0;
  105. }
  106. else
  107. flipaxis = 1;
  108. if ( GEstG[flipaxis] > 0 )
  109. flipdir = 1;
  110. else
  111. flipdir = 0;
  112. flip_active_once = 1;
  113. }
  114. // set the error in other axis to return to zero
  115. errorvect[!flipaxis] = GEstG[!flipaxis];
  116. }
  117. #endif
  118. }