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_PSMV "Enable Playstation Move driver" ON)
option(BUILD_WITH_HYDRA "Enable Hydra driver" ON)
option(BUILD_WITH_NS "Enable North Star driver" ON)
###
# Flags
@ -139,6 +140,10 @@ if(BUILD_WITH_OPENHMD)
set(BUILD_DRIVER_OHMD TRUE)
endif()
if(BUILD_WITH_NS)
set(BUILD_DRIVER_NS TRUE)
endif()
if(BUILD_WITH_PSVR)
if (NOT ${HIDAPI_FOUND})
message(FATAL_ERROR "PSVR driver requires hidapi")

View file

@ -131,6 +131,9 @@ drivers = get_option('drivers')
if 'ohmd' in drivers
openhmd_required = true
endif
if 'ns' in drivers
ns_required = true
endif
if 'psvr' in drivers
hidapi_required = true
endif
@ -146,6 +149,12 @@ openhmd = dependency('openhmd', required: openhmd_required)
hidapi = dependency('hidapi-libusb', required: hidapi_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 'ohmd' not in drivers
drivers += ['ohmd']

View file

@ -3,7 +3,7 @@
option('drivers',
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'],
description: 'Set of drivers to build')

View file

@ -18,6 +18,10 @@ if(BUILD_DRIVER_HYDRA)
set(XRT_BUILD_DRIVER_HYDRA TRUE)
endif()
if(BUILD_DRIVER_NS)
set(XRT_BUILD_DRIVER_NS TRUE)
endif()
if(BUILD_DRIVER_OHMD)
set(XRT_BUILD_DRIVER_OHMD TRUE)
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_HDK', 'hdk' 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_PSMV', 'psmv' 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_NS
#cmakedefine XRT_BUILD_DRIVER_OHMD
#cmakedefine XRT_BUILD_DRIVER_PSMV

View file

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

View file

@ -48,6 +48,18 @@ if(BUILD_DRIVER_HYDRA)
list(APPEND ENABLED_DRIVERS hydra)
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)
set(OHMD_SOURCE_FILES
ohmd/oh_device.c

View file

@ -39,6 +39,18 @@ lib_drv_hydra = static_library(
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(
'drv_ohmd',
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>)
endif()
if(BUILD_DRIVER_NS)
list(APPEND DRIVER_OBJECTS $<TARGET_OBJECTS:drv_ns>)
endif()
if(BUILD_DRIVER_OHMD)
list(APPEND DRIVER_OBJECTS $<TARGET_OBJECTS:drv_ohmd>)
list(APPEND DRIVER_LIBRARIES OpenHMD::OpenHMD)

View file

@ -22,6 +22,10 @@
#include "ohmd/oh_interface.h"
#endif
#ifdef XRT_BUILD_DRIVER_NS
#include "north_star/ns_interface.h"
#endif
#ifdef XRT_BUILD_DRIVER_PSMV
#include "psmv/psmv_interface.h"
#endif
@ -89,10 +93,15 @@ xrt_auto_prober_creator target_auto_list[] = {
#endif
#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,
#endif
#ifdef XRT_BUILD_DRIVER_NS
// North star driver here for now.
ns_create_auto_prober,
#endif
#ifdef XRT_BUILD_DRIVER_DUMMY
// Dummy headset driver last.
dummy_create_auto_prober,

View file

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