d/wmr: Decode and handle controller buttons, thumbstick and trackpad.

This commit is contained in:
Nima01 2021-11-27 04:31:13 +01:00
parent ce03824824
commit bdf96d6810
4 changed files with 93 additions and 98 deletions

View file

@ -69,7 +69,7 @@ read_packets(struct wmr_bt_controller *d)
switch (buffer[0]) {
case WMR_BT_MOTION_CONTROLLER_MSG:
// Note: skipping msg type byte
if (!wmr_controller_packet_parse(&buffer[1], (size_t)size - 1, &d->controller_message, d->log_level)) {
if (!wmr_controller_packet_parse(&buffer[1], (size_t)size - 1, &d->input, d->log_level)) {
WMR_ERROR(d, "WMR Controller (Bluetooth): Failed parsing message type: %02x, size: %i",
buffer[0], size);
return false;

View file

@ -54,8 +54,6 @@ struct wmr_bt_controller
struct os_thread_helper controller_thread;
struct os_mutex lock;
struct wmr_controller_message controller_message;
struct m_imu_3dof fusion;
struct
@ -70,24 +68,7 @@ struct wmr_bt_controller
uint32_t last_ticks;
struct
{
bool menu;
bool squeeze;
float trigger;
struct
{
bool click;
struct xrt_vec2 values;
} thumbstick;
struct
{
bool click;
bool touch;
struct xrt_vec2 values;
} trackpad;
} input;
struct wmr_controller_input input;
};

View file

@ -22,7 +22,7 @@
bool
wmr_controller_packet_parse(const unsigned char *buffer,
size_t len,
struct wmr_controller_message *out_message,
struct wmr_controller_input *decoded_input,
enum u_logging_level log_level)
{
if (len != 44) {
@ -30,53 +30,88 @@ wmr_controller_packet_parse(const unsigned char *buffer,
return false;
}
U_LOG_IFL_D(log_level,
"%02x %02x %02x %02x %02x %02x %02x %02x | " // buttons and inputs, battery
"%02x %02x %02x %02x %02x %02x %02x %02x %02x | " // accel
"%02x %02x | " // temp
"%02x %02x %02x %02x %02x %02x %02x %02x %02x | " // gyro
"%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x | " // timestamp and more?
"%02x %02x %02x %02x %02x %02x", // device run state, status and more?
buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5], buffer[6], buffer[7], buffer[8],
buffer[9], buffer[10], buffer[11], buffer[12], buffer[13], buffer[14], buffer[15], buffer[16],
buffer[17], buffer[18], buffer[19], buffer[20], buffer[21], buffer[22], buffer[23], buffer[24],
buffer[25], buffer[26], buffer[27], buffer[28], buffer[29], buffer[30], buffer[31], buffer[32],
buffer[33], buffer[34], buffer[35], buffer[36], buffer[37], buffer[38], buffer[39], buffer[40],
buffer[41], buffer[42], buffer[43]);
/*
U_LOG_IFL_D(log_level,
"%02x %02x %02x %02x %02x %02x %02x %02x | " // buttons and inputs, battery
"%02x %02x %02x %02x %02x %02x %02x %02x %02x | " // accel
"%02x %02x | " // temp
"%02x %02x %02x %02x %02x %02x %02x %02x %02x | " // gyro
"%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x | " // timestamp and more?
"%02x %02x %02x %02x %02x %02x", // device run state, status and more?
buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5], buffer[6], buffer[7],
buffer[8], buffer[9], buffer[10], buffer[11], buffer[12], buffer[13], buffer[14], buffer[15], buffer[16],
buffer[17], buffer[18], buffer[19], buffer[20], buffer[21], buffer[22], buffer[23],
buffer[24], buffer[25], buffer[26], buffer[27], buffer[28], buffer[29], buffer[30], buffer[31], buffer[32],
buffer[33], buffer[34], buffer[35], buffer[36], buffer[37], buffer[38], buffer[39],
buffer[40], buffer[41], buffer[42], buffer[43]);
*/
const unsigned char *p = buffer;
out_message->buttons = read8(&p);
// Read buttons
unsigned char buttons = read8(&p);
decoded_input->thumbstick.click = buttons & 0x01;
// decoded_input->home = buttons & 0x02;
decoded_input->menu = buttons & 0x04;
decoded_input->squeeze = buttons & 0x08; // squeeze-click
decoded_input->trackpad.click = buttons & 0x10;
// decoded_input->bt_pairing = buttons & 0x20;
decoded_input->trackpad.touch = buttons & 0x40;
// Todo: interpret analog stick data
out_message->stick_1 = read8(&p);
out_message->stick_2 = read8(&p);
out_message->stick_3 = read8(&p);
out_message->trigger = read8(&p); // pressure: 0x00 - 0xFF
// Read thumbstick coordinates (12 bit resolution)
signed int stick_x = read8(&p);
unsigned char nipples = read8(&p);
stick_x += ((nipples & 0x0F) << 8);
signed int stick_y = (nipples >> 4);
stick_y += (read8(&p) << 4);
// Touchpad coords range: 0x00 - 0x64. Both are 0xFF when untouched.
out_message->pad_x = read8(&p);
out_message->pad_y = read8(&p);
out_message->battery = read8(&p);
out_message->accel_x = read24(&p);
out_message->accel_y = read24(&p);
out_message->accel_z = read24(&p);
out_message->temp = read16(&p);
out_message->gyro_x = read24(&p);
out_message->gyro_y = read24(&p);
out_message->gyro_z = read24(&p);
decoded_input->thumbstick.values.x = (float)(stick_x - 0x07FF) / 0x07FF;
if (decoded_input->thumbstick.values.x > 1.0f) {
decoded_input->thumbstick.values.x = 1.0f;
}
out_message->timestamp = read32(&p); // Maybe only part of timestamp.
read16(&p); // Unknown. Seems to depend on controller orientation.
read32(&p); // Unknown.
decoded_input->thumbstick.values.y = (float)(stick_y - 0x07FF) / 0x07FF;
if (decoded_input->thumbstick.values.y > 1.0f) {
decoded_input->thumbstick.values.y = 1.0f;
}
read16(&p); // Unknown. Device state, etc.
read16(&p);
read16(&p);
U_LOG_IFL_D(log_level, "buttons: %02x, trigger: %02x, pad_x: %02x, pad_y: %02x", out_message->buttons,
out_message->trigger, out_message->pad_x, out_message->pad_y);
// Read trigger value (0x00 - 0xFF)
decoded_input->trigger = (float)read8(&p) / 0xFF;
U_LOG_IFL_D(log_level, "thumbstick: x %f, y %f, trigger: %f", decoded_input->thumbstick.values.x,
decoded_input->thumbstick.values.y, decoded_input->trigger);
// Read trackpad coordinates (0x00 - 0x64. Both are 0xFF when untouched)
unsigned char trackpad_x = read8(&p);
unsigned char trackpad_y = read8(&p);
decoded_input->trackpad.values.x = (trackpad_x == 0xFF) ? 0.0f : (float)(trackpad_x - 0x32) / 0x32;
decoded_input->trackpad.values.y = (trackpad_y == 0xFF) ? 0.0f : (float)(trackpad_y - 0x32) / 0x32;
U_LOG_IFL_D(log_level, "touchpad: x %f, y %f", decoded_input->trackpad.values.x,
decoded_input->trackpad.values.y);
/* Todo: More decoding here
unsigned char battery = read8(&p);
unsigned int accel_x = read24(&p);
unsigned int accel_y = read24(&p);
unsigned int accel_z = read24(&p);
unsigned int temp = read16(&p);
unsigned int gyro_x = read24(&p);
unsigned int gyro_y = read24(&p);
unsigned int gyro_z = read24(&p);
unsigned int timestamp = read32(&p); // Maybe only part of timestamp.
read16(&p); // Unknown. Seems to depend on controller orientation.
read32(&p); // Unknown.
read16(&p); // Unknown. Device state, etc.
read16(&p);
read16(&p);
*/
return true;
}

View file

@ -33,44 +33,23 @@ extern "C" {
#define WMR_BT_MOTION_CONTROLLER_MSG 0x01
struct wmr_controller_message
struct wmr_controller_input
{
// Very much still work in progress!
bool menu;
bool squeeze; // Actually a "squeeze" click
float trigger;
// HP Reverb G1 button map:
// Stick_pressed: 0x01
// Home button pressed: 0x02
// Menu button pressed: 0x04
// Grip button pressed: 0x08
// Touch-pad pressed: 0x10
// BT pairing button pressed: 0x20
// Touch-pad touched: 0x40
uint8_t buttons;
// Todo: interpret analog stick data
uint8_t stick_1;
uint8_t stick_2;
uint8_t stick_3;
uint8_t trigger; // pressure: 0x00 - 0xFF
// Touchpad coords range: 0x00 - 0x64. Both are 0xFF when untouched.
uint8_t pad_x;
uint8_t pad_y;
uint8_t battery;
int32_t accel_x;
int32_t accel_y;
int32_t accel_z;
int32_t temp;
int32_t gyro_x;
int32_t gyro_y;
int32_t gyro_z;
uint64_t timestamp;
struct
{
bool click;
struct xrt_vec2 values;
} thumbstick;
struct
{
bool click;
bool touch;
struct xrt_vec2 values;
} trackpad;
};
@ -89,7 +68,7 @@ struct wmr_controller_message
bool
wmr_controller_packet_parse(const unsigned char *buffer,
size_t len,
struct wmr_controller_message *out_message,
struct wmr_controller_input *decoded_input,
enum u_logging_level log_level);