Skip to content

Commit f62c982

Browse files
committed
Reverted Accelerometer and Gyro displays to throttled display (10hz)
Also made accelerometer threshold for drift calibration more lenient for very noisy accelerometers. The testcontroller tool could eventually be used to come up with a better way to profile an IMU's "stationary" noise so that this threshold can be as tight as necessary for the sake of automatic drift calibration. (thanks @HilariousCow!)
1 parent b833c61 commit f62c982

File tree

3 files changed

+26
-25
lines changed

3 files changed

+26
-25
lines changed

test/gamepadutils.c

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ typedef struct
4242

4343
struct Quaternion
4444
{
45-
float x, y, z, w;
45+
float x, y, z, w;
4646
};
4747

4848
static const Vector3 debug_cube_vertices[] = {
@@ -227,15 +227,15 @@ void DrawAccelerometerDebugArrow(SDL_Renderer *renderer, const Quaternion *gyro_
227227
SDL_FPoint accel_screen = ProjectVec3ToRect(&rotated_accel, bounds);
228228

229229
/* Draw the line from origin to the rotated accelerometer vector */
230-
SDL_SetRenderDrawColor(renderer, GYRO_COLOR_ORANGE);
230+
SDL_SetRenderDrawColor(renderer, GYRO_COLOR_ORANGE);
231231
SDL_RenderLine(renderer, origin_screen.x, origin_screen.y, accel_screen.x, accel_screen.y);
232232

233233
const float head_width = 4.0f;
234234
SDL_FRect arrow_head_rect;
235-
arrow_head_rect.x = accel_screen.x - head_width * 0.5f;
235+
arrow_head_rect.x = accel_screen.x - head_width * 0.5f;
236236
arrow_head_rect.y = accel_screen.y - head_width * 0.5f;
237-
arrow_head_rect.w = head_width;
238-
arrow_head_rect.h = head_width;
237+
arrow_head_rect.w = head_width;
238+
arrow_head_rect.h = head_width;
239239
SDL_RenderRect(renderer, &arrow_head_rect);
240240

241241
/* Restore current color */
@@ -1024,7 +1024,7 @@ void SetGyroDisplayArea(GyroDisplay *ctx, const SDL_FRect *area)
10241024
}
10251025

10261026
SDL_copyp(&ctx->area, area);
1027-
1027+
10281028
/* Place the reset button to the bottom right of the gyro display area.*/
10291029
SDL_FRect reset_button_area;
10301030
reset_button_area.w = SDL_max(MINIMUM_BUTTON_WIDTH, GetGamepadButtonLabelWidth(ctx->reset_gyro_button) + 2 * BUTTON_PADDING);
@@ -1611,8 +1611,7 @@ void RenderGamepadDisplay(GamepadDisplay *ctx, SDL_Gamepad *gamepad)
16111611
has_gyro = SDL_GamepadHasSensor(gamepad, SDL_SENSOR_GYRO);
16121612

16131613
if (has_accel || has_gyro) {
1614-
const float gyro_sensor_rate = has_gyro ? SDL_GetGamepadSensorDataRate(gamepad, SDL_SENSOR_GYRO) : 0;
1615-
const int SENSOR_UPDATE_INTERVAL_MS = gyro_sensor_rate > 0.0f ? (int)( 1000.0f / gyro_sensor_rate ) : 100;
1614+
const int SENSOR_UPDATE_INTERVAL_MS = 100;
16161615
Uint64 now = SDL_GetTicks();
16171616

16181617
if (now >= ctx->last_sensor_update + SENSOR_UPDATE_INTERVAL_MS) {
@@ -1622,6 +1621,7 @@ void RenderGamepadDisplay(GamepadDisplay *ctx, SDL_Gamepad *gamepad)
16221621
if (has_gyro) {
16231622
SDL_GetGamepadSensorData(gamepad, SDL_SENSOR_GYRO, ctx->gyro_data, SDL_arraysize(ctx->gyro_data));
16241623
}
1624+
ctx->last_sensor_update = now;
16251625
}
16261626

16271627
if (has_accel) {
@@ -1637,10 +1637,9 @@ void RenderGamepadDisplay(GamepadDisplay *ctx, SDL_Gamepad *gamepad)
16371637
SDLTest_DrawString(ctx->renderer, x + center - SDL_strlen(text) * FONT_CHARACTER_SIZE, y, text);
16381638
SDL_snprintf(text, sizeof(text), "[%.2f,%.2f,%.2f]%s/s", ctx->gyro_data[0] * RAD_TO_DEG, ctx->gyro_data[1] * RAD_TO_DEG, ctx->gyro_data[2] * RAD_TO_DEG, DEGREE_UTF8);
16391639
SDLTest_DrawString(ctx->renderer, x + center + 2.0f, y, text);
1640-
16411640

1642-
/* Display a smoothed version of the above for the sake of turntable tests */
16431641

1642+
/* Display the testcontroller tool's evaluation of drift. This is also useful to get an average rate of turn in calibrated turntable tests. */
16441643
if (ctx->gyro_drift_correction_data[0] != 0.0f && ctx->gyro_drift_correction_data[2] != 0.0f && ctx->gyro_drift_correction_data[2] != 0.0f )
16451644
{
16461645
y += ctx->button_height + 2.0f;
@@ -1652,7 +1651,7 @@ void RenderGamepadDisplay(GamepadDisplay *ctx, SDL_Gamepad *gamepad)
16521651

16531652
}
16541653

1655-
ctx->last_sensor_update = now;
1654+
16561655
}
16571656
}
16581657
SDL_free(mapping);
@@ -1782,7 +1781,7 @@ void RenderGyroDriftCalibrationButton(GyroDisplay *ctx, GamepadDisplay *gamepad_
17821781

17831782
/* Drift progress bar */
17841783
/* Demonstrate how far we are through the drift progress, and how it resets when there's "high noise", i.e if flNoiseFraction == 1.0f */
1785-
SDL_FRect progress_bar_rect;
1784+
SDL_FRect progress_bar_rect;
17861785
progress_bar_rect.x = recalibrate_button_area.x + BUTTON_PADDING;
17871786
progress_bar_rect.y = recalibrate_button_area.y + recalibrate_button_area.h * 0.5f + BUTTON_PADDING * 0.5f;
17881787
progress_bar_rect.w = recalibrate_button_area.w - BUTTON_PADDING * 2.0f;
@@ -1798,7 +1797,7 @@ void RenderGyroDriftCalibrationButton(GyroDisplay *ctx, GamepadDisplay *gamepad_
17981797

17991798
/* Set the color based on the drift calibration progress fraction */
18001799
SDL_SetRenderDrawColor(ctx->renderer, GYRO_COLOR_GREEN); /* red when too much noise, green when low noise*/
1801-
1800+
18021801
/* Now draw the bars with the filled, then empty rectangles */
18031802
SDL_RenderFillRect(ctx->renderer, &progress_bar_fill); /* draw the filled rectangle*/
18041803
SDL_SetRenderDrawColor(ctx->renderer, 100, 100, 100, 255); /* gray box*/
@@ -1830,12 +1829,12 @@ float RenderEulerReadout(GyroDisplay *ctx, GamepadDisplay *gamepad_display )
18301829

18311830
/* Yaw Readout */
18321831
log_y += new_line_height;
1833-
SDL_snprintf(text, sizeof(text), "Yaw: %6.2f%s", ctx->euler_displacement_angles[1], DEGREE_UTF8);
1832+
SDL_snprintf(text, sizeof(text), " Yaw: %6.2f%s", ctx->euler_displacement_angles[1], DEGREE_UTF8);
18341833
SDLTest_DrawString(ctx->renderer, log_gyro_euler_text_x + 2.0f, log_y, text);
18351834

18361835
/* Roll Readout */
18371836
log_y += new_line_height;
1838-
SDL_snprintf(text, sizeof(text), "Roll: %6.2f%s", ctx->euler_displacement_angles[2], DEGREE_UTF8);
1837+
SDL_snprintf(text, sizeof(text), " Roll: %6.2f%s", ctx->euler_displacement_angles[2], DEGREE_UTF8);
18391838
SDLTest_DrawString(ctx->renderer, log_gyro_euler_text_x + 2.0f, log_y, text);
18401839

18411840
return log_y + new_line_height; /* Return the next y position for further rendering */
@@ -1907,7 +1906,7 @@ void RenderGyroDisplay(GyroDisplay *ctx, GamepadDisplay *gamepadElements, SDL_Ga
19071906
if (bHasCachedDriftSolution) {
19081907
float bottom = RenderEulerReadout(ctx, gamepadElements);
19091908
RenderGyroGizmo(ctx, gamepad, bottom);
1910-
1909+
19111910
}
19121911
SDL_SetRenderDrawColor(ctx->renderer, r, g, b, a);
19131912
}

test/gamepadutils.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ extern void DestroyGamepadButton(GamepadButton *ctx);
143143

144144
/* Gyro element Display */
145145
/* If you want to calbirate against a known rotation (i.e. a turn table test) Increase ACCELEROMETER_NOISE_THRESHOLD to about 5, or drift correction will be constantly reset.*/
146-
#define ACCELEROMETER_NOISE_THRESHOLD 0.125f
146+
#define ACCELEROMETER_NOISE_THRESHOLD 0.5f
147147
typedef struct Quaternion Quaternion;
148148
typedef struct GyroDisplay GyroDisplay;
149149

test/testcontroller.c

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ typedef struct
147147
Uint64 gyro_packet_number;
148148
Uint64 accelerometer_packet_number;
149149
/* When both gyro and accelerometer events have been processed, we can increment this and use it to calculate polling rate over time.*/
150-
Uint64 imu_packet_counter;
150+
Uint64 imu_packet_counter;
151151

152152
Uint64 starting_time_stamp_ns; /* Use this to help estimate how many packets are received over a duration */
153153
Uint16 imu_estimated_sensor_rate; /* in Hz, used to estimate how many packets are received over a duration */
@@ -244,7 +244,7 @@ void SampleGyroPacketForDrift( IMUState *imustate )
244244
if (imustate->gyro_drift_sample_count >= SDL_GAMEPAD_IMU_MIN_GYRO_DRIFT_SAMPLE_COUNT) {
245245
FinalizeDriftSolution(imustate);
246246
}
247-
}
247+
}
248248
}
249249

