The open source OpenXR runtime
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

d/survive: Wait max 5 seconds for HMD and device configs

Sometimes the Index is in weird hardware states and doesn't respond properly.
In such cases, time out after 5 seconds and continue with no HMD present.

Previously we also relied on the controller configs to be already available
once the HMD config was available. In rare cases they were not - wait for
the controller configs with the same timeout.

+62 -49
+51 -48
src/xrt/drivers/survive/survive_driver.c
··· 41 41 42 42 #include "math/m_predict.h" 43 43 44 + // typically HMD config is available at around 2 seconds after init 45 + #define WAIT_TIMEOUT 5.0 46 + 44 47 // public documentation 45 48 //! @todo move to vive_protocol 46 49 #define INDEX_MIN_IPD 0.058 ··· 607 610 static bool 608 611 update_axis(struct survive_device *survive, 609 612 struct Axis *axis, 610 - const struct SurviveSimpleButtonEvent *e, 613 + const SurviveSimpleButtonEvent *e, 611 614 int i, 612 615 uint64_t now) 613 616 { ··· 890 893 } 891 894 892 895 static bool 893 - wait_for_hmd_config(SurviveSimpleContext *ctx) 896 + wait_for_device_config(const struct SurviveSimpleObject *sso) 894 897 { 895 - for (const SurviveSimpleObject *it = 896 - survive_simple_get_first_object(ctx); 897 - it != 0; it = survive_simple_get_next_object(ctx, it)) { 898 + // if not backed by a survive object, we will never get a config 899 + if (!survive_has_obj(sso)) { 900 + return false; 901 + } 898 902 899 - enum SurviveSimpleObject_type type = 900 - survive_simple_object_get_type(it); 901 - if (type == SurviveSimpleObject_HMD && survive_config_ready(it)) 903 + double start = time_ns_to_s(os_monotonic_get_ns()); 904 + do { 905 + if (survive_config_ready(sso)) { 902 906 return true; 903 - } 907 + } 908 + os_nanosleep(1000 * 1000 * 100); 909 + } while (time_ns_to_s(os_monotonic_get_ns()) - start < WAIT_TIMEOUT); 910 + 904 911 return false; 905 912 } 906 913 ··· 1067 1074 } 1068 1075 1069 1076 static bool 1070 - _create_hmd_device(struct survive_system *sys, enum VIVE_VARIANT variant) 1077 + _create_hmd_device(struct survive_system *sys, 1078 + enum VIVE_VARIANT variant, 1079 + const SurviveSimpleObject *sso) 1071 1080 { 1072 1081 enum u_device_alloc_flags flags = 1073 1082 (enum u_device_alloc_flags)U_DEVICE_ALLOC_HMD; ··· 1078 1087 U_DEVICE_ALLOCATE(struct survive_device, flags, inputs, outputs); 1079 1088 sys->hmd = survive; 1080 1089 survive->sys = sys; 1081 - survive->survive_obj = NULL; 1090 + survive->survive_obj = sso; 1082 1091 survive->variant = variant; 1083 1092 1084 1093 survive->base.name = XRT_DEVICE_GENERIC_HMD; ··· 1089 1098 survive->base.get_view_pose = survive_device_get_view_pose; 1090 1099 survive->base.tracking_origin = &sys->base; 1091 1100 1092 - survive_simple_start_thread(sys->ctx); 1093 - 1094 - //! @todo support hotplugging for hmd and controllers, don't block 1095 - //! monado until hmd available' 1096 - while (!wait_for_hmd_config(sys->ctx)) { 1097 - SURVIVE_INFO(survive, "Waiting for survive HMD config parsing"); 1098 - os_nanosleep(1000 * 1000 * 100); 1099 - } 1100 - SURVIVE_INFO(survive, "survive got HMD config"); 1101 - 1102 - while (!survive->survive_obj) { 1103 - SURVIVE_INFO(survive, "Waiting for survive HMD to be found..."); 1104 - for (const SurviveSimpleObject *it = 1105 - survive_simple_get_first_object(sys->ctx); 1106 - it != 0; 1107 - it = survive_simple_get_next_object(sys->ctx, it)) { 1108 - const char *codename = survive_simple_object_name(it); 1109 - 1110 - enum SurviveSimpleObject_type type = 1111 - survive_simple_object_get_type(it); 1112 - if (type == SurviveSimpleObject_HMD && 1113 - sys->hmd->survive_obj == NULL) { 1114 - SURVIVE_INFO(survive, "Found HMD: %s", 1115 - codename); 1116 - survive->survive_obj = it; 1117 - } 1118 - } 1119 - } 1120 1101 SURVIVE_INFO(survive, "survive HMD present"); 1121 1102 1122 1103 survive->base.hmd->blend_mode = XRT_BLEND_MODE_OPAQUE; ··· 1513 1494 } else if (strcmp(model_number, "VIVE Tracker Pro MV") == 0) { 1514 1495 variant = VIVE_VARIANT_TRACKER_v2; 1515 1496 U_LOG_D("Found Gen 2 tracker."); 1497 + } else if (strcmp(model_number, "Utah MP") == 0) { 1498 + U_LOG_W("Found Utah MP (Index HMD), not a controller!"); 1516 1499 } else { 1517 - U_LOG_E("Failed to parse controller variant"); 1500 + U_LOG_E("Failed to parse controller variant: %s", model_number); 1518 1501 } 1519 1502 1520 1503 return variant; ··· 1557 1540 struct survive_system *ss = U_TYPED_CALLOC(struct survive_system); 1558 1541 1559 1542 struct xrt_prober_device *dev = devices[index]; 1560 - enum VIVE_VARIANT variant = _product_to_variant(dev->product_id); 1561 - U_LOG_I("survive: Assuming variant %d", variant); 1543 + 1544 + survive_simple_start_thread(actx); 1562 1545 1563 1546 ss->ctx = actx; 1564 1547 ss->base.type = XRT_TRACKING_TYPE_LIGHTHOUSE; ··· 1571 1554 1572 1555 ss->ll = debug_get_log_option_survive_log(); 1573 1556 1574 - _create_hmd_device(ss, variant); 1575 - 1576 1557 /* iterate over all devices, if SurviveSimpleObject_OBJECT parse config 1577 1558 * and if controller, add it with variant from config. 1578 1559 */ ··· 1580 1561 survive_simple_get_first_object(ss->ctx); 1581 1562 it != 0; it = survive_simple_get_next_object(ss->ctx, it)) { 1582 1563 1564 + if (!wait_for_device_config(it)) { 1565 + U_LOG_IFL_E(ss->ll, 1566 + "Failed to get device config from survive"); 1567 + continue; 1568 + } 1569 + 1570 + U_LOG_IFL_D(ss->ll, "Got device config from survive"); 1571 + 1583 1572 enum SurviveSimpleObject_type type = 1584 1573 survive_simple_object_get_type(it); 1585 - if (type == SurviveSimpleObject_OBJECT) { 1574 + 1575 + if (type == SurviveSimpleObject_HMD) { 1576 + enum VIVE_VARIANT variant = 1577 + _product_to_variant(dev->product_id); 1578 + U_LOG_I("survive HMD: Assuming variant %d", variant); 1579 + _create_hmd_device(ss, variant, it); 1580 + } else if (type == SurviveSimpleObject_OBJECT) { 1586 1581 char *json_string = survive_get_json_config(it); 1587 1582 cJSON *json = cJSON_Parse(json_string); 1588 1583 if (!cJSON_IsObject(json)) { 1589 1584 U_LOG_IFL_E(ss->ll, 1590 1585 "Could not parse JSON data."); 1586 + cJSON_Delete(json); 1591 1587 continue; 1592 1588 } 1593 1589 ··· 1603 1599 break; 1604 1600 default: 1605 1601 U_LOG_IFL_D(ss->ll, "Skip non controller obj."); 1602 + U_LOG_IFL_T(ss->ll, "json: %s", json_string); 1606 1603 break; 1607 1604 } 1608 - 1609 1605 cJSON_Delete(json); 1606 + } else { 1607 + U_LOG_IFL_D(ss->ll, "Skip non OBJECT obj."); 1610 1608 } 1611 1609 } 1612 1610 ··· 1614 1612 // (void *)ss->controllers[0], (void *)ss->controllers[1]); 1615 1613 1616 1614 if (ss->ll <= U_LOGGING_DEBUG) { 1617 - u_device_dump_config(&ss->hmd->base, __func__, "libsurvive"); 1615 + if (ss->hmd) { 1616 + u_device_dump_config(&ss->hmd->base, __func__, 1617 + "libsurvive"); 1618 + } 1618 1619 } 1619 1620 1620 1621 int out_idx = 0; 1621 - out_xdevs[out_idx++] = &ss->hmd->base; 1622 + if (ss->hmd) { 1623 + out_xdevs[out_idx++] = &ss->hmd->base; 1624 + } 1622 1625 if (&ss->controllers[SURVIVE_LEFT_CONTROLLER]) { 1623 1626 out_xdevs[out_idx++] = 1624 1627 &ss->controllers[SURVIVE_LEFT_CONTROLLER]->base;
+8 -1
src/xrt/drivers/survive/survive_wrap.c
··· 22 22 #pragma GCC diagnostic pop 23 23 24 24 bool 25 + survive_has_obj(const SurviveSimpleObject *sso) 26 + { 27 + SurviveObject *so = survive_simple_get_survive_object(sso); 28 + return so != NULL; 29 + } 30 + 31 + bool 25 32 survive_config_ready(const SurviveSimpleObject *sso) 26 33 { 27 34 SurviveObject *so = survive_simple_get_survive_object(sso); 28 - return so->conf != 0; 35 + return so && so->conf != 0; 29 36 } 30 37 31 38 char *
+3
src/xrt/drivers/survive/survive_wrap.h
··· 12 12 #include "survive_api.h" 13 13 14 14 bool 15 + survive_has_obj(const SurviveSimpleObject *sso); 16 + 17 + bool 15 18 survive_config_ready(const SurviveSimpleObject *sso); 16 19 17 20 char *