CertainLach/VivePro2-Linux-Driver

Cosmos Elite support ?

MonsieurLanza opened this issue · 46 comments

Hello, do you have an idea what amount of effort it would take to get Cosmos Elite (the one with lighthouse tracking) working, using this repo as a basis ?

Should I dig in, or ditch the idea straight away ?

I use Arch, btw. ;)
Thanks.

So far, after some battle with kernel versions and config here and on https://github.com/santeri3700/vive-pro-2-on-linux, I was able to get a patched kernel (with the last patches which includes the cosmos ID \o/), and the vivepro2 driver.

Patches need another update, they won’t work on the latest linux-drm-misc-next, I had to get the 2023-01-12 tag. And the provided config failed to boot on my machine.

Steam now displays the VR icon in the toolbar, and on my nvidia box with the AllowHMD option set in xorg conf, I can see the render… on my primary display. So I now know the tracking works, and the render seems somewhat correct, I’m not sure about the dimensions. And the system freezes while exiting SteamVR.

But with or without the AllowHMD flag, nothing renders on HMD itself. My guess because the vivepro2 driver does not set the mode properly (only vivepro2 modes seems available), but I now have to find a way to get logs.

For cosmos support, you should at least

  1. Set your modes here: https://github.com/CertainLach/VivePro2-Linux-Driver/blob/master/crates/vive-hid/src/lib.rs#L169 (Only one mode is available on cosmos)
  2. Disable every writing method in vive-hid crate (Because cosmos has other protocols)

There was a release of steamvr part with cosmos-specific fixes here: https://github.com/CertainLach/VivePro2-Linux-Driver/releases/tag/v0.3.1-cosmos
However my tester reported it doesn't work, and most likely some other kernel changes are required.

Set of changes, that was applied on v0.3.1-cosmos tag:
https://gist.github.com/CertainLach/888c4958678bee5f1736bc2ac3a5095d

It also disables lens distortion functionality, as I'm not sure of its protocol on cosmos either.

Thank you.

Ok, I had correct modes, and product ID. I did not remove any of the writing, though.

You should remove writings, as cosmos has slightly different protocol, which also lacks some of the vive pro 2 features (I.e mode switching)

Well, stuck on "Permission denied". Maybe stupid, but still…

