Skip to content

Commit f5d1402

Browse files
authored
Flydigi Vader 4 Pro IMU rate correction (#13215)
Flydigi IMU rate now matches observed rate of packets in both dongle and wired connection. Flydigi Vader 4 Pro IMU rate correction was set at a fixed 125hz. In actuality rate is 1000hz over dongle and 500hz when wired.
1 parent 1e886c8 commit f5d1402

File tree

1 file changed

+33
-16
lines changed

1 file changed

+33
-16
lines changed

src/joystick/hidapi/SDL_hidapi_flydigi.c

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,13 @@ enum
4242
SDL_GAMEPAD_NUM_BASE_FLYDIGI_BUTTONS
4343
};
4444

45-
#define SENSOR_INTERVAL_NS 8000000ULL
45+
/* Rate of IMU Sensor Packets over wireless Dongle observed in testcontroller tool at 1000hz */
46+
#define SENSOR_INTERVAL_VADER4_PRO_DONGLE_RATE_HZ 1000
47+
#define SENSOR_INTERVAL_VADER4_PRO_DONGLE_NS (SDL_NS_PER_SECOND / SENSOR_INTERVAL_VADER4_PRO_DONGLE_RATE_HZ)
48+
/* Rate of IMU Sensor Packets over wired observed in testcontroller tool connection at 500hz */
49+
#define SENSOR_INTERVAL_VADER_PRO4_WIRED_RATE_HZ 500
50+
#define SENSOR_INTERVAL_VADER_PRO4_WIRED_NS (SDL_NS_PER_SECOND / SENSOR_INTERVAL_VADER_PRO4_WIRED_RATE_HZ)
51+
4652
#define FLYDIGI_CMD_REPORT_ID 0x05
4753
#define FLYDIGI_HAPTIC_COMMAND 0x0F
4854
#define FLYDIGI_GET_CONFIG_COMMAND 0xEB
@@ -58,7 +64,8 @@ typedef struct
5864
bool sensors_supported;
5965
bool sensors_enabled;
6066
Uint16 firmware_version;
61-
Uint64 sensor_timestamp; // Microseconds. Simulate onboard clock. Advance by known rate: SENSOR_INTERVAL_NS == 8ms = 125 Hz
67+
Uint64 sensor_timestamp_ns; // Simulate onboard clock. Advance by known time step. Nanoseconds.
68+
Uint64 sensor_timestamp_step_ns; // Based on observed rate of receipt of IMU sensor packets.
6269
float accelScale;
6370
Uint8 last_state[USB_PACKET_LENGTH];
6471
} SDL_DriverFlydigi_Context;
@@ -163,6 +170,10 @@ static void UpdateDeviceIdentity(SDL_HIDAPI_Device *device)
163170
}
164171
device->guid.data[15] = ctx->deviceID;
165172

173+
// This is the previous sensor default of 125hz.
174+
// Override this in the switch statement below based on observed sensor packet rate.
175+
ctx->sensor_timestamp_step_ns = SDL_NS_PER_SECOND / 125;
176+
166177
switch (ctx->deviceID) {
167178
case 19:
168179
HIDAPI_SetDeviceName(device, "Flydigi Apex 2");
@@ -197,12 +208,14 @@ static void UpdateDeviceIdentity(SDL_HIDAPI_Device *device)
197208
ctx->has_cz = true;
198209
ctx->sensors_supported = true;
199210
ctx->accelScale = SDL_STANDARD_GRAVITY / 256.0f;
211+
ctx->sensor_timestamp_step_ns = ctx->wireless ? SENSOR_INTERVAL_VADER4_PRO_DONGLE_NS : SENSOR_INTERVAL_VADER_PRO4_WIRED_NS;
200212
break;
201213
case 85:
202214
HIDAPI_SetDeviceName(device, "Flydigi Vader 4 Pro");
203215
ctx->has_cz = true;
204216
ctx->sensors_supported = true;
205217
ctx->accelScale = SDL_STANDARD_GRAVITY / 256.0f;
218+
ctx->sensor_timestamp_step_ns = ctx->wireless ? SENSOR_INTERVAL_VADER4_PRO_DONGLE_NS : SENSOR_INTERVAL_VADER_PRO4_WIRED_NS;
206219
break;
207220
default:
208221
break;
@@ -256,8 +269,10 @@ static bool HIDAPI_DriverFlydigi_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joy
256269
}
257270

