42
42
SDL_GAMEPAD_NUM_BASE_FLYDIGI_BUTTONS
43
43
};
44
44
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
+
46
52
#define FLYDIGI_CMD_REPORT_ID 0x05
47
53
#define FLYDIGI_HAPTIC_COMMAND 0x0F
48
54
#define FLYDIGI_GET_CONFIG_COMMAND 0xEB
@@ -58,7 +64,8 @@ typedef struct
58
64
bool sensors_supported ;
59
65
bool sensors_enabled ;
60
66
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.
62
69
float accelScale ;
63
70
Uint8 last_state [USB_PACKET_LENGTH ];
64
71
} SDL_DriverFlydigi_Context ;
@@ -163,6 +170,10 @@ static void UpdateDeviceIdentity(SDL_HIDAPI_Device *device)
163
170
}
164
171
device -> guid .data [15 ] = ctx -> deviceID ;
165
172
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
+
166
177
switch (ctx -> deviceID ) {
167
178
case 19 :
168
179
HIDAPI_SetDeviceName (device , "Flydigi Apex 2" );
@@ -197,12 +208,14 @@ static void UpdateDeviceIdentity(SDL_HIDAPI_Device *device)
197
208
ctx -> has_cz = true;
198
209
ctx -> sensors_supported = true;
199
210
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 ;
200
212
break ;
201
213
case 85 :
202
214
HIDAPI_SetDeviceName (device , "Flydigi Vader 4 Pro" );
203
215
ctx -> has_cz = true;
204
216
ctx -> sensors_supported = true;
205
217
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 ;
206
219
break ;
207
220
default :
208
221
break ;
@@ -256,8 +269,10 @@ static bool HIDAPI_DriverFlydigi_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joy
256
269
}
257
270
258
271
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 );
261
276
}
262
277
263
278
return true;
@@ -411,18 +426,20 @@ static void HIDAPI_DriverFlydigi_HandleStatePacket(SDL_Joystick *joystick, SDL_D
411
426
Uint64 sensor_timestamp ;
412
427
float values [3 ];
413
428
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
+
426
443
SDL_SendJoystickSensor (timestamp , joystick , SDL_SENSOR_GYRO , sensor_timestamp , values , 3 );
427
444
428
445
values [0 ] = - LOAD16 (data [11 ], data [12 ]) * ctx -> accelScale ; // Acceleration along pitch axis
0 commit comments