RiftCat / vridge-api

VRidge API is a way to read and write all head and motion controller tracking data used by VRidge.
https://riftcat.com/vridge
MIT License
53 stars 15 forks source link

Headtracking Packet - TaskType is Int (not Byte) #4

Closed mungewell closed 7 years ago

mungewell commented 7 years ago

Small mistake in the Documentation: https://github.com/RiftCat/vridge-api/wiki/Head-Tracking-API#request-packets

This can be built as follows (Python Construct), and results in a totals packet length of 76 bytes.

# SendRadRotationAndPosition
packet = Struct(
        Const(Int32ul, 2),
        Const(Int32ul, 3),
        Const(Int32ul, 24),
        "data" / Padded(64, Array(6, Float32l)),
)
BoomBrush commented 7 years ago

Thank you for posting that. I'm trying to send position information over python and I had no clue what was meant by "binary-serialized messages". How would I convert "packet" to a form so that I can send it using the ZMQ module. I would be using (my connection).send(packet) but that errors. I'd love to get in contact with you about this.

balukin commented 7 years ago

Packets are serialized and deserialized using .NET's binary formatter (Marshal.StructureToPtr) that reads/writes fields in order of declaration in given struct. It also keeps fields aligned to number of bytes specified by Pack variable.

In case of HeadTrackingRequest it should be int32 (4 bytes), byte(padded to 4 bytes), int32 (4 bytes) + byte[64], total of 76 bytes.

I agree that the current packet format has few details missing from the specification because .NET's struct marshaling is better suited for local memory operation and not network transport between different platforms and architectures.

That's why in next API version we're going to use protobuf serialization and structuring which can work on every platform without worrying about padding, endianness, field order and all that jazz. It's much better for API use-case and should have been used from the beginning.

We launched with .NET's default tools because first version of the API was mostly for internal use. API will be compatible with v2 so you can use write your code now and it will work in the future. Once v3 is completed it will be easier to serialize packets from languages other than .NET family.

I'll try to verify those layouts next week and clarify paddings and byte & field order. Until then you can read those articles as a temporarily solution: https://msdn.microsoft.com/en-us/library/system.runtime.interopservices.layoutkind(v=vs.110).aspx https://msdn.microsoft.com/en-us/library/system.runtime.interopservices.structlayoutattribute.pack%28v=vs.110%29.aspx

BoomBrush commented 7 years ago

I got it working, I was just searching for the wrong terms. Massive THANK YOU to mungewell though, as I started looking into those modules and used his example in my code. A bit sad that my solution won't work anymore if you change how the API works. If you add some examples in languages other than C++ (like Python) including the necessary librarys nd such, that would be brilliant.

balukin commented 7 years ago

A bit sad that my solution won't work anymore if you change how the API works

It will work, we'll keep old endpoints accessible. New plugins will use new serialization specs but old ones will work fine.

mungewell commented 7 years ago

Hi, I can work either way (Int32, or Byte padded to 4 bytes). Have to experiment when the new API comes out.

For reference my example script is here: https://github.com/mungewell/pyPSVR/tree/master/example3_vridgeapi

BoomBrush commented 7 years ago

That is pretty much an exact copy of what I've been doing for the last 5 hours. I'm actually working on my own room scale VR setup. Using ps3eye cameras I will calculate my position in the room then give that information to Vridge. Read more about it here: https://www.reddit.com/r/vridge/comments/673ssi/

mungewell commented 7 years ago

Very interesting! That's pretty much exactly what I'm doing with the PSVR... what do they say about great minds? ;-)

What are you using for markers on the phone/headset. I did some experimentation with DataMatrix and April tags - see 'example1' in the same repo.

I have a copy of clips here: https://youtu.be/OpAQQPBD7jk https://youtu.be/fcf8Qy-Vcgo

BoomBrush commented 7 years ago

I'm not using a marker. I plan to use 4 or 5 PS3Eye cameras all with their IR blocking filters removed and with IR pass filters applied so that they only see IR. Then, each camera will be tracking a pingpong ball on top of my head. The ping pong ball has an infrared LED in the middle of it causing it to light up to the cameras. So I made some software which looks at the PS3Eye cameras and using blob detection gets the X,Y of the ping pong ball. Each camera is connected to a separate computer (yes a lot of spare laptops!) and sends the X,Y location over the network to a central computer. Then, software on that computer (I didnt write this software) takes all the X,Y points and after some calibration will do some fancy matrix math and produce a single X,Y,Z point. Then, my vridge program I just made about the same time you did sends this X,Y,Z to Vridge to use for it's positional information.

At least that is the plan. I can't test it right now because it's day and the window in my room is letting too much light in (even with blinds fully closed) so the software is having issues with the blob detection. Since theres a lot of light everywhere in the room from the sun, random objects light up and the camera can't tell the difference. I tried to make it select only the biggest blob but that didn't help.

If I actually get this working I will drop a video and release all my code for it.

In order to use the PS3Eye cameras in python the driver I have chosen only forces me to use ONLY 1 camera per computer. On the plus side, I can use OpenCV's webcam interface and get direct images. I've tried other solutions where I import a .dll and try to use some librarys of which have no documentation and that just hasn't worked out. This seems to work fine. In the future I'd like to plug all the cameras into one computer. Right now, the software actually only needs 2 cameras to actually work but 4-5 will greatly increase the accuracy leading to a better VR experience.

BoomBrush commented 7 years ago

I got my program working. Heres a description of it I wrote on reddit:

https://www.reddit.com/r/vridge/comments/6gphgi/working_position_tracking_using_2_ps3eye_cameras/

balukin commented 7 years ago

I'm closing this issue since it seems to be resolved.

We'll be changing packets structs/serialization to make it less confusing. See https://github.com/RiftCat/vridge-api/issues/9.