258271
if (ctx->sensors_supported) {
259-
SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO, 125.0f);
260-
SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL, 125.0f);
272+
273+
const float flSensorRate = ctx->wireless ? (float)SENSOR_INTERVAL_VADER4_PRO_DONGLE_RATE_HZ : (float)SENSOR_INTERVAL_VADER_PRO4_WIRED_RATE_HZ;
274+
SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO, flSensorRate);
275+
SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL, flSensorRate);
261276
}
262277

263278
return true;
@@ -411,18 +426,20 @@ static void HIDAPI_DriverFlydigi_HandleStatePacket(SDL_Joystick *joystick, SDL_D
411426
Uint64 sensor_timestamp;
412427
float values[3];
413428

414-
// Note: we cannot use the time stamp of the receiving computer due to packet delay creating "spiky" timings.
415-
// The imu time stamp is intended to be the sample time of the on-board hardware.
416-
// In the absence of time stamp data from the data[], we can simulate that by
417-
// advancing a time stamp by the observed/known imu clock rate. This is 8ms = 125 Hz
418-
sensor_timestamp = ctx->sensor_timestamp;
419-
ctx->sensor_timestamp += SENSOR_INTERVAL_NS;
420-
421-
// This device's IMU values are reported differently from SDL
422-
// Thus we perform a rotation of the coordinate system to match the SDL standard.
423-
values[0] = -LOAD16(data[26], data[27]) * DEG2RAD(65536) / INT16_MAX; // Rotation around pitch axis
424-
values[1] = -LOAD16(data[18], data[20]) * DEG2RAD(65536) / INT16_MAX; // Rotation around yaw axis
425-
values[2] = -LOAD16(data[29], data[30]) * DEG2RAD(1024) / INT16_MAX; // Rotation around roll axis
429+
// Advance the imu sensor time stamp based on the observed rate of receipt of packets in the testcontroller app.
430+
// This varies between Product ID and connection type.
431+
sensor_timestamp = ctx->sensor_timestamp_ns;
432+
ctx->sensor_timestamp_ns += ctx->sensor_timestamp_step_ns;
433+
434+
// Pitch and yaw scales may be receiving extra filtering for the sake of bespoke direct mouse output.
435+
// As result, roll has a different scaling factor than pitch and yaw.
436+
// These values were estimated using the testcontroller tool in lieux of hard data sheet references.
437+
const float flPitchAndYawScale = DEG2RAD(72000.0f);
438+
const float flRollScale = DEG2RAD(1200.0f);
439+
values[0] = HIDAPI_RemapVal(-1.0f * LOAD16(data[26], data[27]), INT16_MIN, INT16_MAX, -flPitchAndYawScale, flPitchAndYawScale);
440+
values[1] = HIDAPI_RemapVal(-1.0f * LOAD16(data[18], data[20]), INT16_MIN, INT16_MAX, -flPitchAndYawScale, flPitchAndYawScale);
441+
values[2] = HIDAPI_RemapVal(-1.0f * LOAD16(data[29], data[30]), INT16_MIN, INT16_MAX, -flRollScale, flRollScale);
442+
426443
SDL_SendJoystickSensor(timestamp, joystick, SDL_SENSOR_GYRO, sensor_timestamp, values, 3);
427444

428445
values[0] = -LOAD16(data[11], data[12]) * ctx->accelScale; // Acceleration along pitch axis

0 commit comments

Comments
 (0)