The open source OpenXR runtime
at prediction-2 1195 lines 29 kB view raw
1// Copyright 2016, Joey Ferwerda. 2// Copyright 2019-2022, Collabora, Ltd. 3// SPDX-License-Identifier: BSL-1.0 4/*! 5 * @file 6 * @brief PSVR device implementation, imported from OpenHMD. 7 * @author Joey Ferwerda <joeyferweda@gmail.com> 8 * @author Philipp Zabel <philipp.zabel@gmail.com> 9 * @author Jakob Bornecrantz <jakob@collabora.com> 10 * @ingroup drv_psvr 11 */ 12 13#include "xrt/xrt_compiler.h" 14#include "xrt/xrt_tracking.h" 15 16#include "os/os_time.h" 17#include "os/os_threading.h" 18 19#include "math/m_api.h" 20 21#include "util/u_var.h" 22#include "util/u_misc.h" 23#include "util/u_time.h" 24#include "util/u_debug.h" 25#include "util/u_device.h" 26#include "util/u_trace_marker.h" 27#include "util/u_distortion_mesh.h" 28 29#include "math/m_imu_3dof.h" 30 31#include "math/m_mathinclude.h" 32 33#include <stdio.h> 34#include <stdlib.h> 35#include <string.h> 36 37#include "psvr_device.h" 38 39 40/* 41 * 42 * Structs and defines. 43 * 44 */ 45 46DEBUG_GET_ONCE_BOOL_OPTION(psvr_disco, "PSVR_DISCO", false) 47#define PSVR_DEBUG(p, ...) U_LOG_XDEV_IFL_D(&p->base, p->log_level, __VA_ARGS__) 48#define PSVR_ERROR(p, ...) U_LOG_XDEV_IFL_E(&p->base, p->log_level, __VA_ARGS__) 49 50#define FEATURE_BUFFER_SIZE 256 51 52/*! 53 * Private struct for the @ref drv_psvr device. 54 * 55 * @ingroup drv_psvr 56 * @implements xrt_device 57 */ 58struct psvr_device 59{ 60 struct xrt_device base; 61 62 //! Owned by the @ref oth thread. 63 hid_device *hid_sensor; 64 65 //! Owned and protected by the device_mutex. 66 hid_device *hid_control; 67 struct os_mutex device_mutex; 68 69 //! Used to read sensor packets. 70 struct os_thread_helper oth; 71 72 struct xrt_tracked_psvr *tracker; 73 74 //! Only touched from the sensor thread. 75 timepoint_ns last_sensor_time; 76 77 struct psvr_parsed_sensor last; 78 79 struct 80 { 81 uint8_t leds[9]; 82 } wants; 83 84 struct 85 { 86 uint8_t leds[9]; 87 } state; 88 89 struct 90 { 91 struct xrt_vec3 gyro; 92 struct xrt_vec3 accel; 93 } read; 94 95 uint16_t buttons; 96 97 bool powered_on; 98 bool in_vr_mode; 99 100 enum u_logging_level log_level; 101 102 struct 103 { 104 union { 105 uint8_t data[290]; 106 struct 107 { 108 uint32_t _pad0[4]; 109 struct xrt_vec3 unknown0; 110 uint32_t _zero0; 111 uint32_t _pad2_vec3_zero[4]; 112 uint32_t _pad3_vec3_zero[4]; 113 uint32_t _pad4_vec3_zero[4]; 114 struct xrt_vec3 accel_pos_y; 115 uint32_t _pad5[1]; 116 struct xrt_vec3 accel_neg_x; 117 uint32_t _pad6[1]; 118 struct xrt_vec3 accel_neg_y; 119 uint32_t _pad7[1]; 120 struct xrt_vec3 accel_pos_x; 121 uint32_t _pad8[1]; 122 struct xrt_vec3 accel_pos_z; 123 uint32_t _pad9[1]; 124 struct xrt_vec3 accel_neg_z; 125 uint32_t _pad10[1]; 126 struct xrt_vec3 gyro_neg_y; 127 uint32_t _pad11[1]; 128 struct xrt_vec3 gyro_pos_x; 129 uint32_t _pad12[1]; 130 struct xrt_vec3 gyro_neg_z; 131 uint32_t _pad13[1]; 132 }; 133 }; 134 int last_packet; 135 } calibration; 136 137 138 struct 139 { 140 bool last_frame; 141 bool control; 142 } gui; 143 144#if 1 145 struct m_imu_3dof fusion; 146#else 147 struct 148 { 149 struct xrt_quat rot; 150 } fusion; 151#endif 152 153 //! For compute_distortion 154 struct u_panotools_values vals; 155}; 156 157 158// Alternative way to turn on all of the leds. 159XRT_MAYBE_UNUSED static const unsigned char psvr_tracking_on[12] = { 160 0x11, 0x00, 0xaa, 0x08, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 161}; 162 163 164#define PSVR_LED_POWER_OFF ((uint8_t)0x00) 165#define PSVR_LED_POWER_MAX ((uint8_t)0xff) 166 167#define PSVR_LED_POWER_WIRE_OFF ((uint8_t)0) 168#define PSVR_LED_POWER_WIRE_MAX ((uint8_t)100) 169 170 171enum psvr_leds 172{ 173 PSVR_LED_A = (1 << 0), 174 PSVR_LED_B = (1 << 1), 175 PSVR_LED_C = (1 << 2), 176 PSVR_LED_D = (1 << 3), 177 PSVR_LED_E = (1 << 4), 178 PSVR_LED_F = (1 << 5), 179 PSVR_LED_G = (1 << 6), 180 PSVR_LED_H = (1 << 7), 181 PSVR_LED_I = (1 << 8), 182 183 PSVR_LED_FRONT = PSVR_LED_A | PSVR_LED_B | PSVR_LED_C | PSVR_LED_D | PSVR_LED_E | PSVR_LED_F | PSVR_LED_G, 184 185 PSVR_LED_BACK = PSVR_LED_H | PSVR_LED_I, 186 187 PSVR_LED_ALL = PSVR_LED_FRONT | PSVR_LED_BACK, 188}; 189 190 191/* 192 * 193 * Helpers and internal functions. 194 * 195 */ 196 197static inline struct psvr_device * 198psvr_device(struct xrt_device *p) 199{ 200 return (struct psvr_device *)p; 201} 202 203static int 204open_hid(struct psvr_device *p, struct hid_device_info *dev_info, hid_device **out_dev) 205{ 206 hid_device *dev = NULL; 207 int ret; 208 209 dev = hid_open_path(dev_info->path); 210 if (dev == NULL) { 211 PSVR_ERROR(p, "Failed to open '%s'", dev_info->path); 212 return -1; 213 } 214 215 ret = hid_set_nonblocking(dev, 1); 216 if (ret != 0) { 217 PSVR_ERROR(p, "Failed to set non-blocking on device"); 218 hid_close(dev); 219 return -1; 220 } 221 222 *out_dev = dev; 223 return 0; 224} 225 226static int 227send_to_control(struct psvr_device *psvr, const uint8_t *data, size_t size) 228{ 229 return hid_write(psvr->hid_control, data, size); 230} 231 232static int 233send_request_data(struct psvr_device *psvr, uint8_t id, uint8_t num) 234{ 235 const uint8_t data[12] = { 236 0x81, 0x00, 0xaa, 0x08, id, num, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 237 }; 238 return send_to_control(psvr, data, sizeof(data)); 239} 240 241static uint8_t 242scale_led_power(uint8_t power) 243{ 244 return (uint8_t)((power / 255.0f) * 100.0f); 245} 246 247 248/* 249 * 250 * Sensor functions. 251 * 252 */ 253 254static void 255read_sample_and_apply_calibration(struct psvr_device *psvr, 256 struct psvr_parsed_sample *sample, 257 struct xrt_vec3 *out_accel, 258 struct xrt_vec3 *out_gyro) 259{ 260 const struct xrt_vec3_i32 raw_accel = sample->accel; 261 const struct xrt_vec3_i32 raw_gyro = sample->gyro; 262 263 // Convert so that for a perfect IMU 1.0 is one G. 264 struct xrt_vec3 accel = { 265 raw_accel.x / 16384.0f, 266 raw_accel.y / 16384.0f, 267 raw_accel.z / 16384.0f, 268 }; 269 270 // What unit is this? 271 struct xrt_vec3 gyro = { 272 raw_gyro.x * 0.00105f, 273 raw_gyro.y * 0.00105f, 274 raw_gyro.z * 0.00105f, 275 }; 276 277 float ax = 2.0f / (psvr->calibration.accel_pos_x.x - psvr->calibration.accel_neg_x.x); 278 float ay = 2.0f / (psvr->calibration.accel_pos_y.y - psvr->calibration.accel_neg_y.y); 279 float az = 2.0f / (psvr->calibration.accel_pos_z.z - psvr->calibration.accel_neg_z.z); 280 281 float ox = (psvr->calibration.accel_pos_x.x + psvr->calibration.accel_neg_x.x) / 2.0f; 282 float oy = (psvr->calibration.accel_pos_y.y + psvr->calibration.accel_neg_y.y) / 2.0f; 283 float oz = (psvr->calibration.accel_pos_z.z + psvr->calibration.accel_neg_z.z) / 2.0f; 284 285 accel.x -= ox; 286 accel.y -= oy; 287 accel.z -= oz; 288 accel.x *= ax; 289 accel.y *= ay; 290 accel.z *= az; 291 292 // Go from Gs to m/s2 and flip the Z-axis. 293 accel.x *= (float)+MATH_GRAVITY_M_S2; 294 accel.y *= (float)+MATH_GRAVITY_M_S2; 295 accel.z *= (float)-MATH_GRAVITY_M_S2; 296 297 // Flip the Z-axis. 298 gyro.x *= +1.0; 299 gyro.y *= +1.0; 300 gyro.z *= -1.0; 301 302 *out_accel = accel; 303 *out_gyro = gyro; 304} 305 306static void 307update_fusion_locked(struct psvr_device *psvr, struct psvr_parsed_sample *sample, uint64_t timestamp_ns) 308{ 309 struct xrt_vec3 mag = {0.0f, 0.0f, 0.0f}; 310 (void)mag; 311 312 read_sample_and_apply_calibration(psvr, sample, &psvr->read.accel, &psvr->read.gyro); 313 314 if (psvr->tracker != NULL) { 315 struct xrt_tracking_sample sample; 316 sample.accel_m_s2 = psvr->read.accel; 317 sample.gyro_rad_secs = psvr->read.gyro; 318 319 xrt_tracked_psvr_push_imu(psvr->tracker, timestamp_ns, &sample); 320 } else { 321 m_imu_3dof_update(&psvr->fusion, timestamp_ns, &psvr->read.accel, &psvr->read.gyro); 322 } 323} 324 325static void 326update_fusion(struct psvr_device *psvr, struct psvr_parsed_sample *sample, uint64_t timestamp_ns) 327{ 328 os_mutex_lock(&psvr->device_mutex); 329 update_fusion_locked(psvr, sample, timestamp_ns); 330 os_mutex_unlock(&psvr->device_mutex); 331} 332 333static uint32_t 334calc_delta_and_handle_rollover(uint32_t next, uint32_t last) 335{ 336 uint32_t tick_delta = next - last; 337 338 // The 24-bit tick counter has rolled over, 339 // adjust the "negative" value to be positive. 340 if (tick_delta > 0xffffff) { 341 tick_delta += 0x1000000; 342 } 343 344 return tick_delta; 345} 346 347static timepoint_ns 348ensure_forward_progress_timestamps(struct psvr_device *psvr, timepoint_ns timestamp_ns) 349{ 350 timepoint_ns t = timestamp_ns; 351 352 /* 353 * This make sure the timestamp is after the last we sent to the fusion, 354 * but it effectively drops the sample. 355 */ 356 if (psvr->last_sensor_time > t) { 357 t = psvr->last_sensor_time + 1; 358 } 359 360 psvr->last_sensor_time = t; 361 return t; 362} 363 364static void 365handle_tracker_sensor_msg(struct psvr_device *psvr, unsigned char *buffer, int size) 366{ 367 timepoint_ns now_ns = os_monotonic_get_ns(); 368 uint32_t last_sample_tick = psvr->last.samples[1].tick; 369 370 if (!psvr_parse_sensor_packet(&psvr->last, buffer, size)) { 371 PSVR_ERROR(psvr, "couldn't decode tracker sensor message"); 372 } 373 374 struct psvr_parsed_sensor *s = &psvr->last; 375 376 // Simplest is the buttons. 377 psvr->buttons = s->buttons; 378 379 uint32_t tick_delta = 500; 380 381 // Startup correction, ignore last_sample_tick if zero. 382 if (last_sample_tick > 0) { 383 tick_delta = calc_delta_and_handle_rollover(s->samples[0].tick, last_sample_tick); 384 385 // The PSVR device can buffer sensor data from previous 386 // sessions which we can get at the start of new sessions. 387 // @todo Maybe just skip the first 10 sensor packets? 388 // @todo Maybe reset sensor fusion? 389 if (tick_delta < 400 || tick_delta > 600) { 390 PSVR_DEBUG(psvr, "tick_delta = %u", tick_delta); 391 tick_delta = 500; 392 } 393 } 394 395 // New delta between the two samples. 396 uint32_t tick_delta2 = calc_delta_and_handle_rollover(s->samples[1].tick, s->samples[0].tick); 397 398 time_duration_ns inter_sample_duration_ns = tick_delta2 * PSVR_NS_PER_TICK; 399 400 // If this is larger then one second something bad is going on. 401 assert(inter_sample_duration_ns < U_TIME_1S_IN_NS); 402 403 // Move it back in time. 404 timepoint_ns timestamp_ns = (uint64_t)now_ns - (uint64_t)inter_sample_duration_ns; 405 406 // Make sure timestamps are always after a previous timestamp. 407 timestamp_ns = ensure_forward_progress_timestamps(psvr, timestamp_ns); 408 409 // Update the fusion with first sample. 410 update_fusion(psvr, &s->samples[0], timestamp_ns); 411 412 // Make sure timestamps are always after a previous timestamp. 413 timestamp_ns = ensure_forward_progress_timestamps(psvr, now_ns); 414 415 // Update the fusion with second sample. 416 update_fusion(psvr, &s->samples[1], timestamp_ns); 417} 418 419static void 420sensor_clear_queue(struct psvr_device *psvr) 421{ 422 uint8_t buffer[FEATURE_BUFFER_SIZE]; 423 424 while (hid_read(psvr->hid_sensor, buffer, FEATURE_BUFFER_SIZE) > 0) { 425 // Just drop the packets. 426 } 427} 428 429static int 430sensor_read_one_packet(struct psvr_device *psvr) 431{ 432 uint8_t buffer[FEATURE_BUFFER_SIZE]; 433 434 // Try for one second to get packates. 435 int size = hid_read_timeout(psvr->hid_sensor, buffer, FEATURE_BUFFER_SIZE, 1000); 436 if (size <= 0) { 437 return size; 438 } 439 440 handle_tracker_sensor_msg(psvr, buffer, size); 441 442 return 0; 443} 444 445static void * 446sensor_thread(void *ptr) 447{ 448 U_TRACE_SET_THREAD_NAME("PS VR"); 449 450 struct psvr_device *psvr = (struct psvr_device *)ptr; 451 int ret = 0; 452 453 // Empty the queue. 454 sensor_clear_queue(psvr); 455 456 os_thread_helper_lock(&psvr->oth); 457 458 while (os_thread_helper_is_running_locked(&psvr->oth) && ret >= 0) { 459 os_thread_helper_unlock(&psvr->oth); 460 461 ret = sensor_read_one_packet(psvr); 462 463 os_thread_helper_lock(&psvr->oth); 464 } 465 466 os_thread_helper_unlock(&psvr->oth); 467 468 return NULL; 469} 470 471 472/* 473 * 474 * Control device handling. 475 * 476 */ 477 478static void 479handle_control_status_msg(struct psvr_device *psvr, unsigned char *buffer, int size) 480{ 481 struct psvr_parsed_status status = {0}; 482 483 if (!psvr_parse_status_packet(&status, buffer, size)) { 484 PSVR_ERROR(psvr, "couldn't decode tracker sensor message"); 485 } 486 487 488 /* 489 * Power 490 */ 491 492 if (status.status & PSVR_STATUS_BIT_POWER) { 493 if (!psvr->powered_on) { 494 PSVR_DEBUG(psvr, "Device powered on! '%02x'", status.status); 495 } 496 psvr->powered_on = true; 497 } else { 498 if (psvr->powered_on) { 499 PSVR_DEBUG(psvr, "Device powered off! '%02x'", status.status); 500 } 501 psvr->powered_on = false; 502 } 503 504 505 /* 506 * VR-Mode 507 */ 508 509 if (status.vr_mode == PSVR_STATUS_VR_MODE_OFF) { 510 if (psvr->in_vr_mode) { 511 PSVR_DEBUG(psvr, "Device not in vr-mode! '%02x'", status.vr_mode); 512 } 513 psvr->in_vr_mode = false; 514 } else if (status.vr_mode == PSVR_STATUS_VR_MODE_ON) { 515 if (!psvr->in_vr_mode) { 516 PSVR_DEBUG(psvr, "Device in vr-mode! '%02x'", status.vr_mode); 517 } 518 psvr->in_vr_mode = true; 519 } else { 520 PSVR_ERROR(psvr, "Unknown vr_mode status!"); 521 } 522} 523 524static void 525handle_device_name_msg(struct psvr_device *psvr, unsigned char *buffer, int size) 526{ 527 //! @todo Get the name here. 528} 529 530static void 531handle_calibration_msg(struct psvr_device *psvr, const unsigned char *buffer, size_t size) 532{ 533 const size_t data_start = 6; 534 const size_t data_length = 58; 535 const size_t packet_length = data_start + data_length; 536 537 if (size != packet_length) { 538 PSVR_ERROR(psvr, "invalid calibration packet length"); 539 return; 540 } 541 542 uint16_t which = buffer[1]; 543 size_t dst = data_length * which; 544 for (size_t src = data_start; src < size; src++, dst++) { 545 psvr->calibration.data[dst] = buffer[src]; 546 } 547 548 psvr->calibration.last_packet = which; 549} 550 551static void 552handle_control_0x82(struct psvr_device *psvr, unsigned char *buffer, int size) 553{ 554 if (size < 4) { 555 return; 556 } 557 558 if (size < (int)sizeof(float) * 6) { 559 PSVR_DEBUG(psvr, "%02x %02x %02x %02x", buffer[0], buffer[1], buffer[2], buffer[3]); 560 } 561 562 float *f = (float *)buffer; 563 int *i = (int *)buffer; 564 565 PSVR_DEBUG(psvr, 566 "%02x %02x %02x %02x\n" 567 "%+f %+f %+f %+f %+f\n" 568 "0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n" 569 "% 10i % 10i % 10i % 10i % 10i", 570 buffer[0], buffer[1], buffer[2], buffer[3], f[1], f[2], f[3], f[4], f[5], i[1], i[2], i[3], i[4], 571 i[5], i[1], i[2], i[3], i[4], i[5]); 572} 573 574static void 575handle_control_0xA0(struct psvr_device *psvr, unsigned char *buffer, int size) 576{ 577 if (size < 4) { 578 return; 579 } 580 581 PSVR_DEBUG(psvr, "%02x %02x %02x %02x", buffer[0], buffer[1], buffer[2], buffer[3]); 582} 583 584static int 585read_control_packets(struct psvr_device *psvr) 586{ 587 uint8_t buffer[FEATURE_BUFFER_SIZE]; 588 int size = 0; 589 590 do { 591 size = hid_read(psvr->hid_control, buffer, FEATURE_BUFFER_SIZE); 592 if (size == 0) { 593 return 0; 594 } 595 if (size < 0) { 596 return -1; 597 } 598 599 if (buffer[0] == PSVR_PKG_STATUS) { 600 handle_control_status_msg(psvr, buffer, size); 601 } else if (buffer[0] == PSVR_PKG_DEVICE_NAME) { 602 handle_device_name_msg(psvr, buffer, size); 603 } else if (buffer[0] == PSVR_PKG_CALIBRATION) { 604 handle_calibration_msg(psvr, buffer, size); 605 } else if (buffer[0] == PSVR_PKG_0x82) { 606 handle_control_0x82(psvr, buffer, size); 607 } else if (buffer[0] == PSVR_PKG_0xA0) { 608 handle_control_0xA0(psvr, buffer, size); 609 } else { 610 PSVR_ERROR(psvr, "Got report, 0x%02x", buffer[0]); 611 } 612 613 } while (true); 614} 615 616 617/*! 618 * Get the device name data and calibration data, see link below for info. 619 * 620 * https://github.com/gusmanb/PSVRFramework/wiki/Report-0x81-Device-ID-and-Calibration 621 */ 622static int 623read_calibration_data(struct psvr_device *psvr) 624{ 625 // Request the device name. 626 int ret = send_request_data(psvr, PSVR_GET_DATA_ID_DEVICE_NAME, 0); 627 if (ret < 0) { 628 return ret; 629 } 630 631 // Request unknown data 0x82. 632 ret = send_request_data(psvr, PSVR_GET_DATA_ID_0x82, 0); 633 if (ret < 0) { 634 return ret; 635 } 636 637 // There are 5 pages of PSVR calibration data. 638 for (int i = 0; i < 5; i++) { 639 // Request the IMU calibration data. 640 ret = send_request_data(psvr, PSVR_GET_DATA_ID_CALIBRATION, i); 641 if (ret < 0) { 642 return ret; 643 } 644 } 645 646 // We have requested 5 pages worth of data, wait for the replies. 647 for (int i = 0; i < 100; i++) { 648 os_nanosleep(1000 * 1000); 649 read_control_packets(psvr); 650 651 // If we have gotten of the packets stop wait. 652 if (psvr->calibration.last_packet == 4) { 653 break; 654 } 655 } 656 657 // Did we really get all of the data? 658 if (psvr->calibration.last_packet != 4) { 659 PSVR_ERROR(psvr, "Failed to get calibration"); 660 return -1; 661 } 662 663 PSVR_DEBUG(psvr, 664 "calibration.accel_pos_x: %f %f %f\n" 665 "calibration.accel_neg_x: %f %f %f\n" 666 "calibration.accel_pos_y: %f %f %f\n" 667 "calibration.accel_neg_y: %f %f %f\n" 668 "calibration.accel_pos_z: %f %f %f\n" 669 "calibration.accel_neg_z: %f %f %f\n", 670 psvr->calibration.accel_pos_x.x, psvr->calibration.accel_pos_x.y, psvr->calibration.accel_pos_x.z, 671 psvr->calibration.accel_neg_x.x, psvr->calibration.accel_neg_x.y, psvr->calibration.accel_neg_x.z, 672 psvr->calibration.accel_pos_y.x, psvr->calibration.accel_pos_y.y, psvr->calibration.accel_pos_y.z, 673 psvr->calibration.accel_neg_y.x, psvr->calibration.accel_neg_y.y, psvr->calibration.accel_neg_y.z, 674 psvr->calibration.accel_pos_z.x, psvr->calibration.accel_pos_z.y, psvr->calibration.accel_pos_z.z, 675 psvr->calibration.accel_neg_z.x, psvr->calibration.accel_neg_z.y, psvr->calibration.accel_neg_z.z); 676 677#if 0 678 for (size_t i = 0; i < sizeof(psvr->calibration.data); i++) { 679 fprintf(stderr, "%02x ", psvr->calibration.data[i]); 680 } 681 fprintf(stderr, "\n"); 682 683 int *data = (int*)&psvr->calibration.data[0]; 684 for (size_t i = 0; i < (sizeof(psvr->calibration.data) / 4); i++) { 685 int v = data[i]; 686 U_LOG_E("%i %f", v, *(float*)&v); 687 } 688#endif 689 690 // Jobs done! 691 // - Orc peon. 692 return 0; 693} 694 695 696/* 697 * 698 * Control sending functions. 699 * 700 */ 701 702static int 703wait_for_power(struct psvr_device *psvr, bool on) 704{ 705 for (int i = 0; i < 5000; i++) { 706 read_control_packets(psvr); 707 708 if (psvr->powered_on == on) { 709 return 0; 710 } 711 712 os_nanosleep(1000 * 1000); 713 } 714 715 return -1; 716} 717 718static int 719wait_for_vr_mode(struct psvr_device *psvr, bool on) 720{ 721 for (int i = 0; i < 5000; i++) { 722 read_control_packets(psvr); 723 724 if (psvr->in_vr_mode == on) { 725 return 0; 726 } 727 728 os_nanosleep(1000 * 1000); 729 } 730 731 return -1; 732} 733 734static int 735control_power_and_wait(struct psvr_device *psvr, bool on) 736{ 737 const char *status = on ? "on" : "off"; 738 const uint8_t data[8] = { 739 0x17, 0x00, 0xaa, 0x04, on, 0x00, 0x00, 0x00, 740 }; 741 742 int ret = send_to_control(psvr, data, sizeof(data)); 743 if (ret < 0) { 744 PSVR_ERROR(psvr, "Failed to switch %s the headset! '%i'", status, ret); 745 } 746 747 748 ret = wait_for_power(psvr, on); 749 if (ret < 0) { 750 PSVR_ERROR(psvr, "Failed to wait for headset power %s! '%i'", status, ret); 751 return ret; 752 } 753 754 return ret; 755} 756 757static int 758control_vrmode_and_wait(struct psvr_device *psvr, bool on) 759{ 760 const uint8_t data[8] = { 761 0x23, 0x00, 0xaa, 0x04, on, 0x00, 0x00, 0x00, 762 }; 763 int ret; 764 765 ret = send_to_control(psvr, data, sizeof(data)); 766 if (ret < 0) { 767 PSVR_ERROR(psvr, "Failed %s vr-mode the headset! '%i'", on ? "enable" : "disable", ret); 768 return ret; 769 } 770 771 ret = wait_for_vr_mode(psvr, on); 772 if (ret < 0) { 773 PSVR_ERROR(psvr, "Failed to wait for vr mode! '%i'", ret); 774 return ret; 775 } 776 777 return 0; 778} 779 780static int 781update_leds_if_changed(struct psvr_device *psvr) 782{ 783 if (memcmp(psvr->wants.leds, psvr->state.leds, sizeof(psvr->state.leds)) == 0) { 784 return 0; 785 } 786 787 memcpy(psvr->state.leds, psvr->wants.leds, sizeof(psvr->state.leds)); 788 789 uint8_t data[20] = { 790 0x15, 791 0x00, 792 0xaa, 793 0x10, 794 (uint8_t)PSVR_LED_ALL, 795 (uint8_t)(PSVR_LED_ALL >> 8), 796 scale_led_power(psvr->state.leds[0]), 797 scale_led_power(psvr->state.leds[1]), 798 scale_led_power(psvr->state.leds[2]), 799 scale_led_power(psvr->state.leds[3]), 800 scale_led_power(psvr->state.leds[4]), 801 scale_led_power(psvr->state.leds[5]), 802 scale_led_power(psvr->state.leds[6]), 803 scale_led_power(psvr->state.leds[7]), 804 scale_led_power(psvr->state.leds[8]), 805 0, 806 0, 807 0, 808 0, 809 0, 810 }; 811 812 return send_to_control(psvr, data, sizeof(data)); 813} 814 815/*! 816 * Control the leds on the headset, allowing you to turn on and off different 817 * leds with a single call. 818 * 819 * @param[in] psvr The PSVR to control leds on. 820 * @param[in] adjust The leds to adjust with @p power. 821 * @param[in] power The power level to give to @p adjust leds. 822 * @param[in] off Leds that should be turned off, 823 * @p adjust has higher priority. 824 * @ingroup drv_psvr 825 */ 826static int 827control_leds(struct psvr_device *psvr, enum psvr_leds adjust, uint8_t power, enum psvr_leds off) 828{ 829 // Get the leds we should control and remove any extra bits. 830 enum psvr_leds all = (enum psvr_leds)((adjust | off) & PSVR_LED_ALL); 831 if (all == 0) { 832 // Nothing todo. 833 return 0; 834 } 835 836 for (uint32_t i = 0; i < ARRAY_SIZE(psvr->wants.leds); i++) { 837 uint32_t mask = (1 << i); 838 if (adjust & mask) { 839 psvr->wants.leds[i] = power; 840 } 841 if (off & mask) { 842 psvr->wants.leds[i] = 0x00; 843 } 844 } 845 846 return update_leds_if_changed(psvr); 847} 848 849static int 850disco_leds(struct psvr_device *psvr) 851{ 852 static const uint16_t leds[] = { 853 // First loop 854 PSVR_LED_A, 855 PSVR_LED_E, 856 PSVR_LED_B, 857 PSVR_LED_G, 858 PSVR_LED_D, 859 PSVR_LED_C, 860 PSVR_LED_F, 861 // Second loop 862 PSVR_LED_A, 863 PSVR_LED_E, 864 PSVR_LED_B, 865 PSVR_LED_G, 866 PSVR_LED_D, 867 PSVR_LED_C, 868 PSVR_LED_F, 869 // Blink loop 870 PSVR_LED_BACK, 871 PSVR_LED_FRONT, 872 PSVR_LED_BACK, 873 PSVR_LED_FRONT, 874 // All on after loop 875 PSVR_LED_ALL, 876 }; 877 878 for (size_t i = 0; i < ARRAY_SIZE(leds); i++) { 879 int ret = control_leds(psvr, (enum psvr_leds)leds[i], PSVR_LED_POWER_MAX, PSVR_LED_ALL); 880 if (ret < 0) { 881 return ret; 882 } 883 884 // Sleep for a tenth of a second while polling for packages. 885 for (int k = 0; k < 100; k++) { 886 ret = read_control_packets(psvr); 887 if (ret < 0) { 888 return ret; 889 } 890 891 os_nanosleep(1000 * 1000); 892 } 893 } 894 895 return 0; 896} 897 898 899/* 900 * 901 * Misc functions. 902 * 903 */ 904 905static void 906teardown(struct psvr_device *psvr) 907{ 908 // Stop the variable tracking. 909 u_var_remove_root(psvr); 910 911 // Shutdown the sensor thread early. 912 os_thread_helper_stop_and_wait(&psvr->oth); 913 914 // Includes null check, and sets to null. 915 xrt_tracked_psvr_destroy(&psvr->tracker); 916 917 if (psvr->hid_control != NULL) { 918 // Turn off VR-mode and power down headset. 919 if (control_vrmode_and_wait(psvr, false) < 0 || control_power_and_wait(psvr, false) < 0) { 920 PSVR_ERROR(psvr, "Failed to shut down the headset!"); 921 } 922 923 hid_close(psvr->hid_control); 924 psvr->hid_control = NULL; 925 } 926 927 if (psvr->hid_sensor != NULL) { 928 hid_close(psvr->hid_sensor); 929 psvr->hid_sensor = NULL; 930 } 931 932 // Destroy the fusion. 933 m_imu_3dof_close(&psvr->fusion); 934 935 os_thread_helper_destroy(&psvr->oth); 936 os_mutex_destroy(&psvr->device_mutex); 937} 938 939 940/* 941 * 942 * xrt_device functions. 943 * 944 */ 945 946static xrt_result_t 947psvr_device_update_inputs(struct xrt_device *xdev) 948{ 949 struct psvr_device *psvr = psvr_device(xdev); 950 951 os_mutex_lock(&psvr->device_mutex); 952 953 update_leds_if_changed(psvr); 954 955 os_mutex_unlock(&psvr->device_mutex); 956 957 return XRT_SUCCESS; 958} 959 960static xrt_result_t 961psvr_device_get_tracked_pose(struct xrt_device *xdev, 962 enum xrt_input_name name, 963 int64_t at_timestamp_ns, 964 struct xrt_space_relation *out_relation) 965{ 966 struct psvr_device *psvr = psvr_device(xdev); 967 968 if (name != XRT_INPUT_GENERIC_HEAD_POSE) { 969 U_LOG_XDEV_UNSUPPORTED_INPUT(&psvr->base, psvr->log_level, name); 970 return XRT_ERROR_INPUT_UNSUPPORTED; 971 } 972 973 os_mutex_lock(&psvr->device_mutex); 974 975 // Read all packets. 976 read_control_packets(psvr); 977 978 // Clear out the relation. 979 U_ZERO(out_relation); 980 981 // We have no tracking, don't return a position. 982 if (psvr->tracker == NULL) { 983 out_relation->pose.orientation = psvr->fusion.rot; 984 985 out_relation->relation_flags = (enum xrt_space_relation_flags)( 986 XRT_SPACE_RELATION_ORIENTATION_VALID_BIT | XRT_SPACE_RELATION_ORIENTATION_TRACKED_BIT); 987 } else { 988 xrt_tracked_psvr_get_tracked_pose(psvr->tracker, at_timestamp_ns, out_relation); 989 } 990 991 os_mutex_unlock(&psvr->device_mutex); 992 993 //! @todo Move this to the tracker. 994 // Make sure that the orientation is valid. 995 math_quat_normalize(&out_relation->pose.orientation); 996 997 return XRT_SUCCESS; 998} 999 1000static void 1001psvr_device_destroy(struct xrt_device *xdev) 1002{ 1003 struct psvr_device *psvr = psvr_device(xdev); 1004 teardown(psvr); 1005 1006 u_device_free(&psvr->base); 1007} 1008 1009static xrt_result_t 1010psvr_compute_distortion(struct xrt_device *xdev, uint32_t view, float u, float v, struct xrt_uv_triplet *result) 1011{ 1012 struct psvr_device *psvr = psvr_device(xdev); 1013 1014 u_compute_distortion_panotools(&psvr->vals, u, v, result); 1015 return XRT_SUCCESS; 1016} 1017 1018 1019/* 1020 * 1021 * Exported functions. 1022 * 1023 */ 1024 1025struct xrt_device * 1026psvr_device_create_auto_prober(struct hid_device_info *sensor_hid_info, 1027 struct hid_device_info *control_hid_info, 1028 struct xrt_tracked_psvr *tracker, 1029 enum u_logging_level log_level) 1030{ 1031 enum u_device_alloc_flags flags = 1032 (enum u_device_alloc_flags)(U_DEVICE_ALLOC_HMD | U_DEVICE_ALLOC_TRACKING_NONE); 1033 struct psvr_device *psvr = U_DEVICE_ALLOCATE(struct psvr_device, flags, 1, 0); 1034 int ret; 1035 1036 psvr->log_level = log_level; 1037 psvr->base.update_inputs = psvr_device_update_inputs; 1038 psvr->base.get_tracked_pose = psvr_device_get_tracked_pose; 1039 psvr->base.get_view_poses = u_device_get_view_poses; 1040 psvr->base.compute_distortion = psvr_compute_distortion; 1041 psvr->base.destroy = psvr_device_destroy; 1042 psvr->base.inputs[0].name = XRT_INPUT_GENERIC_HEAD_POSE; 1043 psvr->base.name = XRT_DEVICE_GENERIC_HMD; 1044 1045 { 1046 struct u_panotools_values vals = {0}; 1047 1048 vals.distortion_k[0] = 0.75f; 1049 vals.distortion_k[1] = -0.01f; 1050 vals.distortion_k[2] = 0.75f; 1051 vals.distortion_k[3] = 0.0f; 1052 vals.distortion_k[4] = 3.8f; 1053 vals.aberration_k[0] = 0.999f; 1054 vals.aberration_k[1] = 1.008f; 1055 vals.aberration_k[2] = 1.018f; 1056 vals.scale = 1.2f * (1980 / 2.0f); 1057 vals.viewport_size.x = (1980 / 2.0f); 1058 vals.viewport_size.y = (1080); 1059 vals.lens_center.x = vals.viewport_size.x / 2.0f; 1060 vals.lens_center.y = vals.viewport_size.y / 2.0f; 1061 1062 psvr->vals = vals; 1063 1064 struct xrt_hmd_parts *hmd = psvr->base.hmd; 1065 hmd->distortion.models = XRT_DISTORTION_MODEL_COMPUTE; 1066 hmd->distortion.preferred = XRT_DISTORTION_MODEL_COMPUTE; 1067 } 1068 1069#if 1 1070 m_imu_3dof_init(&psvr->fusion, M_IMU_3DOF_USE_GRAVITY_DUR_20MS); 1071#else 1072 psvr->fusion.rot.w = 1.0f; 1073#endif 1074 1075 snprintf(psvr->base.str, XRT_DEVICE_NAME_LEN, "PS VR Headset"); 1076 snprintf(psvr->base.serial, XRT_DEVICE_NAME_LEN, "PS VR Headset"); 1077 1078 // Do mutex and thread init before any call to teardown happens. 1079 os_mutex_init(&psvr->device_mutex); 1080 os_thread_helper_init(&psvr->oth); 1081 1082 ret = open_hid(psvr, sensor_hid_info, &psvr->hid_sensor); 1083 if (ret != 0) { 1084 goto cleanup; 1085 } 1086 1087 ret = open_hid(psvr, control_hid_info, &psvr->hid_control); 1088 if (ret < 0) { 1089 goto cleanup; 1090 } 1091 1092 ret = os_thread_helper_start(&psvr->oth, sensor_thread, (void *)psvr); 1093 if (ret < 0) { 1094 goto cleanup; 1095 } 1096 1097 if (control_power_and_wait(psvr, true) < 0 || control_vrmode_and_wait(psvr, true) < 0) { 1098 goto cleanup; 1099 } 1100 1101 // Device is now on and we can read calibration data now. 1102 ret = read_calibration_data(psvr); 1103 if (ret < 0) { 1104 goto cleanup; 1105 } 1106 1107 if (debug_get_bool_option_psvr_disco()) { 1108 ret = disco_leds(psvr); 1109 } else { 1110 ret = control_leds(psvr, PSVR_LED_FRONT, PSVR_LED_POWER_MAX, (enum psvr_leds)0); 1111 } 1112 if (ret < 0) { 1113 PSVR_ERROR(psvr, "Failed to control leds '%i'", ret); 1114 goto cleanup; 1115 } 1116 1117 1118 /* 1119 * Device setup. 1120 */ 1121 1122 struct u_device_simple_info info; 1123 info.display.w_pixels = 1920; 1124 info.display.h_pixels = 1080; 1125 info.display.w_meters = 0.13f; 1126 info.display.h_meters = 0.07f; 1127 info.lens_horizontal_separation_meters = 0.13f / 2.0f; 1128 info.lens_vertical_position_meters = 0.07f / 2.0f; 1129 info.fov[0] = (float)(85.0 * (M_PI / 180.0)); 1130 info.fov[1] = (float)(85.0 * (M_PI / 180.0)); 1131 1132 if (!u_device_setup_split_side_by_side(&psvr->base, &info)) { 1133 PSVR_ERROR(psvr, "Failed to setup basic device info"); 1134 goto cleanup; 1135 } 1136 1137 /* 1138 * Setup variable. 1139 */ 1140 1141 // clang-format off 1142 u_var_add_root(psvr, "PS VR Headset", true); 1143 u_var_add_gui_header(psvr, &psvr->gui.last_frame, "Last data"); 1144 u_var_add_ro_vec3_i32(psvr, &psvr->last.samples[0].accel, "last.samples[0].accel"); 1145 u_var_add_ro_vec3_i32(psvr, &psvr->last.samples[1].accel, "last.samples[1].accel"); 1146 u_var_add_ro_vec3_i32(psvr, &psvr->last.samples[0].gyro, "last.samples[0].gyro"); 1147 u_var_add_ro_vec3_i32(psvr, &psvr->last.samples[1].gyro, "last.samples[1].gyro"); 1148 u_var_add_ro_vec3_f32(psvr, &psvr->read.accel, "read.accel"); 1149 u_var_add_ro_vec3_f32(psvr, &psvr->read.gyro, "read.gyro"); 1150 u_var_add_gui_header(psvr, &psvr->gui.control, "Control"); 1151 u_var_add_u8(psvr, &psvr->wants.leds[0], "Led A"); 1152 u_var_add_u8(psvr, &psvr->wants.leds[1], "Led B"); 1153 u_var_add_u8(psvr, &psvr->wants.leds[2], "Led C"); 1154 u_var_add_u8(psvr, &psvr->wants.leds[3], "Led D"); 1155 u_var_add_u8(psvr, &psvr->wants.leds[4], "Led E"); 1156 u_var_add_u8(psvr, &psvr->wants.leds[5], "Led F"); 1157 u_var_add_u8(psvr, &psvr->wants.leds[6], "Led G"); 1158 u_var_add_u8(psvr, &psvr->wants.leds[7], "Led H"); 1159 u_var_add_u8(psvr, &psvr->wants.leds[8], "Led I"); 1160 u_var_add_log_level(psvr, &psvr->log_level, "Log level"); 1161 // clang-format on 1162 1163 /* 1164 * Finishing touches. 1165 */ 1166 1167 if (psvr->log_level <= U_LOGGING_DEBUG) { 1168 u_device_dump_config(&psvr->base, __func__, "Sony PSVR"); 1169 } 1170 1171 // Did we get a tracker, use it! 1172 psvr->tracker = tracker; 1173 1174 // Use the new origin if we got a tracking system. 1175 if (psvr->tracker != NULL) { 1176 psvr->base.tracking_origin = psvr->tracker->origin; 1177 } 1178 1179 psvr->base.supported.orientation_tracking = true; 1180 psvr->base.supported.position_tracking = psvr->tracker != NULL; 1181 psvr->base.device_type = XRT_DEVICE_TYPE_HMD; 1182 1183 PSVR_DEBUG(psvr, "YES!"); 1184 1185 return &psvr->base; 1186 1187 1188cleanup: 1189 PSVR_DEBUG(psvr, "NO! :("); 1190 1191 teardown(psvr); 1192 free(psvr); 1193 1194 return NULL; 1195}