{"id":13514013,"url":"https://github.com/collabora/libsurvive","last_synced_at":"2025-05-15T09:02:58.309Z","repository":{"id":37815517,"uuid":"75029407","full_name":"collabora/libsurvive","owner":"collabora","description":"Open Source Lighthouse Tracking System","archived":false,"fork":false,"pushed_at":"2025-04-07T14:14:44.000Z","size":7622,"stargazers_count":781,"open_issues_count":56,"forks_count":142,"subscribers_count":56,"default_branch":"master","last_synced_at":"2025-05-07T12:55:52.642Z","etag":null,"topics":["hmd","htc-vive","indoor-positioning","indoor-positioning-algorithms","lighthouse","localization","openvr","ros","valve-index","vive","vive-controller","vive-tracker","vr"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/collabora.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2016-11-29T01:14:05.000Z","updated_at":"2025-05-07T11:56:13.000Z","dependencies_parsed_at":"2022-07-12T16:54:11.627Z","dependency_job_id":"ff4be523-c7e9-420a-a97b-870f6c1cb771","html_url":"https://github.com/collabora/libsurvive","commit_stats":{"total_commits":2017,"total_committers":48,"mean_commits":"42.020833333333336","dds":"0.35052057511155177","last_synced_commit":"4fb6d888d0277a8a3ba725e63707434d80ecdb2a"},"previous_names":["collabora/libsurvive","cntools/libsurvive"],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/collabora%2Flibsurvive","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/collabora%2Flibsurvive/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/collabora%2Flibsurvive/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/collabora%2Flibsurvive/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/collabora","download_url":"https://codeload.github.com/collabora/libsurvive/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252882788,"owners_count":21819155,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["hmd","htc-vive","indoor-positioning","indoor-positioning-algorithms","lighthouse","localization","openvr","ros","valve-index","vive","vive-controller","vive-tracker","vr"],"created_at":"2024-08-01T05:00:43.054Z","updated_at":"2025-05-07T12:55:54.501Z","avatar_url":"https://github.com/collabora.png","language":"C","readme":"# libsurvive [![Build and Test](https://github.com/cntools/libsurvive/workflows/Build%20and%20Test/badge.svg)](https://github.com/cntools/libsurvive/actions/workflows/cmake.yml)[![Build Nuget](https://github.com/cntools/libsurvive/workflows/Build%20Nuget/badge.svg)](https://github.com/cntools/libsurvive/actions/workflows/build_nuget.yml)[![Build Wheels](https://github.com/cntools/libsurvive/workflows/Build%20Wheels/badge.svg)](https://github.com/cntools/libsurvive/actions/workflows/build_wheels.yml)\n\n![Logo](https://cloud.githubusercontent.com/assets/2748168/24084003/9095c98a-0cb8-11e7-88a3-575f9f4c7bb4.png)\n\n\nLibsurvive is a set of tools and libraries that enable 6 dof tracking on \n[lighthouse and vive](https://en.wikipedia.org/wiki/HTC_Vive) based systems that is completely open source and can run \non any device. It currently supports both SteamVR 1.0 and SteamVR 2.0 generation of devices and should support any tracked\nobject commercially available. \n\nSince the focus is on tracking; it does not independently run the HMD. For an open souce stack that does that see [monado](https://monado.freedesktop.org/)\n\nMost of the development is discussed on Discord.  [Join the chat and discussion in our discord!](https://discordapp.com/invite/7QbCAGS). There is also a [matrix bridge](https://app.element.io/#/room/#libsurvive-main:matrix.org) available to join the discussion. \n\nAn example application is libsurvive running the controllers and HMD in Godot:\n[![Watch video](https://img.youtube.com/vi/yC75XknKTo0/0.jpg)](https://www.youtube.com/watch?v=yC75XknKTo0)\n\n\nTable of Contents\n=================\n\n   * [Quick start](#quick-start)\n      * [Debian](#debian)\n      * [Windows](#windows)\n   * [Current Status](#current-status)\n   * [Roadmap](#roadmap)\n   * [Getting Started](#getting-started)\n      * [Calibration](#calibration)\n      * [Visualization](#visualization)\n      * [libsurvive Tools](#libsurvive-tools)\n      * [Using libsurvive in your own application](#using-libsurvive-in-your-own-application)\n         * [Lower level API](#lower-level-api)\n         * [High level API](#high-level-api)\n         * [Python Bindings](#python-bindings)\n         * [C# Bindings](#c-bindings)\n      * [Data recording](#data-recording)\n         * [Normal recording](#normal-recording)\n         * [Raw USB recording](#raw-usb-recording)\n      * [Common command line flags](#common-command-line-flags)\n   * [Drivers](#drivers)\n      * [Custom Drivers](#custom-drivers)\n   * [FAQ](#faq)\n      * [Addendum and notes](#addendum-and-notes)\n\n# Quick start\n\n## Debian\n```\ngit clone https://github.com/cntools/libsurvive.git\ncd libsurvive\nsudo cp ./useful_files/81-vive.rules /etc/udev/rules.d/\nsudo udevadm control --reload-rules \u0026\u0026 sudo udevadm trigger\nsudo apt update \u0026\u0026 sudo apt install build-essential zlib1g-dev libx11-dev libusb-1.0-0-dev freeglut3-dev liblapacke-dev libopenblas-dev libatlas-base-dev cmake\nmake\n```\n\nPlug in a headset / tracker / controller / etc and run:\n```\n./bin/survive-cli\n```\n\nThis should calibrate and display your setup. \n\nFor visualization, you can either download a binary of [websocketd](https://github.com/joewalnes/websocketd/releases/) or enable the experimental apt source and use `sudo apt install websocketd`. After which you can run:\n\n```\n./bin/survive-websocketd \u0026 xdg-open ./tools/viz/index.html\n```\n\n[![Watch video](https://img.youtube.com/vi/l4doRSXM0tU/0.jpg)](https://www.youtube.com/watch?v=l4doRSXM0tU)\n\n## Windows\n\nIf you have `cmake` installed on your path you can simply run the `make.ps1` script by right clicking it and seleting `Run with PowerShell`.\n\nA more manual approach is to open CMakeLists file in something like [CMake GUI](https://cmake.org/runningcmake/) to build\nfrom source using one of the visual studio generators. This will also let you set various build options. The build uses NuGet \nto get the [necessary development dependencies](https://www.nuget.org/packages/lapacke/). After you generate the project, open the\nsolution in visual studio and run build all. \n\n[Websocketd](http://websocketd.com/) should work the same with with the visualization tool; assuming you put it somewhere in the system path. In the build binary folder (`./build-win/Release` if you built from `make.ps1`) there should be a `survive-websocketd.ps1` which can be ran as a PowerShell file. \n\nProbably the easiest way to get started with libsurvive on windows is to check out the [release binaries](https://github.com/cntools/libsurvive/releases).\n\n# Current Status\n\nThe tracking and device enumeration work fairly well at this point; but there isn't an extremely large testing base and \nthe tools aren't as polished as the comparable ones bundled in SteamVR. Work is ongoing to quantify how accurate the \ntracking is and to improve the user experience. \n\n# Roadmap\n\nA very loose collection of things that are on the short term agenda:\n\n- Dynamic correction of calibration. This would detect and silently recalibrate lighthouses that might have moved. The \nend goal is to have a system where the user is never aware of any calibration requirements. \n- An android binary / port\n- Hard numbers on the accuracy and precision of libsurvive as a tracking system. If anyone wants to contribute time testing\non a CNC please get in our [discord](https://discordapp.com/invite/7QbCAGS)\n- Better handling of data starvation -- if the USB or radio connection stutters too long, the tracking will occasionally\nglitch out for a brief period. \n- Use something like usbmon for windows\n\n# Getting Started\n\nIf you followed the quick start guide, you'll notice that the first thing you must do (for linux) is install udev rules:\n\n```\nsudo cp ./useful_files/81-vive.rules to /etc/udev/rules.d/\nsudo udevadm control --reload-rules \u0026\u0026 udevadm trigger\n```\n\nThis allows one to use those devices without having root. No such steps are necessary in windows. \n\nAfter that, when you run `survive-cli` or `survive-websocketd` it should recognize any plugged in vive devices and start\ncalibrating and tracking those devices. \n\n**Important: Close SteamVR for best results. Depending on the system, libsurvive\nwill either cause SteamVR to lose connection to the device or will compete for bandwidth with it**\n\n## Calibration\n\nCalibration is the process which establishes where the lighthouses are set up in relation to the tracked objects. The\nfirst time you run libsurvive, it can take up to ten seconds to communicate with the lighthouses and figure out where \nthey are. \n\nCalibration will continuously integrate objects data so long as they are momentarily stationary. Due to this, you might notice lighthouses shift slighty while it gets a good lock. Subsequent runs should shift much less. \n\nOnce you do this one time, it is saved in `config.json` in `XDG_CONFIG_HOME/libsurvive`. If you delete this file, it will simply\nrecalibrate; but it is faster to use the `--force-calibrate` flag. Some drivers change the name of this file -- notably recordings will instead use `\u003cevent_file\u003e.json`. \n\nIf you have a large space, and you can not centrally locate a single device to 'see' all lighthouses, you can calibrate\na few lighthouses and move the tracked object into the field of view of the uncalibrated lighthouse while keeping it in\nview of at least one of the calibrated ones. Set it down so it doesn't move; and the remaining lighthouse(s) should now\ncalibrate. \n\n**Important: Resetting calibration automatically when a lighthouse is moved is being planned on but is not currently \navailable. If one of the calibrated lighthouses are moved, you either have to redo calibration by deleting the config.json\nfile or passing `--force-calibrate` into any of the libsurvive tools.**\n\n\n## Visualization\n\nThe main visualization tool is a THREE.js page which is fed data through (websocketd)[http://websocketd.com/]. To use\nthis tool, run `survive-websocketd [options]` and open a web browser to `./tools/viz/index.html` from the root of the\ncloned repo. \n\n![Visuzliation Screenshot](https://raw.githubusercontent.com/cnlohr/libsurvive/master/useful_files/viz_screenshot.png)\n\n## libsurvive Tools\n\n- `survive-cli` - This is the main command line interface to the library; really just a very thin wrapper around the library.\n- `survive-websocketd` - A script which runs `survive-cli` through `websocketd` with all the appropriate flags set.\n- `sensors-readout` - Display raw sensor information in a ncurses display\n\n## Using libsurvive in your own application\n\n### Lower level API\n\nThis section is mainly concerned about *consuming* data from the library; for information on how to *provide* data, see\nthe [drivers section](https://github.com/cntools/libsurvive/#drivers).\n\nThe main way to extend and use libsurvive is to use the various callbacks exposed by the library to get information from\nthe system. Use of libsurvive in this way is recommended if you need access to all data going in -- IMU data, individual\nlight data, and/or final pose data. However care needs to be taken to not bog down the system. In general these callbacks\nare invoked from the thread collecting the data; so if you have unnecessary delays in processing data will be dropped \nwhich will cause poor tracking performance. \n\nThe full list of hooks is [here](https://github.com/cntools/libsurvive/blob/master/include/libsurvive/survive_hooks.h). \nThe function types are [here](https://github.com/cntools/libsurvive/blob/master/include/libsurvive/survive_types.h#L168). \n\nYou install your custom hook via:\n\n`\u003chook-name\u003e_process_func survive_install_\u003chook-name\u003e_fn(SurviveContext *ctx, \u003chook-name\u003e_process_func fbp);`\n\nThis returns the previously set function for that particular hook; which you can choose to call in your own callback. This\nis somewhat more cumbersome than just having the callbacks return `true` or `false`; but allows the flexibility to call\nthe previously defined function before or after your code, or not at all. \n\nThese hooks are used internally within libsurvive; if you provide a hook and do not either call the previously defined or\ndefault function, some data will not make it to the posers. \n\n`SurviveContext` and `SurviveObject` both have a `user_ptr` variable which is zero initialized and not used internally, \nand is meant to be set by library consumers for their own purposes. This allows you to install the hook, and not resort \nto using globals. \n\nThese interfaces are relatively stable, but aren't guaranteed to not change. \n\nHave a look at the other libsurvive tools a the top level of the repository for example usage of the lower level API:\n- survive-cli.c\n- sensors-readout.c\n- simple_pose_test.c\n\n### High level API\n\nThe high level `Simple` API is recommended for applications which just need position and velocity data as fast as they\ncan process that data. It has a few main advantages:\n\n- User code runs in it's own thread; so you can't starve libsurvive of data\n- Much more insulated against lower level API changes; so you can upgrade libsurvive versions more easily\n\nThe main loop logic tends to look like this in `C`:\n\n```C\nwhile (survive_simple_wait_for_update(actx) \u0026\u0026 keepRunning) {\n    for (const SurviveSimpleObject *it = survive_simple_get_next_updated(actx); it != 0;\n         it = survive_simple_get_next_updated(actx)) {\n        SurvivePose pose;\n        uint32_t timecode = survive_simple_object_get_latest_pose(it, \u0026pose);\n        printf(\"%s %s (%u): %f %f %f %f %f %f %f\\n\", survive_simple_object_name(it),\n               survive_simple_serial_number(it), timecode, pose.Pos[0], pose.Pos[1], pose.Pos[2], pose.Rot[0],\n               pose.Rot[1], pose.Rot[2], pose.Rot[3]);\n    }\n}\n```\n\nExample code for the application interface can be found in [api_example.c](https://github.com/cntools/libsurvive/blob/master/api_example.c).\n\nThe full header for the simpler API is available [here](https://github.com/cntools/libsurvive/blob/master/include/libsurvive/survive_api.h). \n\n### Python Bindings\n\nPython bindings are available for python3 on windows and linux through https://pypi.org/project/pysurvive/. You can \ninstall them with\n\n```\npip install pysurvive\n```\n\nTo build the python bindings, run `python setup.py install` in the repo root. This should install the `pysurvive` package.\n\nAn example which streams poses out as they come in:\n\n```\nimport pysurvive\nimport sys\n\nactx = pysurvive.SimpleContext(sys.argv)\n\nfor obj in actx.Objects():\n    print(obj.Name())\n\nwhile actx.Running():\n    updated = actx.NextUpdated()\n    if updated:\n        print(updated.Name(), updated.Pose())\n```\n\nThere are more examples in `./bindings/python`.\n\n### C# Bindings\n\nThe C# bindings wrap both the low level access API and the higher level simpler to use API. It is recommended to use the\nhigher level API since the low level one relies heavily on callbacks and marshalling makes working with it prone to \nerrors that are not always easy to solve. \n\nStandard binaries are available at https://www.nuget.org/packages/libsurvive.net/. You can install them for a given\nC# project through the visual studio nuget manager tool.\n\nBuild the solution [here](https://github.com/cntools/libsurvive/tree/master/bindings/cs) with either visual studio or by\nrunning something like\n\n```\ndotnet build -c Release\n```\n\nfrom a terminal to generate the binary `libsurvive.net.dll`. This works in linux as well as windows; but the \nfilename still ends in `dll`. When you run against this binary, `libsurvive.so` needs to either be in the same directory\n(with desired plugins), or on the system path. \n\nThe high level api is exposed through the `libsurvive.SurviveAPI` object. It's use is pretty easy; it can just poll for\nupdates to object positions or button events as in the [Demo project](https://github.com/cntools/libsurvive/tree/master/bindings/cs/Demo/Program.cs):\n\n```cs\nusing libsurvive;\nusing System;\n\nnamespace Demo\n{\n    \n    class Program\n    {\n\t\tstatic void Main() {\n\t\t\tstring[] args = System.Environment.GetCommandLineArgs();\n\t\t\tvar api = new SurviveAPI(args);\n\n\t\t\twhile (api.WaitForUpdate()) {\n\t\t\t\tSurviveAPIOObject obj;\n\t\t\t\twhile ((obj = api.GetNextUpdated()) != null) {\n\t\t\t\t\tConsole.WriteLine(obj.Name + \": \" + obj.LatestPose);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tapi.Close();\n\t\t}\n\t}\n}\n\n```\n\nIt's also meant to be easy to integrate into code bases based on frame updates; such as in the [Unity example](https://github.com/cntools/libsurvive/blob/master/bindings/cs/UnityViewer/Assets/SurviveObject.cs):\n\n```cs\n// Update is called once per frame\nvoid Update() {\n    var updated = survive?.GetNextUpdated();\n\n    if (updated == null)\n        return;\n\n    var updatedObject = getObject(updated.Name);\n\n    Vector3 newPosition = Vector3.zero;\n    Quaternion newRotation = Quaternion.identity;\n    SurvivePose pose = updated.LatestPose;\n    newPosition.x = (float) pose.Pos[0];\n    newPosition.y = (float) pose.Pos[1];\n    newPosition.z = (float) pose.Pos[2];\n    newRotation.w = (float) pose.Rot[0];\n    newRotation.x = (float) pose.Rot[1];\n    newRotation.y = (float) pose.Rot[2];\n    newRotation.z = (float) pose.Rot[3];\n    updatedObject.transform.localPosition = newPosition;\n    updatedObject.transform.localRotation = newRotation;\n}\n```\n\n[![Watch video](https://img.youtube.com/vi/FiRLrWWOhLg/0.jpg)](https://www.youtube.com/watch?v=FiRLrWWOhLg\u0026feature=youtu.be)\n\n## Data recording\n\nThere are a lot of things that can go wrong to give bad tracking or calibration results, and given the wide variety of \ndevices, configurations and use cases, it's extremely helpful when trying to resolve bugs if there is a data recording \nof the bug. This also can get added to our CI system to have automatic testing against that use case. \n\nThere are two mechanisms available for recording data: `--record` and `--usbmon-record`. \n\n`--record` is available in every installation, and less setup to use so for pure tracking issues this is usually the \napproach to take. However, if the issue is in parsing and understanding the low level data packes from the tracked device,\nthe `--usbmon-record` option might be more helpful. \n\n### Normal recording\n\nWhen running any of the libsurvive tools, pass in `--record \u003cfilename\u003e.rec.gz`. This will create a data log of everything\nthe system sees as it runs in that file. This records a large amount of data, so if it is allowed to run for a long time\nthat file might get very large. \n\nTo playback that file, run:\n\n`./survive-cli --playback \u003cfilename\u003e.rec.gz`\n\n### Raw USB recording\n\nOccasionally, when dealing with new hardware or certain types of bugs that cause an issue in the USB layer, it is necessary to have a raw capture of the USB data seen / sent. The USBMON driver lets you do this.\n\nCurrently this driver is only available on linux and you must have libpcap installed -- `sudo apt install libpcap-dev`. You also need the `usbmon` kernel module installed; but many linux flavors come with that built in. \n\nTo start usbmon and prepare it for use for all users, run:\n\n```\nsudo modprobe usbmon\nsudo setfacl -m u:$USER:r /dev/usbmon* # In sensitive environments, you can run survive-cli with sudo instead.\n```\n\nTo capture usb data, run:\n\n```\n./survive-cli --usbmon-record \u003cfilename\u003e.pcap.gz --htcvive \u003cadditional options\u003e` \n```\n\nYou can run that playback with:\n```\n./survive-cli --usbmon-playback \u003cfilename\u003e.pcap.gz [--playback-factor x] \u003cadditional options\u003e` \n```\n\nIf you are sending this file for analysis, note that you need the accompanying `*.usbdevs` file with it to be useful. If you follow the `*.pcap.gz` convention, run something like\n\n```\nzip logs.zip *.pcap* config.json\n```\n\nand post the `logs.zip` to an issue or to discord. \n\nThis driver specifically only captures devices on a white list of VR equipment; but if you don't want to publish raw USB\ndata to the internet, ask in discord for who to send it to in a private message. \n\n## Common command line flags\n\nLibsurvive is very configurable, and contains a lot of command line options depending on the drivers and options given\nat build time. \n\nIt's recommended that you install the bash completion for libsurvive if you are working with the command line options:\n\n`sudo cp survive_autocomplete.sh /etc/bash_completion.d/`.\n\nThe most useful command line option for debugging is `--v` -- this sets the reporting level. This verbosity level roughly follows this guideline:\n\n- `--v 10` - Statistics and information displayed either at the start or end of the application.\n- `--v 100` - Information displayed at many common points while tracking\n- `--v 150` - Information displayed for almost every pose output\n- `--v 250` - Information displayed for almost all light data event in the system\n- `--v 1000` - Everything. \n\nRunning at higher verbosity (\u003e100) will make the visualization tool sluggish. \n\n`--force-calibrate`: This reruns calibration but reuses OOTX; which makes it much faster to run. \n\n`--playback-factor`: When playing back a recording, this will speed up the playback (0 is run everything as fast as possible) or slow it down (2 takes twice as much time)\n\n`--lighthouse-gen`: Force the system to use a particular generation of lighthouse. Right now, sometimes the system misidentified lighthouse 1 (The purely square base stations) for lighthouse 2 (The rounded face base stations) or vice versa. As we find these cases, we are fixing them but this lets a misbehaving system be useful in the meantime. \n\n# Drivers\n\nThese are the different drivers for providing information into libsurvive. All of them are encapsulated in the `src` directory\nwith a `driver_` prefix. Each driver can be specified with a `--\u003cdriver-name\u003e` flag. You can disable a default driver (eg, `htcvive`) with\n`--no-\u003cdriver-name\u003e`.\n\n- `htcvive` - This is the main driver which provides data via USB connection to vive hardware.\n- `simulator` - This simulates a device floating around while providing realistic light / IMU data into libsurvive. Useful\nfor testing different features.\n- `playback` - The playback driver is what enables record/playback functionality. It replays a file into the various data points.\n- `usbmon` - USBmon can be ran concurrent with steamvr to allow both systems to use the tracked object data. \n- `openvr` - This driver exposes external poses and velocities and can be ran with `usbmon` to compare the two systems.\n\n## Custom Drivers\n\nIntegrating a driver is meant to be relatively straight forward and the above mentioned ones are good references for how \nto do it. \n\nThe general approach is to compile to a shared object / DLL with the name of `driver_\u003cname\u003e.so` in the plugins folder. \nThe internals of libsurvive enumerate these plugins and run libsurvive registered function from the form:\n\n```C\nint DriverRegExample(SurviveContext *ctx) {\n    if(...error...) {\n       return SURVIVE_DRIVER_ERROR;\n    }\n    return SURVIVE_DRIVER_NORMAL;\n}\nREGISTER_LINKTIME(DriverRegExample)\n```\n\nIt isn't necessary for a driver to register anything else; but to be integrated into libsurvive the driver must either\nexpose a poll / close function or a thread / close function.\n\nThe simpliest approach is a poll driver:\n\n```void survive_add_driver(SurviveContext *ctx, void *user_ptr, DeviceDriverCb poll, DeviceDriverCb close)```\n\nThe poll function is called continuously while the system is running; and the close function is called at\nshutdown. \n\nMore versatile is a threaded driver:\n\n```bool *survive_add_threaded_driver(SurviveContext *ctx, void *driver_data, const char *name, void *(routine)(void *), DeviceDriverCb close);```\n\nThis starts a thread with the given function and name. \n\nIn the threaded driver case, when accessing any members of `SurviveContext` or `SurviveObject`, you\n must lock and release around that access with the following functions:\n\n```\nvoid survive_get_ctx_lock(SurviveContext *ctx);\nvoid survive_release_ctx_lock(SurviveContext *ctx);\n```\n\nImproper locking or unlocking can result in race conditions or dead locks. \n\nWithin either the threaded function or the polling function, it is then up to the driver to call the appropriate\nhook functions with whatever data they are exposing. Generally the driver will also call `survive_create_device` \nand only concern itself with that device. More than one driver can be running at a time; but they all assume the same\nlighthouse configuration. \n\nA good example of this in action is `driver_simulator.c` which calls various light data and IMU callbacks\nwith a custom `SurviveObject` type. `driver_openvr.cc` demonstrates how to incorporate external position data into the \nlibrary. \n\n\n# FAQ\n\nOther projects using libsurvive\n\n * The [Monado OpenXR runtime](https://monado.freedesktop.org/) uses libsurvive as one of its HMD and controller drivers.\n   * OpenXR applications that run on Monado include the [OpenXR plugin for Godot 3.x](https://github.com/GodotVR/godot_openxr)\n * There is a very unofficial (and not upstreamable) [OpenHMD/libsurvive fork](https://github.com/ChristophHaag/OpenHMD/commits/libsurvive2) that adds a libsurvive driver.\n   * This OpenHMD/libsurvive fork can be plugged into [SteamVR-OpenHMD](https://github.com/ChristophHaag/SteamVR-OpenHMD) or used natively with the [OpenHMD plugin for Godot 3.x](https://github.com/BastiaanOlij/godot_openhmd).\n\n## Addendum and notes\n\nThanks to Mr. Faul for our logo!\nSpecial thanks to @nairol for an extreme amount of detail in reverse engineering the existing HTC Vive system on his https://github.com/nairol/LighthouseRedox project.\n","funding_links":[],"categories":["Augmented Reality (AR) \u0026 Virtual Reality (VR)","3D Graphics Tools, Libraries and Frameworks","Augmented Reality (AR) \u0026 Virtual Reality (VR) Tools and Frameworks"],"sub_categories":["Winetricks","VS Code Extensions for Developer Productivity","Objective-C Tools, Libraries, and Frameworks"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcollabora%2Flibsurvive","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcollabora%2Flibsurvive","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcollabora%2Flibsurvive/lists"}