Skip to content

Commit 1e886c8

Browse files
authored
8 bitdo polling rate corrections (#13221)
Gathered correct IMU polling rate in wired mode for good gyro synchronization. Wireless: different models had different amounts of Bluetooth packet loss. USB_PRODUCT_8BITDO_ULTIMATE2_WIRELESS: Solid 120hz over bluetooth (note: only appears via). USB_PRODUCT_8BITDO_PRO_2_BT: Lossy - 80-90hz registered. SB_PRODUCT_8BITDO_SN30_PRO_BT & USB_PRODUCT_8BITDO_SN30_PRO_BT: Very Lossy - 60-90hz registered
1 parent 913b611 commit 1e886c8

File tree

1 file changed

+30
-6
lines changed

1 file changed

+30
-6
lines changed

src/joystick/hidapi/SDL_hidapi_8bitdo.c

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,6 @@ enum
4848
#define SDL_8BITDO_BT_REPORTID_SDL_REPORTID 0x01
4949

5050
#define ABITDO_ACCEL_SCALE 4096.f
51-
#define ABITDO_SENSOR_POLLING_RATE 125.f
52-
#define SENSOR_INTERVAL_NS 8000000ULL
5351
#define ABITDO_GYRO_MAX_DEGREES_PER_SECOND 2000.f
5452

5553
typedef struct
@@ -69,7 +67,8 @@ typedef struct
6967
float accelScale;
7068
float gyroScale;
7169
Uint8 last_state[USB_PACKET_LENGTH];
72-
Uint64 sensor_timestamp; // Nanoseconds. Simulate onboard clock. Advance by known rate: SENSOR_INTERVAL_NS == 8ms = 125 Hz
70+
Uint64 sensor_timestamp; // Nanoseconds. Simulate onboard clock. Different models have different rates vs different connection styles.
71+
Uint64 sensor_timestamp_interval;
7372
} SDL_Driver8BitDo_Context;
7473

7574
#pragma pack(push,1)
@@ -217,6 +216,27 @@ static void HIDAPI_Driver8BitDo_SetDevicePlayerIndex(SDL_HIDAPI_Device *device,
217216
{
218217
}
219218

219+
static Uint64 HIDAPI_Driver8BitDo_GetIMURateForProductID(SDL_HIDAPI_Device *device)
220+
{
221+
// TODO: If sensor time stamp is sent, these fixed settings from observation can be replaced
222+
switch (device->product_id) {
223+
// Note, This is estimated by observation of Bluetooth packets received in the testcontroller tool
224+
case USB_PRODUCT_8BITDO_SN30_PRO_BT:
225+
case USB_PRODUCT_8BITDO_SF30_PRO_BT:
226+
return 90; // Observed to be anywhere between 60-90 hz. Possibly lossy in current state
227+
case USB_PRODUCT_8BITDO_SF30_PRO:
228+
case USB_PRODUCT_8BITDO_SN30_PRO:
229+
return 100;
230+
case USB_PRODUCT_8BITDO_PRO_2:
231+
case USB_PRODUCT_8BITDO_PRO_2_BT:// Note, labelled as "BT" but appears this way when wired. Observed bluetooth packet rate seems to be 80-90hz
232+
return (device->is_bluetooth ? 85 : 100);
233+
case USB_PRODUCT_8BITDO_ULTIMATE2_WIRELESS:
234+
default:
235+
return 120;
236+
break;
237+
}
238+
}
239+
220240
#ifndef DEG2RAD
221241
#define DEG2RAD(x) ((float)(x) * (float)(SDL_PI_F / 180.f))
222242
#endif
@@ -242,9 +262,13 @@ static bool HIDAPI_Driver8BitDo_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joys
242262
joystick->nhats = 1;
243263

244264
if (ctx->sensors_supported) {
245-
SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO, ABITDO_SENSOR_POLLING_RATE);
246-
SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL, ABITDO_SENSOR_POLLING_RATE);
247265

266+
// Different 8Bitdo controllers in different connection modes have different polling rates.
267+
const Uint64 imu_polling_rate = HIDAPI_Driver8BitDo_GetIMURateForProductID(device);
268+
ctx->sensor_timestamp_interval = SDL_NS_PER_SECOND / imu_polling_rate;
269+
270+
SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO, (float)imu_polling_rate);
271+
SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL, (float)imu_polling_rate);
248272

249273
ctx->accelScale = SDL_STANDARD_GRAVITY / ABITDO_ACCEL_SCALE;
250274
// Hardware senses +/- N Degrees per second mapped to +/- INT16_MAX
@@ -525,7 +549,7 @@ static void HIDAPI_Driver8BitDo_HandleStatePacket(SDL_Joystick *joystick, SDL_Dr
525549
// In the absence of time stamp data from the data[], we can simulate that by
526550
// advancing a time stamp by the observed/known imu clock rate. This is 8ms = 125 Hz
527551
sensor_timestamp = ctx->sensor_timestamp;
528-
ctx->sensor_timestamp += SENSOR_INTERVAL_NS;
552+
ctx->sensor_timestamp += ctx->sensor_timestamp_interval;
529553

530554
// This device's IMU values are reported differently from SDL
531555
// Thus we perform a rotation of the coordinate system to match the SDL standard.

0 commit comments

Comments
 (0)