d/ns: Add North Star stub driver

This commit is contained in:
Nova 2020-01-24 16:35:12 -05:00 committed by Jakob Bornecrantz
parent 260a0279aa
commit 981fe55a27
15 changed files with 383 additions and 2 deletions

View file

@ -80,6 +80,7 @@ cmake_dependent_option(BUILD_WITH_SDL2 "Enable SDL2 based test application" ON "
option(BUILD_WITH_HDK "Enable HDK driver" ON) option(BUILD_WITH_HDK "Enable HDK driver" ON)
option(BUILD_WITH_PSMV "Enable Playstation Move driver" ON) option(BUILD_WITH_PSMV "Enable Playstation Move driver" ON)
option(BUILD_WITH_HYDRA "Enable Hydra driver" ON) option(BUILD_WITH_HYDRA "Enable Hydra driver" ON)
option(BUILD_WITH_NS "Enable North Star driver" ON)
### ###
# Flags # Flags
@ -139,6 +140,10 @@ if(BUILD_WITH_OPENHMD)
set(BUILD_DRIVER_OHMD TRUE) set(BUILD_DRIVER_OHMD TRUE)
endif() endif()
if(BUILD_WITH_NS)
set(BUILD_DRIVER_NS TRUE)
endif()
if(BUILD_WITH_PSVR) if(BUILD_WITH_PSVR)
if (NOT ${HIDAPI_FOUND}) if (NOT ${HIDAPI_FOUND})
message(FATAL_ERROR "PSVR driver requires hidapi") message(FATAL_ERROR "PSVR driver requires hidapi")

View file

@ -131,6 +131,9 @@ drivers = get_option('drivers')
if 'ohmd' in drivers if 'ohmd' in drivers
openhmd_required = true openhmd_required = true
endif endif
if 'ns' in drivers
ns_required = true
endif
if 'psvr' in drivers if 'psvr' in drivers
hidapi_required = true hidapi_required = true
endif endif
@ -146,6 +149,12 @@ openhmd = dependency('openhmd', required: openhmd_required)
hidapi = dependency('hidapi-libusb', required: hidapi_required) hidapi = dependency('hidapi-libusb', required: hidapi_required)
v4l2 = dependency('libv4l2', required: v4l2_required) v4l2 = dependency('libv4l2', required: v4l2_required)
if 'auto' in drivers or 'ns' in drivers
if 'ns' not in drivers
drivers += ['ns']
endif
endif
if openhmd.found() and ('auto' in drivers or 'ohmd' in drivers) if openhmd.found() and ('auto' in drivers or 'ohmd' in drivers)
if 'ohmd' not in drivers if 'ohmd' not in drivers
drivers += ['ohmd'] drivers += ['ohmd']

View file

@ -3,7 +3,7 @@
option('drivers', option('drivers',
type: 'array', type: 'array',
choices: ['auto', 'dummy', 'hdk', 'hydra', 'ohmd', 'psmv', 'psvr', 'v4l2', 'vive'], choices: ['auto', 'dummy', 'hdk', 'hydra', 'ns', 'ohmd', 'psmv', 'psvr', 'v4l2', 'vive'],
value: ['auto'], value: ['auto'],
description: 'Set of drivers to build') description: 'Set of drivers to build')

View file

@ -18,6 +18,10 @@ if(BUILD_DRIVER_HYDRA)
set(XRT_BUILD_DRIVER_HYDRA TRUE) set(XRT_BUILD_DRIVER_HYDRA TRUE)
endif() endif()
if(BUILD_DRIVER_NS)
set(XRT_BUILD_DRIVER_NS TRUE)
endif()
if(BUILD_DRIVER_OHMD) if(BUILD_DRIVER_OHMD)
set(XRT_BUILD_DRIVER_OHMD TRUE) set(XRT_BUILD_DRIVER_OHMD TRUE)
endif() endif()

View file

@ -6,6 +6,7 @@ conf_data.set('XRT_BUILD_TRACKING', build_tracking)
conf_data.set('XRT_BUILD_DRIVER_DUMMY', 'dummy' in drivers) conf_data.set('XRT_BUILD_DRIVER_DUMMY', 'dummy' in drivers)
conf_data.set('XRT_BUILD_DRIVER_HDK', 'hdk' in drivers) conf_data.set('XRT_BUILD_DRIVER_HDK', 'hdk' in drivers)
conf_data.set('XRT_BUILD_DRIVER_HYDRA', 'hydra' in drivers) conf_data.set('XRT_BUILD_DRIVER_HYDRA', 'hydra' in drivers)
conf_data.set('XRT_BUILD_DRIVER_NS', 'ns' in drivers)
conf_data.set('XRT_BUILD_DRIVER_OHMD', 'ohmd' in drivers) conf_data.set('XRT_BUILD_DRIVER_OHMD', 'ohmd' in drivers)
conf_data.set('XRT_BUILD_DRIVER_PSMV', 'psmv' in drivers) conf_data.set('XRT_BUILD_DRIVER_PSMV', 'psmv' in drivers)
conf_data.set('XRT_BUILD_DRIVER_PSVR', 'psvr' in drivers) conf_data.set('XRT_BUILD_DRIVER_PSVR', 'psvr' in drivers)

View file

@ -15,6 +15,8 @@
#cmakedefine XRT_BUILD_DRIVER_HYDRA #cmakedefine XRT_BUILD_DRIVER_HYDRA
#cmakedefine XRT_BUILD_DRIVER_NS
#cmakedefine XRT_BUILD_DRIVER_OHMD #cmakedefine XRT_BUILD_DRIVER_OHMD
#cmakedefine XRT_BUILD_DRIVER_PSMV #cmakedefine XRT_BUILD_DRIVER_PSMV

View file

@ -15,6 +15,8 @@
#mesondefine XRT_BUILD_DRIVER_HYDRA #mesondefine XRT_BUILD_DRIVER_HYDRA
#mesondefine XRT_BUILD_DRIVER_NS
#mesondefine XRT_BUILD_DRIVER_OHMD #mesondefine XRT_BUILD_DRIVER_OHMD
#mesondefine XRT_BUILD_DRIVER_PSMV #mesondefine XRT_BUILD_DRIVER_PSMV

View file

@ -48,6 +48,18 @@ if(BUILD_DRIVER_HYDRA)
list(APPEND ENABLED_DRIVERS hydra) list(APPEND ENABLED_DRIVERS hydra)
endif() endif()
if(BUILD_DRIVER_NS)
set(NS_SOURCE_FILES
north_star/ns_hmd.c
north_star/ns_interface.h
north_star/ns_prober.c
)
# Use OBJECT to not create a archive, since it just gets in the way.
add_library(drv_ns OBJECT ${NS_SOURCE_FILES})
list(APPEND ENABLED_HEADSET_DRIVERS ns)
endif()
if(BUILD_DRIVER_OHMD) if(BUILD_DRIVER_OHMD)
set(OHMD_SOURCE_FILES set(OHMD_SOURCE_FILES
ohmd/oh_device.c ohmd/oh_device.c

View file

@ -39,6 +39,18 @@ lib_drv_hydra = static_library(
build_by_default: 'hydra' in drivers, build_by_default: 'hydra' in drivers,
) )
lib_drv_ns = static_library(
'drv_ns',
files(
'north_star/ns_hmd.c',
'north_star/ns_interface.h',
'north_star/ns_prober.c',
),
include_directories: xrt_include,
dependencies: [aux],
build_by_default: 'ns' in drivers,
)
lib_drv_ohmd = static_library( lib_drv_ohmd = static_library(
'drv_ohmd', 'drv_ohmd',
files( files(

View file

@ -0,0 +1,198 @@
// Copyright 2020, Collabora, Ltd.
// Copyright 2020, Nova King.
// SPDX-License-Identifier: BSL-1.0
/*!
* @file
* @brief North Star HMD code.
* @author Nova King <technobaboo@gmail.com>
* @author Jakob Bornecrantz <jakob@collabora.com>
* @ingroup drv_ns
*/
#include <math.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "math/m_api.h"
#include "xrt/xrt_device.h"
#include "util/u_var.h"
#include "util/u_misc.h"
#include "util/u_debug.h"
#include "util/u_device.h"
#include "util/u_time.h"
#include "util/u_distortion_mesh.h"
/*
*
* Structs and defines.
*
*/
struct ns_hmd
{
struct xrt_device base;
struct xrt_pose pose;
bool print_spew;
bool print_debug;
};
/*
*
* Functions
*
*/
static inline struct ns_hmd *
ns_hmd(struct xrt_device *xdev)
{
return (struct ns_hmd *)xdev;
}
#define NS_SPEW(c, ...) \
do { \
if (c->print_spew) { \
fprintf(stderr, "%s - ", __func__); \
fprintf(stderr, __VA_ARGS__); \
fprintf(stderr, "\n"); \
} \
} while (false)
#define NS_DEBUG(c, ...) \
do { \
if (c->print_debug) { \
fprintf(stderr, "%s - ", __func__); \
fprintf(stderr, __VA_ARGS__); \
fprintf(stderr, "\n"); \
} \
} while (false)
#define NS_ERROR(c, ...) \
do { \
fprintf(stderr, "%s - ", __func__); \
fprintf(stderr, __VA_ARGS__); \
fprintf(stderr, "\n"); \
} while (false)
static void
ns_hmd_destroy(struct xrt_device *xdev)
{
struct ns_hmd *ns = ns_hmd(xdev);
// Remove the variable tracking.
u_var_remove_root(ns);
u_device_free(&ns->base);
}
static void
ns_hmd_update_inputs(struct xrt_device *xdev, struct time_state *timekeeping)
{
// Empty
}
static void
ns_hmd_get_tracked_pose(struct xrt_device *xdev,
enum xrt_input_name name,
struct time_state *timekeeping,
int64_t *out_timestamp,
struct xrt_space_relation *out_relation)
{
struct ns_hmd *ns = ns_hmd(xdev);
if (name != XRT_INPUT_GENERIC_HEAD_POSE) {
NS_ERROR(ns, "unknown input name");
return;
}
int64_t now = time_state_get_now(timekeeping);
*out_timestamp = now;
out_relation->pose = ns->pose;
out_relation->relation_flags = (enum xrt_space_relation_flags)(
XRT_SPACE_RELATION_ORIENTATION_VALID_BIT |
XRT_SPACE_RELATION_POSITION_VALID_BIT);
}
static void
ns_hmd_get_view_pose(struct xrt_device *xdev,
struct xrt_vec3 *eye_relation,
uint32_t view_index,
struct xrt_pose *out_pose)
{
struct xrt_pose pose = {{0.0f, 0.0f, 0.0f, 1.0f}, {0.0f, 0.0f, 0.0f}};
bool adjust = view_index == 0;
pose.position.x = eye_relation->x / 2.0f;
pose.position.y = eye_relation->y / 2.0f;
pose.position.z = eye_relation->z / 2.0f;
// Adjust for left/right while also making sure there aren't any -0.f.
if (pose.position.x > 0.0f && adjust) {
pose.position.x = -pose.position.x;
}
if (pose.position.y > 0.0f && adjust) {
pose.position.y = -pose.position.y;
}
if (pose.position.z > 0.0f && adjust) {
pose.position.z = -pose.position.z;
}
*out_pose = pose;
}
struct xrt_device *
ns_hmd_create(bool print_spew, bool print_debug)
{
enum u_device_alloc_flags flags = (enum u_device_alloc_flags)(
U_DEVICE_ALLOC_HMD | U_DEVICE_ALLOC_TRACKING_NONE);
struct ns_hmd *ns = U_DEVICE_ALLOCATE(struct ns_hmd, flags, 1, 0);
ns->base.update_inputs = ns_hmd_update_inputs;
ns->base.get_tracked_pose = ns_hmd_get_tracked_pose;
ns->base.get_view_pose = ns_hmd_get_view_pose;
ns->base.destroy = ns_hmd_destroy;
ns->base.name = XRT_DEVICE_GENERIC_HMD;
ns->pose.orientation.w = 1.0f; // All other values set to zero.
ns->print_spew = print_spew;
ns->print_debug = print_debug;
// Print name.
snprintf(ns->base.str, XRT_DEVICE_NAME_LEN, "North Star");
// Setup input.
ns->base.inputs[0].name = XRT_INPUT_GENERIC_HEAD_POSE;
// Setup info.
struct u_device_simple_info info;
info.display.w_pixels = 1920;
info.display.h_pixels = 1080;
info.display.w_meters = 0.13f;
info.display.h_meters = 0.07f;
info.lens_horizontal_separation_meters = 0.13f / 2.0f;
info.lens_vertical_position_meters = 0.07f / 2.0f;
info.views[0].fov = 85.0f * (M_PI / 180.0f);
info.views[1].fov = 85.0f * (M_PI / 180.0f);
if (!u_device_setup_split_side_by_side(&ns->base, &info)) {
NS_ERROR(ns, "Failed to setup basic device info");
ns_hmd_destroy(&ns->base);
return NULL;
}
// Setup variable tracker.
u_var_add_root(ns, "North Star", true);
u_var_add_pose(ns, &ns->pose, "pose");
if (ns->base.hmd->distortion.preferred == XRT_DISTORTION_MODEL_NONE) {
// Setup the distortion mesh.
u_distortion_mesh_none(ns->base.hmd);
}
return &ns->base;
}

View file

@ -0,0 +1,49 @@
// Copyright 2019, Collabora, Ltd.
// SPDX-License-Identifier: BSL-1.0
/*!
* @file
* @brief Interface to North Star driver code.
* @author Nova King <technobaboo@gmail.com>
* @ingroup drv_ns
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
/*!
* @defgroup drv_ns North Star Driver
* @ingroup drv
*
* @brief Driver for the North Star HMD.
*/
/*!
* Create a probe for NS devices.
*
* @ingroup drv_ns
*/
struct xrt_auto_prober *
ns_create_auto_prober(void);
/*!
* Create a North Star hmd.
*
* @ingroup drv_ns
*/
struct xrt_device *
ns_hmd_create(bool print_spew, bool print_debug);
/*!
* @dir drivers/ns
*
* @brief @ref drv_ns files.
*/
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,70 @@
// Copyright 2019, Collabora, Ltd.
// SPDX-License-Identifier: BSL-1.0
/*!
* @file
* @brief North Star prober code.
* @author Nova King <technobaboo@gmail.com>
* @author Jakob Bornecrantz <jakob@collabora.com>
* @ingroup drv_ns
*/
#include <stdio.h>
#include <stdlib.h>
#include "xrt/xrt_prober.h"
#include "util/u_misc.h"
#include "util/u_debug.h"
#include "ns_interface.h"
DEBUG_GET_ONCE_BOOL_OPTION(ns_spew, "NS_PRINT_SPEW", false)
DEBUG_GET_ONCE_BOOL_OPTION(ns_debug, "NS_PRINT_DEBUG", false)
struct ns_prober
{
struct xrt_auto_prober base;
bool print_spew;
bool print_debug;
};
static inline struct ns_prober *
ns_prober(struct xrt_auto_prober *p)
{
return (struct ns_prober *)p;
}
static void
ns_prober_destroy(struct xrt_auto_prober *p)
{
struct ns_prober *nsp = ns_prober(p);
free(nsp);
}
static struct xrt_device *
ns_prober_autoprobe(struct xrt_auto_prober *xap,
bool no_hmds,
struct xrt_prober *xp)
{
struct ns_prober *nsp = ns_prober(xap);
if (no_hmds) {
return NULL;
}
return ns_hmd_create(nsp->print_spew, nsp->print_debug);
}
struct xrt_auto_prober *
ns_create_auto_prober()
{
struct ns_prober *nsp = U_TYPED_CALLOC(struct ns_prober);
nsp->base.destroy = ns_prober_destroy;
nsp->base.lelo_dallas_autoprobe = ns_prober_autoprobe;
nsp->print_spew = debug_get_bool_option_ns_spew();
nsp->print_debug = debug_get_bool_option_ns_debug();
return &nsp->base;
}

View file

@ -33,6 +33,10 @@ if(BUILD_DRIVER_HYDRA)
list(APPEND DRIVER_OBJECTS $<TARGET_OBJECTS:drv_hydra>) list(APPEND DRIVER_OBJECTS $<TARGET_OBJECTS:drv_hydra>)
endif() endif()
if(BUILD_DRIVER_NS)
list(APPEND DRIVER_OBJECTS $<TARGET_OBJECTS:drv_ns>)
endif()
if(BUILD_DRIVER_OHMD) if(BUILD_DRIVER_OHMD)
list(APPEND DRIVER_OBJECTS $<TARGET_OBJECTS:drv_ohmd>) list(APPEND DRIVER_OBJECTS $<TARGET_OBJECTS:drv_ohmd>)
list(APPEND DRIVER_LIBRARIES OpenHMD::OpenHMD) list(APPEND DRIVER_LIBRARIES OpenHMD::OpenHMD)

View file

@ -22,6 +22,10 @@
#include "ohmd/oh_interface.h" #include "ohmd/oh_interface.h"
#endif #endif
#ifdef XRT_BUILD_DRIVER_NS
#include "north_star/ns_interface.h"
#endif
#ifdef XRT_BUILD_DRIVER_PSMV #ifdef XRT_BUILD_DRIVER_PSMV
#include "psmv/psmv_interface.h" #include "psmv/psmv_interface.h"
#endif #endif
@ -89,10 +93,15 @@ xrt_auto_prober_creator target_auto_list[] = {
#endif #endif
#ifdef XRT_BUILD_DRIVER_OHMD #ifdef XRT_BUILD_DRIVER_OHMD
// OpenHMD second last as we want to override it with native drivers. // OpenHMD almost as the end as we want to override it with native drivers.
oh_create_auto_prober, oh_create_auto_prober,
#endif #endif
#ifdef XRT_BUILD_DRIVER_NS
// North star driver here for now.
ns_create_auto_prober,
#endif
#ifdef XRT_BUILD_DRIVER_DUMMY #ifdef XRT_BUILD_DRIVER_DUMMY
// Dummy headset driver last. // Dummy headset driver last.
dummy_create_auto_prober, dummy_create_auto_prober,

View file

@ -24,6 +24,10 @@ if 'hydra' in drivers
driver_libs += [lib_drv_hydra] driver_libs += [lib_drv_hydra]
endif endif
if 'ns' in drivers
driver_libs += [lib_drv_ns]
endif
if 'ohmd' in drivers if 'ohmd' in drivers
driver_libs += [lib_drv_ohmd] driver_libs += [lib_drv_ohmd]
endif endif