Mercurial > public > ostc4
comparison Discovery/Src/tInfoCompass.c @ 1007:65d35e66efb9 GasConsumption
Improve compass calibration dialog:
The previous calibration dialog showed some "magic" numbers and a 60 second count down. The new version is trying to guide the user through the calibration process: first rotate pitch, then roll and at last yaw angle. A step to the next angle is taken when enough data per angle is collected (change from red to green). To enable the yaw visualization a simple calibration is done while rotating the axis.
The function behind the calibration was not modified => the suggested process can be ignored and the same handling as the with old dialog may be applied. With the new process the dialog may be left early. Anyhow it will still be left after 60 seconds and the fine calibration is performed in the same way as before.
| author | Ideenmodellierer |
|---|---|
| date | Mon, 05 May 2025 21:02:34 +0200 |
| parents | b7b481df4f22 |
| children |
comparison
equal
deleted
inserted
replaced
| 1006:75f958ca5d0e | 1007:65d35e66efb9 |
|---|---|
| 26 /// along with this program. If not, see <http://www.gnu.org/licenses/>. | 26 /// along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 27 ////////////////////////////////////////////////////////////////////////////// | 27 ////////////////////////////////////////////////////////////////////////////// |
| 28 | 28 |
| 29 /* Includes ------------------------------------------------------------------*/ | 29 /* Includes ------------------------------------------------------------------*/ |
| 30 | 30 |
| 31 #include "gfx_engine.h" | 31 |
| 32 #include "gfx_fonts.h" | 32 #include "gfx_fonts.h" |
| 33 #include "tHome.h" | 33 #include "tHome.h" |
| 34 #include "tInfo.h" | 34 #include "tInfo.h" |
| 35 #include "tInfoCompass.h" | 35 #include "tInfoCompass.h" |
| 36 | 36 |
| 37 #include <string.h> | 37 #include <string.h> |
| 38 #include <math.h> | |
| 39 | |
| 40 #define PI 3.14159265358979323846 | |
| 41 | |
| 42 #define PITCH (0) | |
| 43 #define ROLL (1) | |
| 44 #define YAW (2) | |
| 38 | 45 |
| 39 /* Private variables ---------------------------------------------------------*/ | 46 /* Private variables ---------------------------------------------------------*/ |
| 40 | 47 |
| 41 uint16_t tInfoCompassTimeout = 0; | 48 static uint16_t tInfoCompassTimeout = 0; |
| 42 int16_t minMaxCompassDX[3][2] = { 0 }; | 49 static int16_t minMaxCompassDX[3][2] = { 0 }; |
| 50 | |
| 51 static axisIndicator_t axis[3]; | |
| 52 static uint8_t activeAxis = PITCH; | |
| 53 static uint32_t checkTick = 0; | |
| 43 | 54 |
| 44 /* Exported functions --------------------------------------------------------*/ | 55 /* Exported functions --------------------------------------------------------*/ |
| 45 void openInfo_Compass(void) | 56 void openInfo_Compass(void) |
| 46 { | 57 { |
| 58 uint16_t angle = 0; | |
| 59 uint8_t axisIndex = 0; | |
| 47 set_globalState(StICOMPASS); | 60 set_globalState(StICOMPASS); |
| 48 tInfoCompassTimeout = settingsGetPointer()->timeoutInfoCompass; | 61 tInfoCompassTimeout = settingsGetPointer()->timeoutInfoCompass; |
| 49 tInfoCompassTimeout *= 10; | 62 tInfoCompassTimeout *= 10; |
| 50 | 63 |
| 64 for(axisIndex = 0; axisIndex < 3; axisIndex++) | |
| 65 { | |
| 66 memset(axis[axisIndex].check,0, 360); | |
| 67 } | |
| 68 for(angle = 170; angle < 360; angle++) | |
| 69 { | |
| 70 axis[PITCH].check[angle] = 1; /* pitch only from -90 to +90 */ | |
| 71 } | |
| 72 axis[YAW].coord.x = 100; | |
| 73 axis[YAW].coord.y = 70; | |
| 74 axis[PITCH].coord.x = 100; | |
| 75 axis[PITCH].coord.y = 300; | |
| 76 axis[ROLL].coord.x = 100; | |
| 77 axis[ROLL].coord.y = 200; | |
| 78 | |
| 79 axis[YAW].eclipse.x = 50; | |
| 80 axis[YAW].eclipse.y = 50; | |
| 81 axis[PITCH].eclipse.x = 20; | |
| 82 axis[PITCH].eclipse.y = 50; | |
| 83 axis[ROLL].eclipse.x = 50; | |
| 84 axis[ROLL].eclipse.y = 20; | |
| 85 | |
| 51 for(int i = 0; i<3;i ++) | 86 for(int i = 0; i<3;i ++) |
| 52 { | 87 { |
| 53 minMaxCompassDX[i][0] = 999; | 88 minMaxCompassDX[i][0] = 999; |
| 54 minMaxCompassDX[i][1] = -999; | 89 minMaxCompassDX[i][1] = -999; |
| 55 } | 90 } |
| 91 checkTick = HAL_GetTick(); | |
| 92 | |
| 93 activeAxis = PITCH; | |
| 56 } | 94 } |
| 57 | 95 |
| 58 | 96 void getElipsePoint(uint16_t elipseX , int16_t elipseY, int16_t degree, int16_t *x, int16_t *y) |
| 97 { | |
| 98 double rad = degree * (PI / 180.0); | |
| 99 *x = (int16_t) (elipseX * cos(rad)); | |
| 100 *y = (int16_t) (elipseY * sin(rad)); | |
| 101 } | |
| 59 // =============================================================================== | 102 // =============================================================================== |
| 60 // refreshInfo_Compass | 103 // refreshInfo_Compass |
| 61 /// @brief there is only compass_DX_f, compass_DY_f, compass_DZ_f output during this mode | 104 /// @brief there is only compass_DX_f, compass_DY_f, compass_DZ_f output during this mode |
| 62 /// the accel is not called during this process | 105 /// the accel is not called during this process |
| 63 // =============================================================================== | 106 // =============================================================================== |
| 64 void refreshInfo_Compass(GFX_DrawCfgScreen s) | 107 void refreshInfo_Compass(GFX_DrawCfgScreen s) |
| 65 { | 108 { |
| 109 static int16_t cursorAngle = 0; | |
| 110 | |
| 111 int16_t angle = 0.0; | |
| 112 int16_t drawX = 0; | |
| 113 int16_t drawY = 0; | |
| 114 uint8_t color = 0; | |
| 115 point_t start; | |
| 116 point_t stop; | |
| 117 point_t center; | |
| 118 | |
| 119 int8_t offset = 0; | |
| 120 uint8_t axisIndex = 0; | |
| 121 int16_t index = 0; | |
| 122 uint8_t textIndex = 0; | |
| 66 | 123 |
| 67 tHome_show_lost_connection_count(&s); | 124 tHome_show_lost_connection_count(&s); |
| 68 tInfoCompassTimeout--; | 125 tInfoCompassTimeout--; |
| 69 if(tInfoCompassTimeout == 0) | 126 if(tInfoCompassTimeout == 0) |
| 70 { | 127 { |
| 78 | 135 |
| 79 compassValues[0] = stateUsed->lifeData.compass_DX_f; | 136 compassValues[0] = stateUsed->lifeData.compass_DX_f; |
| 80 compassValues[1] = stateUsed->lifeData.compass_DY_f; | 137 compassValues[1] = stateUsed->lifeData.compass_DY_f; |
| 81 compassValues[2] = stateUsed->lifeData.compass_DZ_f; | 138 compassValues[2] = stateUsed->lifeData.compass_DZ_f; |
| 82 | 139 |
| 140 /* draw indicator */ | |
| 141 for(axisIndex = 0; axisIndex < 3; axisIndex++) | |
| 142 { | |
| 143 switch(axisIndex) | |
| 144 { | |
| 145 default: | |
| 146 case YAW: index = (uint16_t)(stateUsed->lifeData.compass_heading); | |
| 147 textIndex = snprintf(text,80,"yaw %.1f", stateUsed->lifeData.compass_heading); | |
| 148 | |
| 149 if((tInfoCompassTimeout < 50) && (activeAxis == YAW)) | |
| 150 { | |
| 151 snprintf(&text[textIndex],80,"\023\t(%i, %i)", minMaxCompassDX[YAW][0], minMaxCompassDX[YAW][1]); | |
| 152 } | |
| 153 | |
| 154 start.x = axis[axisIndex].coord.x - 1; | |
| 155 start.y = axis[axisIndex].coord.y; | |
| 156 stop.x = axis[axisIndex].coord.x + 1; | |
| 157 stop.y = axis[axisIndex].coord.y; | |
| 158 break; | |
| 159 case PITCH: index = (uint16_t)(stateUsed->lifeData.compass_pitch + 90); | |
| 160 textIndex = snprintf(text,80,"pitch %.1f", stateUsed->lifeData.compass_pitch); | |
| 161 if((tInfoCompassTimeout < 50) && (activeAxis == YAW)) | |
| 162 { | |
| 163 snprintf(&text[textIndex],80,"\023\t(%i, %i)", minMaxCompassDX[PITCH][0], minMaxCompassDX[PITCH][1]); | |
| 164 } | |
| 165 start.x = axis[axisIndex].coord.x - 30; | |
| 166 start.y = axis[axisIndex].coord.y; | |
| 167 stop.x = axis[axisIndex].coord.x + 30; | |
| 168 stop.y = axis[axisIndex].coord.y; | |
| 169 | |
| 170 break; | |
| 171 case ROLL: index = (uint16_t)(stateUsed->lifeData.compass_roll + 180); | |
| 172 textIndex = snprintf(text,80,"roll %.1f", stateUsed->lifeData.compass_roll); | |
| 173 if((tInfoCompassTimeout < 50) && (activeAxis == YAW)) | |
| 174 { | |
| 175 snprintf(&text[textIndex],80,"\023\t(%i, %i)", minMaxCompassDX[ROLL][0], minMaxCompassDX[ROLL][1]); | |
| 176 } | |
| 177 start.x = axis[axisIndex].coord.x; | |
| 178 start.y = axis[axisIndex].coord.y - 30; | |
| 179 stop.x = axis[axisIndex].coord.x; | |
| 180 stop.y = axis[axisIndex].coord.y +30; | |
| 181 break; | |
| 182 } | |
| 183 if(settingsGetPointer()->FlipDisplay) | |
| 184 { | |
| 185 start.x = 800 - start.x; | |
| 186 stop.x = 800 - stop.x; | |
| 187 start.y = 480 - start.y; | |
| 188 stop.y = 480 - stop.y; | |
| 189 } | |
| 190 if(activeAxis == axisIndex) /* only check one axis at a time. reason: yaw will be unstable at the beginning of calibration */ | |
| 191 { | |
| 192 for(offset = -6; offset <= 6; offset++) /* it is hard to hit every single angle and the resolution is not needed */ | |
| 193 { | |
| 194 if(( (index + offset) >= 0) && (index + offset < 360)) | |
| 195 { | |
| 196 axis[axisIndex].check[index + offset] = 1; /* => check surrounding angles as well */ | |
| 197 } | |
| 198 } | |
| 199 } | |
| 200 if(axisIndex == activeAxis) | |
| 201 { | |
| 202 color = CLUT_InfoCompass; | |
| 203 getElipsePoint(axis[axisIndex].eclipse.x,axis[axisIndex].eclipse.y,cursorAngle, &drawX, &drawY); | |
| 204 center.x = axis[axisIndex].coord.x + drawX; | |
| 205 center.y = axis[axisIndex].coord.y + drawY; | |
| 206 | |
| 207 t_Info_draw_circle(center, 4, CLUT_Font020); | |
| 208 cursorAngle += 15; | |
| 209 if(cursorAngle >= 360) | |
| 210 { | |
| 211 cursorAngle = 0; | |
| 212 } | |
| 213 } | |
| 214 else | |
| 215 { | |
| 216 color = CLUT_Font021; | |
| 217 } | |
| 218 tInfo_write_content_simple( 200, 600, 480 - axis[axisIndex].coord.y - 35 , &FontT42, text, color); | |
| 219 tInfo_draw_colorline(start, stop, CLUT_Font020); | |
| 220 for(angle = 0; angle < 360; angle = angle + 3) | |
| 221 { | |
| 222 if(axis[axisIndex].check[angle]) | |
| 223 { | |
| 224 color = CLUT_NiceGreen; | |
| 225 } | |
| 226 else | |
| 227 { | |
| 228 color = CLUT_WarningRed; | |
| 229 } | |
| 230 getElipsePoint(axis[axisIndex].eclipse.x,axis[axisIndex].eclipse.y,angle, &drawX, &drawY); | |
| 231 tInfo_drawPixel(axis[axisIndex].coord.x + drawX, axis[axisIndex].coord.y + drawY,color); | |
| 232 if((axisIndex == PITCH) && (angle == 180)) /* pitch only from -90 to +90 */ | |
| 233 { | |
| 234 break; | |
| 235 } | |
| 236 } | |
| 237 | |
| 238 } | |
| 239 | |
| 83 for(int i = 0; i<3;i ++) | 240 for(int i = 0; i<3;i ++) |
| 84 { | 241 { |
| 85 // do not accept zero | 242 // do not accept zero |
| 86 if(minMaxCompassDX[i][0] == 0) | 243 if(minMaxCompassDX[i][0] == 0) |
| 87 minMaxCompassDX[i][0] = compassValues[i]; | 244 minMaxCompassDX[i][0] = compassValues[i]; |
| 98 } | 255 } |
| 99 | 256 |
| 100 snprintf(text,80,"Time left: %u s",(tInfoCompassTimeout+9)/10); | 257 snprintf(text,80,"Time left: %u s",(tInfoCompassTimeout+9)/10); |
| 101 tInfo_write_content_simple( 20,800, 25, &FontT42, text, CLUT_InfoCompass); | 258 tInfo_write_content_simple( 20,800, 25, &FontT42, text, CLUT_InfoCompass); |
| 102 | 259 |
| 103 for(int i = 0; i<3;i ++) | 260 |
| 104 { | 261 if(time_elapsed_ms(checkTick, HAL_GetTick() > 1000)) |
| 105 snprintf(text,80,"%c: %i" "\t(%i, %i)", | 262 { |
| 106 'X'+i, | 263 index = 0; |
| 107 compassValues[i], | 264 for(angle = 0; angle < 360; angle++) |
| 108 minMaxCompassDX[i][0], | 265 { |
| 109 minMaxCompassDX[i][1]); | 266 if(axis[activeAxis].check[angle]) |
| 110 tInfo_write_content_simple( 20,800, 96 + (i*96), &FontT48, text, CLUT_InfoCompass); | 267 { |
| 111 } | 268 index++; |
| 112 | 269 } |
| 113 snprintf(text,80,"roll %.1f" "\tpitch %.1f", | 270 } |
| 114 stateUsed->lifeData.compass_roll, | 271 if(index > 350) |
| 115 stateUsed->lifeData.compass_pitch); | 272 { |
| 116 tInfo_write_content_simple( 20,800, 96 * 4, &FontT42, text, CLUT_InfoCompass); | 273 if(activeAxis < 2) |
| 274 { | |
| 275 activeAxis++; | |
| 276 } | |
| 277 else | |
| 278 { | |
| 279 if(tInfoCompassTimeout > 50) | |
| 280 { | |
| 281 tInfoCompassTimeout = 50; /* reduce exit time to five seconds */ | |
| 282 } | |
| 283 } | |
| 284 } | |
| 285 | |
| 286 | |
| 287 checkTick = HAL_GetTick(); | |
| 288 } | |
| 117 } | 289 } |
