mirror of
https://github.com/FWGS/xash3d-fwgs.git
synced 2026-08-08 05:11:51 +08:00
engine: platform: sdl2: implement continuous background recalibration for gyroscope
This commit is contained in:
@@ -52,15 +52,16 @@ static SDL_GameController *g_current_gamepad;
|
||||
static SDL_GameController **g_gamepads;
|
||||
static size_t g_num_gamepads;
|
||||
|
||||
#define CALIBRATION_TIME 10.0f
|
||||
#define CALIBRATION_TIME 5.0f
|
||||
|
||||
static struct
|
||||
{
|
||||
float time;
|
||||
vec3_t data;
|
||||
vec3_t calibrated_values;
|
||||
float data_rate;
|
||||
int samples;
|
||||
float time;
|
||||
vec3_t data;
|
||||
vec3_t calibrated_values;
|
||||
float data_rate;
|
||||
int samples;
|
||||
qboolean continuous; // true after first successful calibration
|
||||
} gyrocal;
|
||||
|
||||
static void SDLash_RestartCalibration( void )
|
||||
@@ -77,7 +78,7 @@ static void SDLash_RestartCalibration( void )
|
||||
if( !gyrocal.data_rate )
|
||||
gyrocal.data_rate = 10.0f;
|
||||
|
||||
Con_Printf( "Starting gyroscope calibration at %g data rate...\n", gyrocal.data_rate );
|
||||
Con_Printf( S_NOTE "Starting gyroscope calibration at %g data rate for %g seconds...\n", gyrocal.data_rate, CALIBRATION_TIME );
|
||||
}
|
||||
|
||||
static void SDLash_FinalizeCalibration( void )
|
||||
@@ -87,14 +88,53 @@ static void SDLash_FinalizeCalibration( void )
|
||||
// we waited for few seconds and got too few samples
|
||||
if( gyrocal.samples <= min_samples )
|
||||
{
|
||||
Joy_SetCalibrationState( JOY_FAILED_TO_CALIBRATE );
|
||||
Con_Printf( "Calibration failed, got samples %d < %d\n", gyrocal.samples, min_samples );
|
||||
return;
|
||||
if( !gyrocal.continuous )
|
||||
{
|
||||
Joy_SetCalibrationState( JOY_FAILED_TO_CALIBRATE );
|
||||
Con_Printf( S_ERROR "Calibration failed, got samples %d < %d\n", gyrocal.samples, min_samples );
|
||||
gyrocal.time = 0.0f;
|
||||
return;
|
||||
}
|
||||
// Con_Reportf( S_WARN "Continuous calibration: too few samples (%d < %d), retrying\n", gyrocal.samples, min_samples );
|
||||
}
|
||||
else
|
||||
{
|
||||
VectorScale( gyrocal.data, 1.0f / gyrocal.samples, gyrocal.calibrated_values );
|
||||
Joy_SetCalibrationState( JOY_CALIBRATED );
|
||||
if( !gyrocal.continuous )
|
||||
Con_Printf( "Calibration done. Result: %f %f %f at %d samples\n", gyrocal.calibrated_values[0], gyrocal.calibrated_values[1], gyrocal.calibrated_values[2], gyrocal.samples );
|
||||
// else
|
||||
// Con_Reportf( "Continuous calibration done. Result: %f %f %f at %d samples\n", gyrocal.calibrated_values[0], gyrocal.calibrated_values[1], gyrocal.calibrated_values[2], gyrocal.samples );
|
||||
gyrocal.continuous = true;
|
||||
}
|
||||
|
||||
VectorScale( gyrocal.data, 1.0f / gyrocal.samples, gyrocal.calibrated_values );
|
||||
Joy_SetCalibrationState( JOY_CALIBRATED );
|
||||
Con_Printf( "Calibration done. Result: %f %f %f at %d samples\n", gyrocal.calibrated_values[0], gyrocal.calibrated_values[1], gyrocal.calibrated_values[2], gyrocal.samples );
|
||||
// schedule next calibration window
|
||||
VectorClear( gyrocal.data );
|
||||
gyrocal.samples = 0;
|
||||
gyrocal.time = host.realtime + CALIBRATION_TIME;
|
||||
}
|
||||
|
||||
static void SDLash_AccumulateCalibrationData( vec3_t data )
|
||||
{
|
||||
// for continuous background calibration only listen for noise
|
||||
// by comparing it with calibrated values
|
||||
//
|
||||
// for first calibration this might be hurtful as device might
|
||||
// output offset data
|
||||
if( gyrocal.continuous )
|
||||
{
|
||||
vec3_t calibrated;
|
||||
VectorSubtract( data, gyrocal.calibrated_values, calibrated );
|
||||
|
||||
if( VectorLength( calibrated ) > 0.1f )
|
||||
return;
|
||||
}
|
||||
|
||||
VectorAdd( gyrocal.data, data, gyrocal.data );
|
||||
gyrocal.samples++;
|
||||
|
||||
if( !gyrocal.continuous )
|
||||
Joy_SetCalibrationState( JOY_CALIBRATING );
|
||||
}
|
||||
|
||||
static void SDLash_GameControllerAddMappings( const char *name )
|
||||
@@ -239,17 +279,13 @@ static void SDLash_GameControllerSensorUpdate( SDL_ControllerSensorEvent sensor
|
||||
if( gyrocal.time != 0.0f )
|
||||
{
|
||||
if( host.realtime > gyrocal.time )
|
||||
{
|
||||
SDLash_FinalizeCalibration();
|
||||
gyrocal.time = 0.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
VectorAdd( gyrocal.data, sensor.data, gyrocal.data );
|
||||
gyrocal.samples++;
|
||||
Joy_SetCalibrationState( JOY_CALIBRATING );
|
||||
}
|
||||
return;
|
||||
SDLash_AccumulateCalibrationData( sensor.data );
|
||||
|
||||
// block gyro events only during initial calibration
|
||||
if( !gyrocal.continuous )
|
||||
return;
|
||||
}
|
||||
|
||||
VectorSubtract( sensor.data, gyrocal.calibrated_values, data );
|
||||
|
||||
Reference in New Issue
Block a user