The open source OpenXR runtime
at prediction-2 1235 lines 40 kB view raw
1// Copyright 2016 Philipp Zabel 2// Copyright 2020-2023, Collabora, Ltd. 3// SPDX-License-Identifier: BSL-1.0 4/*! 5 * @file 6 * @brief Vive Controller prober and driver code 7 * @author Christoph Haag <christoph.gaag@collabora.com> 8 * @author Lubosz Sarnecki <lubosz.sarnecki@collabora.com> 9 * @author Rylie Pavlik <rylie.pavlik@collabora.com> 10 * @author Jakob Bornecrantz <jakob@collabora.com> 11 * 12 * Portions based on the VRPN Razer Hydra driver, 13 * originally written by Rylie Pavlik and available under the BSL-1.0. 14 */ 15 16#include "xrt/xrt_defines.h" 17#include "xrt/xrt_prober.h" 18 19#include "math/m_imu_3dof.h" 20#include "math/m_relation_history.h" 21 22#include "util/u_var.h" 23 24#include "os/os_hid.h" 25#include "os/os_threading.h" 26#include "os/os_time.h" 27 28#include "math/m_api.h" 29#include "math/m_space.h" 30#include "math/m_predict.h" 31 32#include "util/u_json.h" 33#include "util/u_misc.h" 34#include "util/u_time.h" 35#include "util/u_debug.h" 36#include "util/u_device.h" 37#include "util/u_trace_marker.h" 38 39#include "vive/vive_config.h" 40#include "vive/vive_bindings.h" 41#include "vive/vive_poses.h" 42 43#include "vive.h" 44#include "vive_protocol.h" 45#include "vive_controller.h" 46#include "util/u_hand_simulation.h" 47 48#include <assert.h> 49#include <stdio.h> 50#include <stdlib.h> 51#include <string.h> 52 53#ifdef XRT_OS_LINUX 54#include <unistd.h> 55#include <math.h> 56#endif 57 58 59/* 60 * 61 * Defines & structs. 62 * 63 */ 64 65enum vive_controller_input_index 66{ 67 // common inputs 68 VIVE_CONTROLLER_INDEX_AIM_POSE = 0, 69 VIVE_CONTROLLER_INDEX_GRIP_POSE, 70 VIVE_CONTROLLER_INDEX_SYSTEM_CLICK, 71 VIVE_CONTROLLER_INDEX_TRIGGER_CLICK, 72 VIVE_CONTROLLER_INDEX_TRIGGER_VALUE, 73 VIVE_CONTROLLER_INDEX_TRACKPAD, 74 VIVE_CONTROLLER_INDEX_TRACKPAD_TOUCH, 75 76 // Vive Wand specific inputs 77 VIVE_CONTROLLER_INDEX_SQUEEZE_CLICK, 78 VIVE_CONTROLLER_INDEX_MENU_CLICK, 79 VIVE_CONTROLLER_INDEX_TRACKPAD_CLICK, 80 81 // Valve Index specific inputs 82 VIVE_CONTROLLER_INDEX_THUMBSTICK, 83 VIVE_CONTROLLER_INDEX_A_CLICK, 84 VIVE_CONTROLLER_INDEX_B_CLICK, 85 VIVE_CONTROLLER_INDEX_THUMBSTICK_CLICK, 86 VIVE_CONTROLLER_INDEX_THUMBSTICK_TOUCH, 87 VIVE_CONTROLLER_INDEX_SYSTEM_TOUCH, 88 VIVE_CONTROLLER_INDEX_A_TOUCH, 89 VIVE_CONTROLLER_INDEX_B_TOUCH, 90 VIVE_CONTROLLER_INDEX_SQUEEZE_VALUE, 91 VIVE_CONTROLLER_INDEX_SQUEEZE_FORCE, 92 VIVE_CONTROLLER_INDEX_TRIGGER_TOUCH, 93 VIVE_CONTROLLER_INDEX_TRACKPAD_FORCE, 94 95 VIVE_CONTROLLER_HAND_TRACKING, 96 97 VIVE_CONTROLLER_MAX_INDEX, 98}; 99 100 101 102#define DEFAULT_HAPTIC_FREQ 150.0f 103#define MIN_HAPTIC_DURATION 0.05f 104 105// Debug define(s), always off. 106#undef WATCHMAN2_PRINT_HID 107 108 109/* 110 * 111 * Helper functions. 112 * 113 */ 114 115static inline struct vive_controller_device * 116vive_controller_device(struct xrt_device *xdev) 117{ 118 assert(xdev); 119 struct vive_controller_device *ret = (struct vive_controller_device *)xdev; 120 return ret; 121} 122 123static inline void 124get_pose(struct vive_controller_device *d, 125 enum xrt_input_name name, 126 int64_t at_timestamp_ns, 127 struct xrt_space_relation *out_relation) 128{ 129 struct xrt_space_relation imu_relation = {0}; 130 imu_relation.relation_flags = XRT_SPACE_RELATION_BITMASK_ALL; 131 m_relation_history_get(d->fusion.relation_hist, at_timestamp_ns, &imu_relation); 132 imu_relation.relation_flags = XRT_SPACE_RELATION_BITMASK_ALL; // Needed after history_get 133 134 // Get the offset to the pose (this is from libsurvive's reporting position currently) 135 struct xrt_pose pose_offset = XRT_POSE_IDENTITY; 136 vive_poses_get_pose_offset(d->base.name, d->base.device_type, name, &pose_offset); 137 138 // We want this to make grip the center of rotation. 139 struct xrt_pose grip = XRT_POSE_IDENTITY; 140 enum xrt_input_name grip_name = XRT_INPUT_INDEX_GRIP_POSE; //! @todo Vive poses only have index poses. 141 vive_poses_get_pose_offset(d->base.name, d->base.device_type, grip_name, &grip); 142 143 // Build proper relation. 144 struct xrt_relation_chain chain = {0}; 145 m_relation_chain_push_pose(&chain, &pose_offset); 146 m_relation_chain_push_inverted_pose_if_not_identity(&chain, &grip); 147 m_relation_chain_push_relation(&chain, &imu_relation); 148 m_relation_chain_push_pose_if_not_identity(&chain, &d->offset); 149 150 // And resolve it. 151 struct xrt_space_relation relation = {0}; 152 m_relation_chain_resolve(&chain, &relation); 153 154 relation.linear_velocity = (struct xrt_vec3){0, 0, 0}; 155 156 *out_relation = relation; 157} 158 159 160/* 161 * 162 * Member functions. 163 * 164 */ 165 166static void 167vive_controller_device_destroy(struct xrt_device *xdev) 168{ 169 struct vive_controller_device *d = vive_controller_device(xdev); 170 171 os_thread_helper_destroy(&d->controller_thread); 172 173 // Now that the thread is not running we can destroy the lock. 174 os_mutex_destroy(&d->lock); 175 176 os_mutex_destroy(&d->fusion.mutex); 177 m_relation_history_destroy(&d->fusion.relation_hist); 178 m_imu_3dof_close(&d->fusion.i3dof); 179 180 if (d->controller_hid) 181 os_hid_destroy(d->controller_hid); 182 183 free(d); 184} 185 186static xrt_result_t 187vive_controller_device_wand_update_inputs(struct xrt_device *xdev) 188{ 189 struct vive_controller_device *d = vive_controller_device(xdev); 190 191 os_mutex_lock(&d->lock); 192 193 uint8_t buttons = d->state.buttons; 194 195 /* 196 int i = 8; 197 while(i--) { 198 putchar('0' + ((buttons >> i) & 1)); 199 } 200 printf("\n"); 201 */ 202 203 uint64_t now = os_monotonic_get_ns(); 204 205 /* d->state.buttons is bitmask of currently pressed buttons. 206 * (index n) nth bit in the bitmask -> input "name" 207 */ 208 const int button_index_map[] = {VIVE_CONTROLLER_INDEX_TRIGGER_CLICK, VIVE_CONTROLLER_INDEX_TRACKPAD_TOUCH, 209 VIVE_CONTROLLER_INDEX_TRACKPAD_CLICK, VIVE_CONTROLLER_INDEX_SYSTEM_CLICK, 210 VIVE_CONTROLLER_INDEX_SQUEEZE_CLICK, VIVE_CONTROLLER_INDEX_MENU_CLICK}; 211 212 int button_count = ARRAY_SIZE(button_index_map); 213 for (int i = 0; i < button_count; i++) { 214 215 bool pressed = (buttons >> i) & 1; 216 bool last_pressed = (d->state.last_buttons >> i) & 1; 217 218 if (pressed != last_pressed) { 219 struct xrt_input *input = &d->base.inputs[button_index_map[i]]; 220 221 input->timestamp = now; 222 input->value.boolean = pressed; 223 224 VIVE_DEBUG(d, "button %d %s\n", i, pressed ? "pressed" : "released"); 225 } 226 } 227 d->state.last_buttons = d->state.buttons; 228 229 230 struct xrt_input *trackpad_input = &d->base.inputs[VIVE_CONTROLLER_INDEX_TRACKPAD]; 231 trackpad_input->timestamp = now; 232 trackpad_input->value.vec2.x = d->state.trackpad.x; 233 trackpad_input->value.vec2.y = d->state.trackpad.y; 234 VIVE_TRACE(d, "Trackpad: %f, %f", d->state.trackpad.x, d->state.trackpad.y); 235 236 237 struct xrt_input *trigger_input = &d->base.inputs[VIVE_CONTROLLER_INDEX_TRIGGER_VALUE]; 238 trigger_input->timestamp = now; 239 trigger_input->value.vec1.x = d->state.trigger; 240 VIVE_TRACE(d, "Trigger: %f", d->state.trigger); 241 242 os_mutex_unlock(&d->lock); 243 244 return XRT_SUCCESS; 245} 246 247static xrt_result_t 248vive_controller_device_index_update_inputs(struct xrt_device *xdev) 249{ 250 XRT_TRACE_MARKER(); 251 252 struct vive_controller_device *d = vive_controller_device(xdev); 253 254 os_mutex_lock(&d->lock); 255 uint8_t buttons = d->state.buttons; 256 257 /* 258 int i = 8; 259 while(i--) { 260 putchar('0' + ((buttons >> i) & 1)); 261 } 262 printf("\n"); 263 */ 264 265 bool was_trackpad_touched = d->base.inputs[VIVE_CONTROLLER_INDEX_TRACKPAD_TOUCH].value.boolean; 266 267 uint64_t now = os_monotonic_get_ns(); 268 269 /* d->state.buttons is bitmask of currently pressed buttons. 270 * (index n) nth bit in the bitmask -> input "name" 271 */ 272 const int button_index_map[] = {VIVE_CONTROLLER_INDEX_TRIGGER_CLICK, VIVE_CONTROLLER_INDEX_TRACKPAD_TOUCH, 273 VIVE_CONTROLLER_INDEX_THUMBSTICK_CLICK, VIVE_CONTROLLER_INDEX_SYSTEM_CLICK, 274 VIVE_CONTROLLER_INDEX_A_CLICK, VIVE_CONTROLLER_INDEX_B_CLICK}; 275 276 int button_count = ARRAY_SIZE(button_index_map); 277 for (int i = 0; i < button_count; i++) { 278 279 bool pressed = (buttons >> i) & 1; 280 bool last_pressed = (d->state.last_buttons >> i) & 1; 281 282 if (pressed != last_pressed) { 283 struct xrt_input *input = &d->base.inputs[button_index_map[i]]; 284 285 input->timestamp = now; 286 input->value.boolean = pressed; 287 288 VIVE_DEBUG(d, "button %d %s\n", i, pressed ? "pressed" : "released"); 289 } 290 } 291 d->state.last_buttons = d->state.buttons; 292 293 bool is_trackpad_touched = d->base.inputs[VIVE_CONTROLLER_INDEX_TRACKPAD_TOUCH].value.boolean; 294 295 /* trackpad and thumbstick position are the same usb events. 296 * report trackpad position when trackpad has been touched last, and 297 * thumbstick position when trackpad touch has been released 298 */ 299 struct xrt_input *thumb_input; 300 301 // after releasing trackpad, next 0,0 position still goes to trackpad 302 if (is_trackpad_touched || was_trackpad_touched) 303 thumb_input = &d->base.inputs[VIVE_CONTROLLER_INDEX_TRACKPAD]; 304 else 305 thumb_input = &d->base.inputs[VIVE_CONTROLLER_INDEX_THUMBSTICK]; 306 thumb_input->timestamp = now; 307 thumb_input->value.vec2.x = d->state.trackpad.x; 308 thumb_input->value.vec2.y = d->state.trackpad.y; 309 310 const char *component = is_trackpad_touched || was_trackpad_touched ? "Trackpad" : "Thumbstick"; 311 VIVE_TRACE(d, "%s: %f, %f", component, d->state.trackpad.x, d->state.trackpad.y); 312 313 314 struct xrt_input *trigger_input = &d->base.inputs[VIVE_CONTROLLER_INDEX_TRIGGER_VALUE]; 315 316 trigger_input->timestamp = now; 317 trigger_input->value.vec1.x = d->state.trigger; 318 319 VIVE_TRACE(d, "Trigger: %f", d->state.trigger); 320 321 322 /* d->state.touch is bitmask of currently touched buttons. 323 * (index n) nth bit in the bitmask -> input "name" 324 */ 325 const int touched_button_index_map[] = {0, 326 0, 327 0, 328 VIVE_CONTROLLER_INDEX_SYSTEM_TOUCH, 329 VIVE_CONTROLLER_INDEX_A_TOUCH, 330 VIVE_CONTROLLER_INDEX_B_TOUCH, 331 VIVE_CONTROLLER_INDEX_THUMBSTICK_TOUCH}; 332 int touch_button_count = ARRAY_SIZE(touched_button_index_map); 333 uint8_t touch_buttons = d->state.touch; 334 for (int i = 0; i < touch_button_count; i++) { 335 336 bool touched = (touch_buttons >> i) & 1; 337 bool last_touched = (d->state.last_touch >> i) & 1; 338 339 if (touched != last_touched) { 340 struct xrt_input *input = &d->base.inputs[touched_button_index_map[i]]; 341 342 input->timestamp = now; 343 input->value.boolean = touched; 344 345 VIVE_DEBUG(d, "button %d %s\n", i, touched ? "touched" : "untouched"); 346 } 347 } 348 d->state.last_touch = d->state.touch; 349 350 d->base.inputs[VIVE_CONTROLLER_INDEX_SQUEEZE_FORCE].value.vec1.x = (float)d->state.squeeze_force / UINT8_MAX; 351 d->base.inputs[VIVE_CONTROLLER_INDEX_SQUEEZE_FORCE].timestamp = now; 352 if (d->state.squeeze_force > 0) { 353 VIVE_DEBUG(d, "Squeeze force: %f\n", (float)d->state.squeeze_force / UINT8_MAX); 354 } 355 356 d->base.inputs[VIVE_CONTROLLER_INDEX_TRACKPAD_FORCE].value.vec1.x = (float)d->state.trackpad_force / UINT8_MAX; 357 d->base.inputs[VIVE_CONTROLLER_INDEX_TRACKPAD_FORCE].timestamp = now; 358 if (d->state.trackpad_force > 0) { 359 VIVE_DEBUG(d, "Trackpad force: %f\n", (float)d->state.trackpad_force / UINT8_MAX); 360 } 361 362 os_mutex_unlock(&d->lock); 363 364 return XRT_SUCCESS; 365} 366 367static xrt_result_t 368vive_controller_get_hand_tracking(struct xrt_device *xdev, 369 enum xrt_input_name name, 370 int64_t requested_timestamp_ns, 371 struct xrt_hand_joint_set *out_value, 372 int64_t *out_timestamp_ns) 373{ 374 XRT_TRACE_MARKER(); 375 376 struct vive_controller_device *d = vive_controller_device(xdev); 377 378 if (name != XRT_INPUT_HT_CONFORMING_LEFT && name != XRT_INPUT_HT_CONFORMING_RIGHT) { 379 U_LOG_XDEV_UNSUPPORTED_INPUT(&d->base, d->log_level, name); 380 return XRT_ERROR_INPUT_UNSUPPORTED; 381 } 382 383 enum xrt_hand hand = d->config.variant == CONTROLLER_INDEX_LEFT ? XRT_HAND_LEFT : XRT_HAND_RIGHT; 384 385 float thumb_curl = 0.0f; 386 //! @todo place thumb preciely on the button that is touched/pressed 387 if (d->base.inputs[VIVE_CONTROLLER_INDEX_A_TOUCH].value.boolean || 388 d->base.inputs[VIVE_CONTROLLER_INDEX_B_TOUCH].value.boolean || 389 d->base.inputs[VIVE_CONTROLLER_INDEX_THUMBSTICK_TOUCH].value.boolean || 390 d->base.inputs[VIVE_CONTROLLER_INDEX_TRACKPAD_TOUCH].value.boolean) { 391 thumb_curl = 1.0; 392 } 393 394 struct u_hand_tracking_curl_values values = { 395 .little = (float)d->state.pinky_finger_handle / UINT8_MAX, 396 .ring = (float)d->state.ring_finger_handle / UINT8_MAX, 397 .middle = (float)d->state.middle_finger_handle / UINT8_MAX, 398 .index = (float)d->state.index_finger_trigger / UINT8_MAX, 399 .thumb = thumb_curl, 400 }; 401 402 struct xrt_space_relation hand_relation; 403 get_pose(d, name, requested_timestamp_ns, &hand_relation); 404 405 u_hand_sim_simulate_for_valve_index_knuckles(&values, hand, &hand_relation, out_value); 406 407 // This is the truth - we pose-predicted or interpolated all the way up to `at_timestamp_ns`. 408 *out_timestamp_ns = requested_timestamp_ns; 409 410 out_value->is_active = true; 411 return XRT_SUCCESS; 412} 413 414static xrt_result_t 415vive_controller_device_get_tracked_pose(struct xrt_device *xdev, 416 enum xrt_input_name name, 417 int64_t at_timestamp_ns, 418 struct xrt_space_relation *out_relation) 419{ 420 struct vive_controller_device *d = vive_controller_device(xdev); 421 422 // U_LOG_D("input name %d %d", name, XRT_INPUT_VIVE_GRIP_POSE); 423 if (name != XRT_INPUT_VIVE_AIM_POSE && name != XRT_INPUT_VIVE_GRIP_POSE && name != XRT_INPUT_INDEX_AIM_POSE && 424 name != XRT_INPUT_INDEX_GRIP_POSE) { 425 U_LOG_XDEV_UNSUPPORTED_INPUT(&d->base, d->log_level, name); 426 return XRT_ERROR_INPUT_UNSUPPORTED; 427 } 428 429 get_pose(d, name, at_timestamp_ns, out_relation); 430 431 return XRT_SUCCESS; 432} 433 434static int 435vive_controller_haptic_pulse(struct vive_controller_device *d, const struct xrt_output_value *value) 436{ 437 float duration_seconds; 438 if (value->vibration.duration_ns == XRT_MIN_HAPTIC_DURATION) { 439 VIVE_TRACE(d, "Haptic pulse duration: using %f minimum", MIN_HAPTIC_DURATION); 440 duration_seconds = MIN_HAPTIC_DURATION; 441 } else { 442 duration_seconds = time_ns_to_s(value->vibration.duration_ns); 443 } 444 445 VIVE_TRACE(d, "Haptic pulse amp %f, %fHz, %fs", value->vibration.amplitude, value->vibration.frequency, 446 duration_seconds); 447 float frequency = value->vibration.frequency; 448 449 if (frequency == XRT_FREQUENCY_UNSPECIFIED) { 450 VIVE_TRACE(d, "Haptic pulse frequency unspecified, setting to %fHz", DEFAULT_HAPTIC_FREQ); 451 frequency = DEFAULT_HAPTIC_FREQ; 452 } 453 454 455 /* haptic pulse for Vive Controller: 456 * desired_frequency = 1000 * 1000 / (high + low). 457 * => (high + low) = 1000 * 1000 / desired_frequency 458 * repeat = desired_duration_in_seconds * desired_frequency. 459 * 460 * I think: 461 * Lowest amplitude: 1, high+low-1 462 * Highest amplitude: (high+low)/2, / (high+low)/2 463 */ 464 465 float high_plus_low = 1000.f * 1000.f / frequency; 466 uint16_t pulse_low = (uint16_t)(value->vibration.amplitude * high_plus_low / 2.); 467 468 /* Vive Controller doesn't vibrate with value == 0. 469 * Not sure if this actually happens, but let's fix it anyway. */ 470 if (pulse_low == 0) 471 pulse_low = 1; 472 473 uint16_t pulse_high = high_plus_low - pulse_low; 474 475 uint16_t repeat_count = duration_seconds * frequency; 476 477 const struct vive_controller_haptic_pulse_report report = { 478 .id = VIVE_CONTROLLER_COMMAND_REPORT_ID, 479 .command = VIVE_CONTROLLER_HAPTIC_PULSE_COMMAND, 480 .len = 7, 481 .zero = 0x00, 482 .pulse_high = __cpu_to_le16(pulse_high), 483 .pulse_low = __cpu_to_le16(pulse_low), 484 .repeat_count = __cpu_to_le16(repeat_count), 485 }; 486 487 return os_hid_set_feature(d->controller_hid, (uint8_t *)&report, sizeof(report)); 488} 489 490static xrt_result_t 491vive_controller_device_set_output(struct xrt_device *xdev, 492 enum xrt_output_name name, 493 const struct xrt_output_value *value) 494{ 495 struct vive_controller_device *d = vive_controller_device(xdev); 496 497 if (name != XRT_OUTPUT_NAME_VIVE_HAPTIC && name != XRT_OUTPUT_NAME_INDEX_HAPTIC) { 498 U_LOG_XDEV_UNSUPPORTED_OUTPUT(&d->base, d->log_level, name); 499 return XRT_ERROR_OUTPUT_UNSUPPORTED; 500 } 501 502 if (value->vibration.amplitude > 0.01) { 503 os_mutex_lock(&d->lock); 504 vive_controller_haptic_pulse(d, value); 505 os_mutex_unlock(&d->lock); 506 } 507 508 return XRT_SUCCESS; 509} 510 511 512/* 513 * 514 * Misc functions. 515 * 516 */ 517 518static void 519controller_handle_battery(struct vive_controller_device *d, struct vive_controller_battery_sample *sample) 520{ 521 uint8_t charge_percent = sample->battery & VIVE_CONTROLLER_BATTERY_CHARGE_MASK; 522 bool charging = sample->battery & VIVE_CONTROLLER_BATTERY_CHARGING; 523 VIVE_DEBUG(d, "Charging %d, percent %d\n", charging, charge_percent); 524 d->state.charging = charging; 525 d->state.battery = charge_percent; 526} 527 528static void 529controller_handle_buttons(struct vive_controller_device *d, struct vive_controller_button_sample *sample) 530{ 531 d->state.buttons = sample->buttons; 532} 533 534static void 535controller_handle_touch_position(struct vive_controller_device *d, struct vive_controller_touch_sample *sample) 536{ 537 int16_t x = __le16_to_cpu(sample->touch[0]); 538 int16_t y = __le16_to_cpu(sample->touch[1]); 539 d->state.trackpad.x = (float)x / INT16_MAX; 540 d->state.trackpad.y = (float)y / INT16_MAX; 541 if (d->state.trackpad.x != 0 || d->state.trackpad.y != 0) 542 VIVE_TRACE(d, "Trackpad %f,%f\n", d->state.trackpad.x, d->state.trackpad.y); 543} 544 545static void 546controller_handle_analog_trigger(struct vive_controller_device *d, struct vive_controller_trigger_sample *sample) 547{ 548 d->state.trigger = (float)sample->trigger / UINT8_MAX; 549 VIVE_TRACE(d, "Trigger %f\n", d->state.trigger); 550} 551 552 553static void 554vive_controller_handle_imu_sample(struct vive_controller_device *d, struct watchman_imu_sample *sample) 555{ 556 XRT_TRACE_MARKER(); 557 558 uint64_t now_ns = os_monotonic_get_ns(); 559 560 /* ouvrt: "Time in 48 MHz ticks, but we are missing the low byte" */ 561 uint32_t time_raw = d->last_ticks | (sample->timestamp_hi << 8); 562 ticks_to_ns(time_raw, &d->imu.last_sample_ticks, &d->imu.last_sample_ts_ns); 563 564 int16_t acc[3] = { 565 __le16_to_cpu(sample->acc[0]), 566 __le16_to_cpu(sample->acc[1]), 567 __le16_to_cpu(sample->acc[2]), 568 }; 569 570 int16_t gyro[3] = { 571 __le16_to_cpu(sample->gyro[0]), 572 __le16_to_cpu(sample->gyro[1]), 573 __le16_to_cpu(sample->gyro[2]), 574 }; 575 576 float scale = (float)d->config.imu.acc_range / 32768.0f; 577 struct xrt_vec3 acceleration = { 578 scale * d->config.imu.acc_scale.x * acc[0] - d->config.imu.acc_bias.x, 579 scale * d->config.imu.acc_scale.y * acc[1] - d->config.imu.acc_bias.y, 580 scale * d->config.imu.acc_scale.z * acc[2] - d->config.imu.acc_bias.z, 581 }; 582 583 scale = (float)d->config.imu.gyro_range / 32768.0f; 584 struct xrt_vec3 angular_velocity = { 585 scale * d->config.imu.gyro_scale.x * gyro[0] - d->config.imu.gyro_bias.x, 586 scale * d->config.imu.gyro_scale.y * gyro[1] - d->config.imu.gyro_bias.y, 587 scale * d->config.imu.gyro_scale.z * gyro[2] - d->config.imu.gyro_bias.z, 588 }; 589 590 VIVE_TRACE(d, "ACC %f %f %f", acceleration.x, acceleration.y, acceleration.z); 591 VIVE_TRACE(d, "GYRO %f %f %f", angular_velocity.x, angular_velocity.y, angular_velocity.z); 592 /* 593 */ 594 595 if (d->config.variant == CONTROLLER_VIVE_WAND) { 596 struct xrt_vec3 fixed_acceleration = {.x = -acceleration.x, .y = -acceleration.z, .z = -acceleration.y}; 597 acceleration = fixed_acceleration; 598 599 struct xrt_vec3 fixed_angular_velocity = { 600 .x = -angular_velocity.x, .y = -angular_velocity.z, .z = -angular_velocity.y}; 601 angular_velocity = fixed_angular_velocity; 602 } else if (d->config.variant == CONTROLLER_INDEX_RIGHT) { 603 struct xrt_vec3 fixed_acceleration = {.x = acceleration.z, .y = -acceleration.y, .z = acceleration.x}; 604 acceleration = fixed_acceleration; 605 606 struct xrt_vec3 fixed_angular_velocity = { 607 .x = angular_velocity.z, .y = -angular_velocity.y, .z = angular_velocity.x}; 608 angular_velocity = fixed_angular_velocity; 609 } else if (d->config.variant == CONTROLLER_INDEX_LEFT) { 610 struct xrt_vec3 fixed_acceleration = {.x = -acceleration.z, .y = acceleration.x, .z = -acceleration.y}; 611 acceleration = fixed_acceleration; 612 613 struct xrt_vec3 fixed_angular_velocity = { 614 .x = -angular_velocity.z, .y = angular_velocity.x, .z = -angular_velocity.y}; 615 angular_velocity = fixed_angular_velocity; 616 } 617 618 d->last.acc = acceleration; 619 d->last.gyro = angular_velocity; 620 621 struct xrt_space_relation rel = {0}; 622 rel.relation_flags = XRT_SPACE_RELATION_ORIENTATION_VALID_BIT | XRT_SPACE_RELATION_ORIENTATION_TRACKED_BIT; 623 624 os_mutex_lock(&d->fusion.mutex); 625 m_imu_3dof_update(&d->fusion.i3dof, d->imu.last_sample_ts_ns, &acceleration, &angular_velocity); 626 rel.pose.orientation = d->fusion.i3dof.rot; 627 os_mutex_unlock(&d->fusion.mutex); 628 629 m_relation_history_push(d->fusion.relation_hist, &rel, now_ns); 630 631 // Update the pose we show in the GUI. 632 d->pose = rel.pose; 633} 634 635static void 636controller_handle_touch_force(struct vive_controller_device *d, struct watchman_touch_force *sample) 637{ 638 d->state.touch = sample->touch; 639 640 d->state.middle_finger_handle = sample->middle_finger_handle; 641 d->state.ring_finger_handle = sample->ring_finger_handle; 642 d->state.pinky_finger_handle = sample->pinky_finger_handle; 643 d->state.index_finger_trigger = sample->index_finger_trigger; 644 645 d->state.squeeze_force = sample->squeeze_force; 646 d->state.trackpad_force = sample->trackpad_force; 647} 648 649static void 650vive_controller_handle_lighthousev1(struct vive_controller_device *d, uint8_t *buf, uint8_t len) 651{ 652 VIVE_TRACE(d, "Got lighthouse message with len %d.\n", len); 653} 654 655/* 656 * Handles battery, imu, trigger, buttons, trackpad. 657 * Then hands off to vive_controller_handle_lighthousev1(). 658 */ 659static void 660vive_controller_decode_watchmanv1(struct vive_controller_device *d, struct vive_controller_message *message) 661{ 662 uint8_t *buf = message->payload; 663 uint8_t *end = message->payload + message->len - 1; 664 665 /* 666 for (int i = 0; i < message->len; i++) { 667 //printf("%02x ", buf[i]); 668 int j = 8; 669 while(j--) { 670 putchar('0' + ((buf[i] >> j) & 1)); 671 } 672 putchar(' '); 673 } 674 printf("\n"); 675 */ 676 677 /* payload starts with "event flags" byte. 678 * If it does not start with 111, it contains only lighthouse data. 679 * If it starts with 111, events follow in this order, each of them 680 * optional: 681 * - battery: 1 byte (1110???1) 682 * - trigger: 1 byte (1111?1??) 683 * - trackpad: 4 byte (1111??1?) 684 * - buttons: 1 byte (1111???1) 685 * - imu: 13 byte (111?1???) 686 * There may be another input event after a battery event. 687 * Lighthouse data may follow in the rest of the payload. 688 */ 689 690 // input events have first three bits set 691 if ((*buf & 0xe0) == 0xe0 && buf < end) { 692 693 // clang-format off 694 695 // battery follows when 1110???1 696 bool has_battery = (*buf & 0x10) != 0x10 && (*buf & 0x1) == 0x1; 697 698 // input follows when 1111?<trigger><trackpad><buttons> 699 bool has_trigger = (*buf & 0x10) == 0x10 && (*buf & 0x4) == 0x4; 700 bool has_trackpad = (*buf & 0x10) == 0x10 && (*buf & 0x2) == 0x2; 701 bool has_buttons = (*buf & 0x10) == 0x10 && (*buf & 0x1) == 0x1; 702 703 // imu event follows when 111?1??? 704 // there are imu-only messages, and imu-after-battery 705 bool has_imu = (*buf & 0x08) == 0x8; 706 707 // clang-format on 708 709 VIVE_TRACE(d, 710 "battery %d trigger %d trackpad %d " 711 "buttons %d imu %d", 712 has_battery, has_trigger, has_trackpad, has_buttons, has_imu); 713 714 buf++; 715 716 if (has_battery) { 717 controller_handle_battery(d, (struct vive_controller_battery_sample *)buf); 718 buf += sizeof(struct vive_controller_battery_sample); 719 } 720 721 if (has_buttons) { 722 controller_handle_buttons(d, (struct vive_controller_button_sample *)buf); 723 buf += sizeof(struct vive_controller_button_sample); 724 } 725 if (has_trigger) { 726 controller_handle_analog_trigger(d, (struct vive_controller_trigger_sample *)buf); 727 buf += sizeof(struct vive_controller_trigger_sample); 728 } 729 if (has_trackpad) { 730 controller_handle_touch_position(d, (struct vive_controller_touch_sample *)buf); 731 buf += 4; 732 } 733 if (has_imu) { 734 vive_controller_handle_imu_sample(d, (struct watchman_imu_sample *)buf); 735 buf += sizeof(struct watchman_imu_sample); 736 } 737 } 738 739 if (buf > end) 740 VIVE_ERROR(d, "overshoot: %td\n", (ptrdiff_t)(buf - end)); 741 742 if (buf < end) 743 vive_controller_handle_lighthousev1(d, buf, end - buf); 744} 745 746/* 747 * Handles battery, imu, trigger, buttons, trackpad. 748 * Then hands off to vive_controller_handle_lighthousev1(). 749 */ 750static void 751vive_controller_decode_watchmanv2(struct vive_controller_device *d, struct vive_controller_message *message) 752{ 753 uint8_t *buf = message->payload; 754 uint8_t *end = message->payload + message->len - 1; 755 756#ifdef WATCHMAN2_PRINT_HID 757 for (int i = 0; i < message->len; i++) { 758 int j = 8; 759 while (j--) { 760 putchar('0' + ((buf[i] >> j) & 1)); 761 } 762 putchar(' '); 763 } 764 printf("\n"); 765 for (int i = 0; i < message->len; i++) { 766 printf("%8.02x ", buf[i]); 767 } 768 printf("\n"); 769#endif 770 771 772 /* payload starts with "event flags" byte. */ 773 774 /* 775 * If flags == 0xe1 == 11100001, battery follows. 776 * Battery is always at the beginning of the payload. 777 * after battery there may be another payload. 778 * careful: 0xe1 often comes alone without actual data. 779 */ 780 if (*buf == 0xe1 && buf < end) { 781 buf++; 782 controller_handle_battery(d, (struct vive_controller_battery_sample *)buf); 783 buf += sizeof(struct vive_controller_battery_sample); 784 785#ifdef WATCHMAN2_PRINT_HID 786 printf( 787 " " 788 " battery"); 789#endif 790 } 791 792 793 /* 794 * If flags == 0xf0 == 11110000, 8 bytes touch+force follow. 795 * This package is always at the beginning of the payload. 796 */ 797 if (*buf == 0xf0 && buf < end) { 798 buf++; 799 controller_handle_touch_force(d, (struct watchman_touch_force *)buf); 800 size_t s = sizeof(struct watchman_touch_force); 801 buf += s; 802 803#ifdef WATCHMAN2_PRINT_HID 804 printf(" "); 805 for (size_t i = 0; i < s; i++) 806 printf(" t&force"); 807#endif 808 } 809 810 /* 811 * If flags == 0xe8 == 11101000, imu data follows. 812 * This package can be at the beginning of the payload or after battery. 813 */ 814 // TODO: it's possible we misparse non-im udata as imu data 815 if (*buf == 0xe8 && buf < end) { 816 buf++; 817 vive_controller_handle_imu_sample(d, (struct watchman_imu_sample *)buf); 818 size_t s = sizeof(struct watchman_imu_sample); 819 buf += s; 820 821#ifdef WATCHMAN2_PRINT_HID 822 printf(" "); 823 for (size_t i = 0; i < s; i++) 824 printf(" imu"); 825#endif 826 } 827 828 /* 829 * If flags starts with 1111, events follow in this order, 830 * each of them optional: 831 * - trigger: 1 byte (1111?1??) 832 * - trackpad: 4 byte (1111??1?) 833 * - buttons: 1 byte (1111???1) 834 * - touch&force+imu or imu: 8+13 or 13 byte (11111???) 835 * There may be another input event after a battery event. 836 */ 837 if ((*buf & 0xf0) == 0xf0 && buf < end - 1) { 838 839 // clang-format off 840 841 // input flags 1111<touch_force><trigger><trackpad><buttons> 842 bool has_touch_force = (*buf & 0x8) == 0x8; 843 bool has_trigger = (*buf & 0x4) == 0x4; 844 bool has_trackpad = (*buf & 0x2) == 0x2; 845 bool has_buttons = (*buf & 0x1) == 0x1; 846 847 // clang-format on 848 849 buf++; 850 851#ifdef WATCHMAN2_PRINT_HID 852 printf(" "); 853#endif 854 855 if (has_buttons) { 856 controller_handle_buttons(d, (struct vive_controller_button_sample *)buf); 857 buf += sizeof(struct vive_controller_button_sample); 858#ifdef WATCHMAN2_PRINT_HID 859 printf(" buttons"); 860#endif 861 } 862 if (has_trigger) { 863 controller_handle_analog_trigger(d, (struct vive_controller_trigger_sample *)buf); 864 buf += sizeof(struct vive_controller_trigger_sample); 865#ifdef WATCHMAN2_PRINT_HID 866 printf(" trigger"); 867#endif 868 } 869 if (has_trackpad) { 870 controller_handle_touch_position(d, (struct vive_controller_touch_sample *)buf); 871 buf += sizeof(struct vive_controller_touch_sample); 872#ifdef WATCHMAN2_PRINT_HID 873 for (unsigned long i = 0; i < sizeof(struct vive_controller_touch_sample); i++) 874 printf(" trackpad"); 875#endif 876 } 877 if (has_touch_force) { 878 uint8_t type_flag = *buf; 879 if (type_flag == TYPE_FLAG_TOUCH_FORCE) { 880 controller_handle_touch_force(d, (struct watchman_touch_force *)buf); 881 size_t s = sizeof(struct watchman_touch_force); 882 buf += s; 883#ifdef WATCHMAN2_PRINT_HID 884 for (unsigned long i = 0; i < sizeof(struct watchman_touch_force); i++) 885 printf(" t&force"); 886#endif 887 } 888 } 889 // if something still follows, usually imu 890 // sometimes it's 5 unknown bytes' 891 if (buf < end && end - buf >= (long)sizeof(struct watchman_imu_sample)) { 892 vive_controller_handle_imu_sample(d, (struct watchman_imu_sample *)buf); 893 size_t s = sizeof(struct watchman_imu_sample); 894 buf += s; 895#ifdef WATCHMAN2_PRINT_HID 896 for (unsigned long i = 0; i < sizeof(struct watchman_imu_sample); i++) 897 printf(" imu"); 898#endif 899 } 900 } 901 902 903#ifdef WATCHMAN2_PRINT_HID 904 printf("\n"); 905#endif 906 907 if (buf < end) { 908 VIVE_TRACE(d, "%td bytes unparsed data in message\n", 909 (ptrdiff_t)(message->len - (buf - message->payload) - 1)); 910 } 911 if (buf > end) 912 VIVE_ERROR(d, "overshoot: %td\n", (ptrdiff_t)(buf - end)); 913 914 //! @todo: Parse lighthouse v2 data 915} 916/* 917 * Decodes multiplexed Wireless Receiver messages. 918 */ 919static void 920vive_controller_decode_message(struct vive_controller_device *d, struct vive_controller_message *message) 921{ 922 d->last_ticks = (message->timestamp_hi << 24) | (message->timestamp_lo << 16); 923 924 //! @todo: Check if Vive controller on watchman2 is correctly handled 925 //! with watchman2 codepath 926 switch (d->watchman_gen) { 927 case WATCHMAN_GEN1: vive_controller_decode_watchmanv1(d, message); break; 928 case WATCHMAN_GEN2: vive_controller_decode_watchmanv2(d, message); break; 929 default: VIVE_ERROR(d, "Can't decode unknown watchman gen"); 930 } 931} 932 933#define FEATURE_BUFFER_SIZE 256 934 935static int 936vive_controller_device_update(struct vive_controller_device *d) 937{ 938 uint8_t buf[FEATURE_BUFFER_SIZE]; 939 940 int ret = os_hid_read(d->controller_hid, buf, sizeof(buf), 1000); 941 if (ret == 0) { 942 // controller off 943 return true; 944 } 945 946 if (ret < 0) { 947 VIVE_ERROR(d, "Failed to read device '%i'!", ret); 948 return false; 949 } 950 951 switch (buf[0]) { 952 case VIVE_CONTROLLER_REPORT1_ID: 953 os_mutex_lock(&d->lock); 954 vive_controller_decode_message(d, &((struct vive_controller_report1 *)buf)->message); 955 os_mutex_unlock(&d->lock); 956 break; 957 958 case VIVE_CONTROLLER_REPORT2_ID: 959 os_mutex_lock(&d->lock); 960 vive_controller_decode_message(d, &((struct vive_controller_report2 *)buf)->message[0]); 961 vive_controller_decode_message(d, &((struct vive_controller_report2 *)buf)->message[1]); 962 os_mutex_unlock(&d->lock); 963 break; 964 case VIVE_CONTROLLER_DISCONNECT_REPORT_ID: VIVE_DEBUG(d, "Controller disconnected."); break; 965 default: VIVE_ERROR(d, "Unknown controller message type: %u", buf[0]); 966 } 967 968 return true; 969} 970 971static void * 972vive_controller_run_thread(void *ptr) 973{ 974 struct vive_controller_device *d = (struct vive_controller_device *)ptr; 975 976 uint8_t buf[FEATURE_BUFFER_SIZE]; 977 while (os_hid_read(d->controller_hid, buf, sizeof(buf), 0) > 0) { 978 // Empty queue first 979 } 980 981 os_thread_helper_lock(&d->controller_thread); 982 while (os_thread_helper_is_running_locked(&d->controller_thread)) { 983 os_thread_helper_unlock(&d->controller_thread); 984 985 if (!vive_controller_device_update(d)) { 986 return NULL; 987 } 988 989 // Just keep swimming. 990 os_thread_helper_lock(&d->controller_thread); 991 } 992 993 return NULL; 994} 995 996void 997vive_controller_reset_pose_cb(void *ptr) 998{ 999 struct vive_controller_device *d = (struct vive_controller_device *)ptr; 1000 os_mutex_lock(&d->fusion.mutex); 1001 m_imu_3dof_reset(&d->fusion.i3dof); 1002 d->pose = (struct xrt_pose)XRT_POSE_IDENTITY; 1003 os_mutex_unlock(&d->fusion.mutex); 1004} 1005 1006static void 1007vive_controller_setup_ui(struct vive_controller_device *d) 1008{ 1009 char tmp[256] = {0}; 1010 snprintf(tmp, sizeof(tmp), "Vive Controller %zu", d->index); 1011 1012 u_var_add_root(d, tmp, false); 1013 u_var_add_log_level(d, &d->log_level, "Log level"); 1014 1015 u_var_add_gui_header(d, NULL, "Tracking"); 1016 u_var_add_pose(d, &d->pose, "Tracked Pose"); 1017 u_var_add_pose(d, &d->offset, "Pose Offset"); 1018 1019 d->gui.reset_pose_btn.cb = vive_controller_reset_pose_cb; 1020 d->gui.reset_pose_btn.ptr = d; 1021 u_var_add_button(d, &d->gui.reset_pose_btn, "Reset pose"); 1022 1023 u_var_add_gui_header(d, NULL, "3DoF Tracking"); 1024 m_imu_3dof_add_vars(&d->fusion.i3dof, d, ""); 1025 u_var_add_gui_header(d, NULL, "Calibration"); 1026 u_var_add_vec3_f32(d, &d->config.imu.acc_scale, "acc_scale"); 1027 u_var_add_vec3_f32(d, &d->config.imu.acc_bias, "acc_bias"); 1028 u_var_add_vec3_f32(d, &d->config.imu.gyro_scale, "gyro_scale"); 1029 u_var_add_vec3_f32(d, &d->config.imu.gyro_bias, "gyro_bias"); 1030} 1031 1032/* 1033 * 1034 * 'Exported' function(s). 1035 * 1036 */ 1037 1038#define SET_WAND_INPUT(NAME, NAME2) \ 1039 do { \ 1040 (d->base.inputs[VIVE_CONTROLLER_INDEX_##NAME].name = XRT_INPUT_VIVE_##NAME2); \ 1041 } while (0) 1042 1043#define SET_INDEX_INPUT(NAME, NAME2) \ 1044 do { \ 1045 (d->base.inputs[VIVE_CONTROLLER_INDEX_##NAME].name = XRT_INPUT_INDEX_##NAME2); \ 1046 } while (0) 1047 1048struct vive_controller_device * 1049vive_controller_create(struct os_hid_device *controller_hid, enum watchman_gen watchman_gen, int controller_num) 1050{ 1051 1052 enum u_device_alloc_flags flags = U_DEVICE_ALLOC_TRACKING_NONE; 1053 struct vive_controller_device *d = 1054 U_DEVICE_ALLOCATE(struct vive_controller_device, flags, VIVE_CONTROLLER_MAX_INDEX, 1); 1055 1056 d->log_level = debug_get_log_option_vive_log(); 1057 d->watchman_gen = WATCHMAN_GEN_UNKNOWN; 1058 d->config.variant = CONTROLLER_UNKNOWN; 1059 d->index = controller_num; 1060 d->pose = (struct xrt_pose)XRT_POSE_IDENTITY; 1061 d->offset = (struct xrt_pose)XRT_POSE_IDENTITY; 1062 1063 d->watchman_gen = watchman_gen; 1064 1065 m_imu_3dof_init(&d->fusion.i3dof, M_IMU_3DOF_USE_GRAVITY_DUR_20MS); 1066 m_relation_history_create(&d->fusion.relation_hist); 1067 int ret = os_mutex_init(&d->fusion.mutex); 1068 if (ret != 0) { 1069 VIVE_ERROR(d, "Failed to init 3dof mutex"); 1070 return NULL; 1071 } 1072 1073 /* default values, will be queried from device */ 1074 d->config.imu.gyro_range = 8.726646f; 1075 d->config.imu.acc_range = 39.226600f; 1076 1077 d->config.imu.acc_scale.x = 1.0f; 1078 d->config.imu.acc_scale.y = 1.0f; 1079 d->config.imu.acc_scale.z = 1.0f; 1080 d->config.imu.gyro_scale.x = 1.0f; 1081 d->config.imu.gyro_scale.y = 1.0f; 1082 d->config.imu.gyro_scale.z = 1.0f; 1083 1084 d->config.imu.acc_bias.x = 0.0f; 1085 d->config.imu.acc_bias.y = 0.0f; 1086 d->config.imu.acc_bias.z = 0.0f; 1087 d->config.imu.gyro_bias.x = 0.0f; 1088 d->config.imu.gyro_bias.y = 0.0f; 1089 d->config.imu.gyro_bias.z = 0.0f; 1090 1091 d->controller_hid = controller_hid; 1092 1093 d->base.destroy = vive_controller_device_destroy; 1094 d->base.get_tracked_pose = vive_controller_device_get_tracked_pose; 1095 d->base.set_output = vive_controller_device_set_output; 1096 1097 // Have to init before destroy is called. 1098 os_mutex_init(&d->lock); 1099 os_thread_helper_init(&d->controller_thread); 1100 1101 if (vive_get_imu_range_report(d->controller_hid, &d->config.imu.gyro_range, &d->config.imu.acc_range) != 0) { 1102 // reading range report fails for powered off controller 1103 vive_controller_device_destroy(&d->base); 1104 return NULL; 1105 } 1106 1107 VIVE_DEBUG(d, "Vive controller gyroscope range %f", d->config.imu.gyro_range); 1108 VIVE_DEBUG(d, "Vive controller accelerometer range %f", d->config.imu.acc_range); 1109 1110 // successful config parsing determines d->config.variant 1111 char *config = vive_read_config(d->controller_hid); 1112 1113 if (config != NULL) { 1114 vive_config_parse_controller(&d->config, config, d->log_level); 1115 free(config); 1116 } else { 1117 VIVE_ERROR(d, "Could not get Vive controller config\n"); 1118 vive_controller_device_destroy(&d->base); 1119 return NULL; 1120 } 1121 1122 snprintf(d->base.serial, XRT_DEVICE_NAME_LEN, "%s", d->config.firmware.device_serial_number); 1123 1124 if (d->config.variant == CONTROLLER_VIVE_WAND) { 1125 d->base.name = XRT_DEVICE_VIVE_WAND; 1126 snprintf(d->base.str, XRT_DEVICE_NAME_LEN, "Vive Wand Controller (vive)"); 1127 1128 SET_WAND_INPUT(SYSTEM_CLICK, SYSTEM_CLICK); 1129 SET_WAND_INPUT(SQUEEZE_CLICK, SQUEEZE_CLICK); 1130 SET_WAND_INPUT(MENU_CLICK, MENU_CLICK); 1131 SET_WAND_INPUT(TRIGGER_CLICK, TRIGGER_CLICK); 1132 SET_WAND_INPUT(TRIGGER_VALUE, TRIGGER_VALUE); 1133 SET_WAND_INPUT(TRACKPAD, TRACKPAD); 1134 SET_WAND_INPUT(TRACKPAD_CLICK, TRACKPAD_CLICK); 1135 SET_WAND_INPUT(TRACKPAD_TOUCH, TRACKPAD_TOUCH); 1136 1137 SET_WAND_INPUT(AIM_POSE, AIM_POSE); 1138 SET_WAND_INPUT(GRIP_POSE, GRIP_POSE); 1139 1140 d->base.outputs[0].name = XRT_OUTPUT_NAME_VIVE_HAPTIC; 1141 1142 d->base.update_inputs = vive_controller_device_wand_update_inputs; 1143 1144 d->base.binding_profiles = vive_binding_profiles_wand; 1145 d->base.binding_profile_count = vive_binding_profiles_wand_count; 1146 1147 d->base.device_type = XRT_DEVICE_TYPE_ANY_HAND_CONTROLLER; 1148 } else if (d->config.variant == CONTROLLER_INDEX_LEFT || d->config.variant == CONTROLLER_INDEX_RIGHT) { 1149 d->base.name = XRT_DEVICE_INDEX_CONTROLLER; 1150 1151 SET_INDEX_INPUT(SYSTEM_CLICK, SYSTEM_CLICK); 1152 SET_INDEX_INPUT(A_CLICK, A_CLICK); 1153 SET_INDEX_INPUT(B_CLICK, B_CLICK); 1154 SET_INDEX_INPUT(TRIGGER_CLICK, TRIGGER_CLICK); 1155 SET_INDEX_INPUT(TRIGGER_VALUE, TRIGGER_VALUE); 1156 SET_INDEX_INPUT(TRACKPAD, TRACKPAD); 1157 SET_INDEX_INPUT(TRACKPAD_TOUCH, TRACKPAD_TOUCH); 1158 SET_INDEX_INPUT(THUMBSTICK, THUMBSTICK); 1159 SET_INDEX_INPUT(THUMBSTICK_CLICK, THUMBSTICK_CLICK); 1160 1161 SET_INDEX_INPUT(THUMBSTICK_TOUCH, THUMBSTICK_TOUCH); 1162 SET_INDEX_INPUT(SYSTEM_TOUCH, SYSTEM_TOUCH); 1163 SET_INDEX_INPUT(A_TOUCH, A_TOUCH); 1164 SET_INDEX_INPUT(B_TOUCH, B_TOUCH); 1165 SET_INDEX_INPUT(SQUEEZE_VALUE, SQUEEZE_VALUE); 1166 SET_INDEX_INPUT(SQUEEZE_FORCE, SQUEEZE_FORCE); 1167 SET_INDEX_INPUT(TRIGGER_TOUCH, TRIGGER_TOUCH); 1168 SET_INDEX_INPUT(TRACKPAD_FORCE, TRACKPAD_FORCE); 1169 1170 SET_INDEX_INPUT(AIM_POSE, AIM_POSE); 1171 SET_INDEX_INPUT(GRIP_POSE, GRIP_POSE); 1172 1173 d->base.outputs[0].name = XRT_OUTPUT_NAME_INDEX_HAPTIC; 1174 1175 d->base.update_inputs = vive_controller_device_index_update_inputs; 1176 1177 d->base.get_hand_tracking = vive_controller_get_hand_tracking; 1178 1179 d->base.binding_profiles = vive_binding_profiles_index; 1180 d->base.binding_profile_count = vive_binding_profiles_index_count; 1181 1182 if (d->config.variant == CONTROLLER_INDEX_LEFT) { 1183 d->base.device_type = XRT_DEVICE_TYPE_LEFT_HAND_CONTROLLER; 1184 d->base.inputs[VIVE_CONTROLLER_HAND_TRACKING].name = XRT_INPUT_HT_CONFORMING_LEFT; 1185 snprintf(d->base.str, XRT_DEVICE_NAME_LEN, "Valve Index Left Controller (vive)"); 1186 } else if (d->config.variant == CONTROLLER_INDEX_RIGHT) { 1187 d->base.device_type = XRT_DEVICE_TYPE_RIGHT_HAND_CONTROLLER; 1188 d->base.inputs[VIVE_CONTROLLER_HAND_TRACKING].name = XRT_INPUT_HT_CONFORMING_RIGHT; 1189 snprintf(d->base.str, XRT_DEVICE_NAME_LEN, "Valve Index Right Controller (vive)"); 1190 } 1191 } else if (d->config.variant == CONTROLLER_TRACKER_GEN1) { 1192 d->base.name = XRT_DEVICE_VIVE_TRACKER_GEN1; 1193 d->base.update_inputs = u_device_noop_update_inputs; 1194 d->base.device_type = XRT_DEVICE_TYPE_GENERIC_TRACKER; 1195 snprintf(d->base.str, XRT_DEVICE_NAME_LEN, "Vive Tracker Gen1 (vive)"); 1196 } else if (d->config.variant == CONTROLLER_TRACKER_GEN2) { 1197 d->base.name = XRT_DEVICE_VIVE_TRACKER_GEN2; 1198 d->base.update_inputs = u_device_noop_update_inputs; 1199 d->base.device_type = XRT_DEVICE_TYPE_GENERIC_TRACKER; 1200 snprintf(d->base.str, XRT_DEVICE_NAME_LEN, "Vive Tracker Gen2 (vive)"); 1201 } else if (d->config.variant == CONTROLLER_TRACKER_GEN3) { 1202 d->base.name = XRT_DEVICE_VIVE_TRACKER_GEN3; 1203 d->base.update_inputs = u_device_noop_update_inputs; 1204 d->base.device_type = XRT_DEVICE_TYPE_GENERIC_TRACKER; 1205 snprintf(d->base.str, XRT_DEVICE_NAME_LEN, "Vive Tracker Gen3 (vive)"); 1206 } else if (d->config.variant == CONTROLLER_TRACKER_TUNDRA) { 1207 d->base.name = XRT_DEVICE_VIVE_TRACKER_TUNDRA; 1208 d->base.update_inputs = u_device_noop_update_inputs; 1209 d->base.device_type = XRT_DEVICE_TYPE_GENERIC_TRACKER; 1210 snprintf(d->base.str, XRT_DEVICE_NAME_LEN, "Tundra Tracker Gen3 (vive)"); 1211 } else { 1212 d->base.name = XRT_DEVICE_GENERIC_HMD; 1213 d->base.device_type = XRT_DEVICE_TYPE_GENERIC_TRACKER; 1214 VIVE_ERROR(d, "Failed to assign update input function"); 1215 } 1216 1217 if (d->controller_hid) { 1218 int ret = os_thread_helper_start(&d->controller_thread, vive_controller_run_thread, d); 1219 if (ret != 0) { 1220 VIVE_ERROR(d, "Failed to start mainboard thread!"); 1221 vive_controller_device_destroy(&d->base); 1222 return NULL; 1223 } 1224 } 1225 1226 VIVE_DEBUG(d, "Opened vive controller!\n"); 1227 d->base.supported.orientation_tracking = true; 1228 d->base.supported.position_tracking = false; 1229 d->base.supported.hand_tracking = 1230 d->config.variant == CONTROLLER_INDEX_LEFT || d->config.variant == CONTROLLER_INDEX_RIGHT; 1231 1232 vive_controller_setup_ui(d); 1233 1234 return d; 1235}