-
Notifications
You must be signed in to change notification settings - Fork 163
Description
Describe the bug
I am trying to find a way to reestablish a communication from a Vive Controller (or Vive Tracker) after it was turned off and on again. In the current state of libsurvive with libusb, the according SurviveObject is not reopened for communication again.
My approach
My investigation led me to driver_vive.libusb.h to function handle_transfer. There is a flag called request_reopen which is evaluated in driver_vive.c::survive_handle_close_request_flag. This flag will not be set in my case of a Vive Controller connected over a Watchman Dongle, since in the function handle_transfer, iface->consecutive_timeouts will never be increased more than once for wireless connections. It will be increased often when i connect the Controller via cable - this is why @jdavidberger eventually came up with a threshold of 3 consecutive_timeouts to set the request_reopen flag (commit d939c24). My approach is to modify this section in driver_vive.libusb.h::handle_transfer like the following:
// put this function before `handle_transfer`
static bool survive_device_is_rf(const struct DeviceInfo *device_info) {
switch (device_info->type) {
case USB_DEV_HMD:
case USB_DEV_HMD_IMU_LH:
case USB_DEV_W_WATCHMAN1:
case USB_DEV_TRACKER0:
case USB_DEV_TRACKER1:
return false;
}
return true;
}
static void handle_transfer(struct libusb_transfer *transfer) {
uint64_t time = OGGetAbsoluteTimeUS();
SurviveUSBInterface *iface = transfer->user_data;
SurviveContext *ctx = iface->ctx;
if (!iface->shutdown && transfer->status == LIBUSB_TRANSFER_TIMED_OUT) {
iface->consecutive_timeouts++;
// no consecutive timeout counting when using wireless Controller
bool is_rf_device = survive_device_is_rf(iface->usbInfo->device_info);
if(iface->consecutive_timeouts >= 3 || is_rf_device) {
SV_WARN("%f %s Device turned off: %d", survive_run_time(ctx), survive_colorize_codename(iface->assoc_obj),
transfer->status);
goto object_turned_off;
} else {
return;
}
}
// ...Now this seems to work for me although i am sure the issue is related to some different part of the software. Then i came across a different issue: The SurviveObject is destroyed in this case and after reopening the device and creating a new SurviveObject, some seconds later driver_global_scene_solver.c needs to run_optimization. Later in the chain, survive_create_device is run with garbage SurviveObject instances. I assume that this is a synchronisation issue between the threads.
Data
- default MPFit poser, HTCVive driver
Hardware setup
- 1x Lighthouse v2
- 1x Vive Controller
- 1x Watchman dongle
Desktop (please complete the following information):
- Fedora Linux 40
- latest libsurvive
- libusb 1.0.27