250250
void ApplyDriftSolution(float *gyro_data, const float *drift_solution)
@@ -1409,24 +1409,26 @@ static void UpdateGamepadOrientation( Uint64 delta_time_ns )
14091409

14101410
static void HandleGamepadSensorEvent( SDL_Event* event )
14111411
{
1412-
if (!controller)
1413-
return;
1412+
if (!controller) {
1413+
return;
1414+
}
14141415

1415-
if (controller->id != event->gsensor.which)
1416+
if (controller->id != event->gsensor.which) {
14161417
return;
1418+
}
14171419

14181420
if (event->gsensor.sensor == SDL_SENSOR_GYRO) {
14191421
HandleGamepadGyroEvent(event);
14201422
} else if (event->gsensor.sensor == SDL_SENSOR_ACCEL) {
14211423
HandleGamepadAccelerometerEvent(event);
1422-
}
1424+
}
14231425

14241426
/*
14251427
This is where we can update the quaternion because we need to have a drift solution, which requires both
14261428
accelerometer and gyro events are received before progressing.
14271429
*/
14281430
if ( controller->imu_state->accelerometer_packet_number == controller->imu_state->gyro_packet_number ) {
1429-
1431+
14301432
EstimatePacketRate();
14311433
Uint64 sensorTimeStampDelta_ns = event->gsensor.sensor_timestamp - controller->imu_state->last_sensor_time_stamp_ns ;
14321434
UpdateGamepadOrientation(sensorTimeStampDelta_ns);
@@ -2071,7 +2073,7 @@ SDL_AppResult SDLCALL SDL_AppEvent(void *appstate, SDL_Event *event)
20712073
event->gsensor.data[1],
20722074
event->gsensor.data[2],
20732075
event->gsensor.sensor_timestamp);
2074-
2076+
20752077
#endif /* VERBOSE_SENSORS */
20762078
HandleGamepadSensorEvent(event);
20772079
break;

0 commit comments

Comments
 (0)