�[31mERROR�[0m �[2mdriver_proxy::server::driver_host�[0m�[2m:�[0m failed to wrap hmd: hid error: hid error: hidapi error: Permission denied

cosmos-log.txt

I have to stop for tonight.

chmod a+rw /dev/hidraw* for a quick test

There is no udev rules for vive cosmos installed

Thanks again.

So it does not work out of the box. No image, and cosmos is led still red.

At least it does not seem to crash the whole system on exit. Note : stations are not going to standby mode, despite driver saying so.

cosmos-log.txt

To make stations sleep, you should enable power management for them, driver tells its going to put only managed ones to sleep.

Ok.

Now, for what I understand, there is probably an « usb switch » to turn on display.

OpenHMD does this by sending a magic sequence https://github.com/OpenHMD/OpenHMD/blob/master/src/drv_htc_vive/vive.c#L594 , and as the sequence is different for Vive an Vive Pro, I guess it is different for Cosmos. And I guess on Vive Pro 2 setting the display mode does turn the display on.

If I understand correctly, I just have to find that value in the middle if the flow of USB traffic I just wiresharked, write it and see if something happens.

For Vive Pro 2 nothing is required, the display just starts working as soon as it receives the DisplayPort signal.
There are commands for led control, but they are not mandatory to start displaying an image.

I didn't tough about Vive Cosmos requiring it, but this may be the case

I have looked in EyesReader.dll, and seems like there is some function for managing HMD panel.
Is I can see, report should have 0x782938 as its 1-3 bytes (counting from zero) as part of HMD_SetFeatures call, then should contain 0x80 and power state (1 byte) somewhere in data (Too lazy to count bytes, this report is created in SetPowerState function), and rest is filled with zeros.

I think you should be able to easly recover all of the protocol messages by using api monitor (http://www.rohitab.com/apimonitor), and capturing HidD_SetFeature calls from the EyesReader.dll library, every function there has self-explaining name

Config for the lens-server library is returned by GetInHouseDistortionJson, and then there is some other possible useful setters.

Thank you for all that, I’ll have a deeper look when I can get some free time again.

image

PanelOnOff \o/

So far I learned a lot, and have a better idea of what I need to do, which is basically write another ViveDevice for cosmos, there is too much difference with the vivepro2 one for it to make sense.

I have to find larger chunks of time, as I need to (re)learn things, dust off my little rust knowledge, go deeper in HID, Windows tooling…

@CertainLach do you have the vivepro 2 hid descriptors, so that I can compare ?

I’m not getting why with the cosmos I get 2 Hid devices with the right signature, and they do have slightly different hid descriptors. HTC’s drivers seem to "talk" to the first one they find, but I’m not certain.

And did I mention that I HATE little endian ? I want my MC68000 amiga back.

I’m not getting why with the cosmos I get 2 Hid devices with the right signature, and they do have slightly different hid descriptors. HTC’s drivers seem to "talk" to the first one they find, but I’m not certain.

Its the same for Vive Pro 2, one device is for lighthouse driver, and it implements valve protocols (SteamDevice struct in this driver), and then there is Vive device itself, which implements HTC protocols (ViveDevice struct)

Driver only needs to talk to ViveDevice, SteamDevice is compatible with lighthouse driver, and will work by itself.

There is nothing useful in HID descriptors

Writing captured data didn't work?

I really have 2 ˋViveDeviceˋ "0x0bb4:0x0313" signature, along with 2 SteamDevice for lighthouse tracking, when doing a device enumeration.

I reproduced the exact sequence of the hmdPanelOnOff(), but did not see a single pixel light up.

That's weird, are you sure they are both active on the same time?
That may be possible with SteamDevice, as they are differentiated by serial number, but ViveDevice?..

If there is multiple ViveDevices - check their serials, and use the correct one with open method, instead of just calling open_first

Ok, there is my descriptors.

ViveDevice:

0x06, 0x00, 0xFF,  // Usage Page (Vendor Defined 0xFF00)
0x09, 0x01,        // Usage (0x01)
0xA1, 0x01,        // Collection (Application)
0x85, 0x01,        //   Report ID (1)
0x09, 0x01,        //   Usage (0x01)
0x15, 0x00,        //   Logical Minimum (0)
0x26, 0xFF, 0x00,  //   Logical Maximum (255)
0x75, 0x08,        //   Report Size (8)
0x95, 0x3F,        //   Report Count (63)
0x81, 0x82,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x85, 0x01,        //   Report ID (1)
0x09, 0x01,        //   Usage (0x01)
0x91, 0x82,        //   Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Volatile)
0x85, 0x02,        //   Report ID (2)
0x09, 0x02,        //   Usage (0x02)
0x15, 0x00,        //   Logical Minimum (0)
0x26, 0xFF, 0x00,  //   Logical Maximum (255)
0x75, 0x08,        //   Report Size (8)
0x95, 0x3F,        //   Report Count (63)
0x81, 0x82,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x85, 0x02,        //   Report ID (2)
0x09, 0x02,        //   Usage (0x02)
0x91, 0x82,        //   Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Volatile)
0x85, 0x03,        //   Report ID (3)
0x09, 0x00,        //   Usage (0x00)
0x15, 0x00,        //   Logical Minimum (0)
0x26, 0xFF, 0x00,  //   Logical Maximum (255)
0x75, 0x08,        //   Report Size (8)
0x95, 0x3F,        //   Report Count (63)
0x81, 0x82,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x85, 0x04,        //   Report ID (4)
0x09, 0x00,        //   Usage (0x00)
0xB1, 0x82,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Volatile)
0xC0,              // End Collection

// 71 bytes

SteamDevice:

0x06, 0x00, 0xFF,  // Usage Page (Vendor Defined 0xFF00)
0x09, 0x01,        // Usage (0x01)
0xA1, 0x01,        // Collection (Application)
0x15, 0x00,        //   Logical Minimum (0)
0x26, 0xFF, 0x00,  //   Logical Maximum (255)
0x75, 0x08,        //   Report Size (8)
0xA1, 0x01,        //   Collection (Application)
0x95, 0x33,        //     Report Count (51)
0x85, 0x20,        //     Report ID (32)
0x09, 0x01,        //     Usage (0x01)
0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0xC0,              //   End Collection
0xA1, 0x01,        //   Collection (Application)
0x95, 0x02,        //     Report Count (2)
0x85, 0x01,        //     Report ID (1)
0x09, 0x01,        //     Usage (0x01)
0xB1, 0x02,        //     Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0,              //   End Collection
0xA1, 0x01,        //   Collection (Application)
0x95, 0x2E,        //     Report Count (46)
0x85, 0x03,        //     Report ID (3)
0x09, 0x01,        //     Usage (0x01)
0xB1, 0x02,        //     Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0,              //   End Collection
0xA1, 0x01,        //   Collection (Application)
0x95, 0x04,        //     Report Count (4)
0x85, 0x04,        //     Report ID (4)
0x09, 0x01,        //     Usage (0x01)
0xB1, 0x02,        //     Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0,              //   End Collection
0xA1, 0x01,        //   Collection (Application)
0x95, 0x04,        //     Report Count (4)
0x85, 0x07,        //     Report ID (7)
0x09, 0x01,        //     Usage (0x01)
0xB1, 0x02,        //     Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0,              //   End Collection
0xA1, 0x01,        //   Collection (Application)
0x95, 0x34,        //     Report Count (52)
0x85, 0x05,        //     Report ID (5)
0x09, 0x01,        //     Usage (0x01)
0xB1, 0x02,        //     Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0,              //   End Collection
0xA1, 0x01,        //   Collection (Application)
0x95, 0x08,        //     Report Count (8)
0x85, 0x08,        //     Report ID (8)
0x09, 0x01,        //     Usage (0x01)
0xB1, 0x02,        //     Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0,              //   End Collection
0xA1, 0x01,        //   Collection (Application)
0x95, 0x3F,        //     Report Count (63)
0x85, 0x09,        //     Report ID (9)
0x09, 0x01,        //     Usage (0x01)
0xB1, 0x02,        //     Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0,              //   End Collection
0xA1, 0x01,        //   Collection (Application)
0x95, 0x01,        //     Report Count (1)
0x85, 0x06,        //     Report ID (6)
0x09, 0x01,        //     Usage (0x01)
0xB1, 0x02,        //     Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0,              //   End Collection
0xA1, 0x01,        //   Collection (Application)
0x95, 0x03,        //     Report Count (3)
0x85, 0x0B,        //     Report ID (11)
0x09, 0x01,        //     Usage (0x01)
0xB1, 0x02,        //     Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0,              //   End Collection
0xA1, 0x01,        //   Collection (Application)
0x95, 0x03,        //     Report Count (3)
0x85, 0x0A,        //     Report ID (10)
0x09, 0x01,        //     Usage (0x01)
0xB1, 0x02,        //     Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0,              //   End Collection
0xA1, 0x01,        //   Collection (Application)
0x95, 0x01,        //     Report Count (1)
0x85, 0x0C,        //     Report ID (12)
0x09, 0x01,        //     Usage (0x01)
0xB1, 0x02,        //     Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0,              //   End Collection
0xA1, 0x01,        //   Collection (Application)
0x95, 0x3F,        //     Report Count (63)
0x85, 0x13,        //     Report ID (19)
0x09, 0x01,        //     Usage (0x01)
0xB1, 0x02,        //     Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0,              //   End Collection
0xA1, 0x01,        //   Collection (Application)
0x95, 0x3F,        //     Report Count (63)
0x85, 0x01,        //     Report ID (1)
0x09, 0x01,        //     Usage (0x01)
0x91, 0x02,        //     Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0,              //   End Collection
0x15, 0x00,        //   Logical Minimum (0)
0x26, 0xFF, 0x00,  //   Logical Maximum (255)
0x75, 0x08,        //   Report Size (8)
0xA1, 0x01,        //   Collection (Application)
0x95, 0x02,        //     Report Count (2)
0x85, 0x10,        //     Report ID (16)
0x09, 0x01,        //     Usage (0x01)
0xB1, 0x02,        //     Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0,              //   End Collection
0xA1, 0x01,        //   Collection (Application)
0x95, 0x3F,        //     Report Count (63)
0x85, 0x11,        //     Report ID (17)
0x09, 0x01,        //     Usage (0x01)
0xB1, 0x02,        //     Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0,              //   End Collection
0xA1, 0x01,        //   Collection (Application)
0x95, 0x01,        //     Report Count (1)
0x85, 0x12,        //     Report ID (18)
0x09, 0x01,        //     Usage (0x01)
0xB1, 0x02,        //     Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0,              //   End Collection
0xC0,              // End Collection

// 209 bytes

SteamDevice looks the same.

Cosmos one is way simpler
# HTC Corporation VIVE COSMOS
# 0x06, 0x00, 0xff,              // Usage Page (Vendor Defined Page 1)  0
# 0x09, 0x01,                    // Usage (Vendor Usage 1)              3
# 0xa1, 0x01,                    // Collection (Application)            5
# 0x15, 0x00,                    //  Logical Minimum (0)                7
# 0x26, 0xff, 0x00,              //  Logical Maximum (255)              9
# 0x75, 0x08,                    //  Report Size (8)                    12
# 0x96, 0x00, 0x04,              //  Report Count (1024)                14
# 0x09, 0x01,                    //  Usage (Vendor Usage 1)             17
# 0x81, 0x02,                    //  Input (Data,Var,Abs)               19
# 0x95, 0x40,                    //  Report Count (64)                  21
# 0x09, 0x01,                    //  Usage (Vendor Usage 1)             23
# 0xb1, 0x02,                    //  Feature (Data,Var,Abs)             25
# 0xc0,                          // End Collection                      27
# 
R: 28 06 00 ff 09 01 a1 01 15 00 26 ff 00 75 08 96 00 04 09 01 81 02 95 40 09 01 b1 02 c0
N: HTC Corporation VIVE COSMOS
I: 3 0bb4 0313
Not even a feature report ID.

Both /dev/hidraw0 and /dev/hidraw1 reports the same, and usbhid-dump reports 2 devices for

$ usbhid-dump -d 0bb4:0313
004:004:001:DESCRIPTOR         1674908243.867237
 06 00 FF 09 01 A1 01 15 00 26 FF 00 75 08 96 00
 04 09 01 81 02 95 40 09 01 B1 02 C0

004:004:000:DESCRIPTOR 1674908243.867394
06 00 FF 09 01 A1 01 15 00 26 FF 00 75 08 96 00
04 09 01 81 02 95 40 09 01 B1 02 C0

However lsusb reports only one Vive cosmos, so it looks like there is 1 device with 2 hid interfaces.

There is only 1 SteamDevice, however, but 2 watchman dongles (28de:2101). My mistake.

Ok, understood one thing. Everything go through the feature report on Cosmos, even the read_config. They could have used http instead of hid without much difference :D

image

PanelOnOff \o/

The values in the report here are… pointers! Which make little sense at first sight.

There are missing memzeros/wrong array sizes used, it is possible that this is stack values leaked to a SetFeature call.
Example (pseudocode):

char report[10];
int somevalue;
report[0] = 0;
...
SetFeature(&report) // where report is expected to be a char[65 - header], so value of somevalue is also included in report value

This is fairly common in Vive Pro 2 driver too

I see, this is not rust code ^^.

Thing is, the start of the report seems invariable whether it is an On or an Off call. There is something I miss here.

BTW, the config file does not fit at all inside the Vive Pro 2 struct (ViveConfig) : https://gist.github.com/MonsieurLanza/583613475093b716f65c32260f8c364a

I've got a regular Vive headset and a Cosmos Elite.. trying to get the Cosmos going.
I've recompiled my kernel etc
and followed through on CertainLatch's driver with Cosmos modifications, compiled and installed.
I'm now at the same stage as @MonsieurLanza where the headset display isn't coming on.

I do get a tracked view when I turn on SteamVR's "Display VR View" which makes it look like it's sooo close to working.

My controllers won't connect/ track though - but work fine when I plug them into the computer with a usb cable.
I also noticed that the single trigger button on the headset won't work ( when trying to cancel a VR startup notification without the vr controllers).
I have already tried sudo chmod a+rw /dev/hidraw* (and on /dev/usb/hiddev* as well).

p.s. @MonsieurLanza - yeah! Amiga/68k !! ;)

@JJones780 I have made progress on the PR here #20 . It currently dumps the cosmos config file in the logs. I have some hid dump from windows too, and have to make this in.

It’s close but not so close. The tracking part it similar to other vive/valve lightouse products and work out of the box, but the init of the display is completely different. So the vive_hid lib needs specific code, maybe different config struct/handling, as does the hmd init part in driver_proxy.

I’ve been away because of work, but as I plan to use the cosmos to make things with Godot, and given the fact I cannot stand windows except to launch SteamVR from time to time, I’ll get back at it soon.

Nvidia drivers may part of the problem, I’d like to check with an AMD GPU, but I need to dig in boxes, as it is packed during house renovation.

(This little endian thing makes it stupidly complex to read/write bytes in memory. I will never understand.)

I tried accessing the display via i2c and other methods but also ran into a nvidia bug.

I don't have windows installed at all. I am happy to see I am able to switch between the Original HTC Vive and Cosmos headsets with only the driver file change ( driver_lighthouse_real.so ) which means I'll be able to keep up on the cosmos hacking.

@MonsieurLanza

RE: Linux, HTC Vive Cosmos connected and powered.
note: It seems that the cameras and Bluetooth devices are visible but not enabled.
Maybe there's a more general onOff type command we should be looking for; over and above the PanelOnOff?

I opened up the system.img file for the headset ( yes it's Android but I'm betting not connected to the display panels other than turning them or maybe only their backlights off and on ) . It provides ADB, HID and UVC but I don't know of any way to switch it to ADB to connect to the running headset. Looking through the system.img files to see if I can find any hints as to the hardware/startup/hid settings. If anyone has ideas to look into please let me know.
The best bet is probably still the capture of USB HID traffic from a windows machine.

I am sorry I have not been around for some monthes, life has surprises… And I won’t be able to get something done until july, or august. No more room for that during house renovation.

I do not have the problems with controllers/bluetooth you mention. For me, everything works fine, except display. Tracking of the headset and the controllers works, I am able to see it by enabling SteamVR view.

I do have USB hid dumps and API calls. But to get further in, and really try to reproduce the HID exchanges (which are not really HID, but anyway), I have to get the driver to accept the cosmos configuration file, which is quite different from the vive pro 2 one.

hi, I'm very interested in getting this working (VR is the only reason I ever have to boot to windows...) so before I start hacking at it, has any progress been made here or elsewhere which hasn't been captured in this thread?

Sorry, nothing new to report from me.
Windows USB "feature report" traffic trace is needed. I was hoping @MonsieurLanza would be finished his house renovations but I know those easily go overtime ;)
Maybe I'll try digging into the Android code that runs on the headset again and hope the Monsieur appears again soon!

In the end I just bought a cheap second hand Vive Pro which isn't really any worse in terms of specs (and it has OLED!) and is supported on linux (in theory). In practice I also haven't been able to get it to work properly because of ValveSoftware/SteamVR-for-Linux#175... so that's annoying.