The open source OpenXR runtime
at prediction-2 497 lines 16 kB view raw
1// Copyright 2023-2024, Collabora, Ltd. 2// SPDX-License-Identifier: BSL-1.0 3/*! 4 * @file 5 * @brief Visual-Intertial Tracking interface header. 6 * @author Mateo de Mayo <mateo.demayo@collabora.com> 7 * @author Simon Zeni <simon.zeni@collabora.com> 8 * @author Jakob Bornecrantz <jakob@collabora.com> 9 * 10 * This file contains the declaration of the @ref vit_tracker struct. This 11 * header is intended to appear in both consumers (e.g., Monado) and external 12 * visual-inertial tracking (VIT) systems (e.g., Basalt). The implementation of 13 * `vit_interface` is provided by the external system. Additional data types are 14 * declared for the communication between consumers and the system. 15 */ 16 17#pragma once 18 19#if defined(__cplusplus) 20extern "C" { 21#endif 22 23#include <stdbool.h> 24#include <stdint.h> 25 26//! Compatibility with these values should be checked against @ref vit_api_get_version. 27#define VIT_HEADER_VERSION_MAJOR 2 //!< API Breakages 28#define VIT_HEADER_VERSION_MINOR 0 //!< Backwards compatible API changes 29#define VIT_HEADER_VERSION_PATCH 1 //!< Backw. comp. .h-implemented changes 30 31#define VIT_CAMERA_CALIBRATION_DISTORTION_MAX_COUNT 32 32 33/*! 34 * Result type used by the VIT system 35 * 36 * 0 is @ref VIT_SUCCESS, positive values are non fatal results and negative values are errors. 37 */ 38typedef enum vit_result { 39 /*! 40 * Operation suceeded 41 */ 42 VIT_SUCCESS = 0, 43 44 /*! 45 * The operation is not available on the current version 46 */ 47 VIT_ERROR_INVALID_VERSION = -1, 48 49 /*! 50 * The operation received an invalid value. 51 */ 52 VIT_ERROR_INVALID_VALUE = -2, 53 54 /*! 55 * The operation was not able to allocate memory to pursue the operation. 56 */ 57 VIT_ERROR_ALLOCATION_FAILURE = -3, 58 59 /*! 60 * The operation requires an extension that is not supported. 61 */ 62 VIT_ERROR_NOT_SUPPORTED = -4, 63 64 /*! 65 * The operation requires an extension that is not enabled. 66 */ 67 VIT_ERROR_NOT_ENABLED = -5, 68} vit_result_t; 69 70/*! 71 * Image formats. 72 */ 73typedef enum vit_image_format { 74 //! 8-bit luminance 75 VIT_IMAGE_FORMAT_L8 = 1, 76 //! 16-bit luminance 77 VIT_IMAGE_FORMAT_L16 = 2, 78 //! 24-bit rgb, tightly packed. 79 VIT_IMAGE_FORMAT_R8G8B8 = 3, 80} vit_image_format_t; 81 82/*! 83 * Camera calibration types. 84 */ 85typedef enum vit_camera_distortion { 86 //! No distortion (pre-disotorted). 87 VIT_CAMERA_DISTORTION_NONE, 88 //! Distortion radial-tangential (OpenCV), 4 parameters. 89 VIT_CAMERA_DISTORTION_RT4, 90 //! Distortion radial-tangential (OpenCV), 5 parameters. 91 VIT_CAMERA_DISTORTION_RT5, 92 //! Distortion radial-tangential (OpenCV), 8 parameters. 93 VIT_CAMERA_DISTORTION_RT8, 94 //! Distortion Kannala-Brandt (OpenCV fisheye), 4 parameters. 95 VIT_CAMERA_DISTORTION_KB4, 96} vit_camera_distortion_t; 97 98/*! 99 * Optional functionality a tracker can provide. 100 */ 101typedef enum vit_tracker_extension { 102 //! Allows to specify camera calibration data programatically 103 VIT_TRACKER_EXTENSION_ADD_CAMERA_CALIBRATION, 104 //! Allows to specify IMU calibration data programatically 105 VIT_TRACKER_EXTENSION_ADD_IMU_CALIBRATION, 106 //! Optionally provide timing information with the returned poses 107 VIT_TRACKER_EXTENSION_POSE_TIMING, 108 //! Optionally provide feature count information with the returned poses 109 VIT_TRACKER_EXTENSION_POSE_FEATURES, 110 //! Number of extensions 111 VIT_TRACKER_EXTENSION_COUNT, 112} vit_tracker_extension_t; 113 114/*! 115 * Set of extensions. Field order matches enumerators in @ref vit_tracker_extension. 116 */ 117typedef struct vit_tracker_extension_set { 118 bool has_add_camera_calibration; 119 bool has_add_imu_calibration; 120 bool has_pose_timing; 121 bool has_pose_features; 122} vit_tracker_extension_set_t; 123 124/*! 125 * Visual-Inertial Tracking interface, opaque type. 126 */ 127struct vit_tracker; 128typedef struct vit_tracker vit_tracker_t; 129 130/*! 131 * Pose interface, opaque type. 132 */ 133struct vit_pose; 134typedef struct vit_pose vit_pose_t; 135 136/*! 137 * Names of the timestamps returned by `vit_pose_get_timings` 138 */ 139typedef struct vit_tracker_timing_titles { 140 uint32_t count; //! Number of titles 141 const char **titles; //! Names of the measures timestamps 142} vit_tracker_timing_titles; 143 144/*! 145 * Parameters for creating the system pipeline. 146 */ 147typedef struct vit_config { 148 //! Path to a implementation-specific config file. If null, use defaults. 149 const char *file; 150 151 //! Number of cameras to use. Required. 152 uint32_t cam_count; 153 154 //! Number of IMU to use. Required. 155 uint32_t imu_count; 156 157 //! If supported, whether to open the system's UI. 158 bool show_ui; 159} vit_config_t; 160 161/*! 162 * IMU sample type feed into VIT tracker 163 */ 164typedef struct vit_imu_sample { 165 //! In nanoseconds 166 int64_t timestamp; 167 168 //! Acceleration in meters per second squared (m/s²) 169 float ax, ay, az; 170 171 //! Gyro in radians per second (rad/s) 172 float wx, wy, wz; 173} vit_imu_sample_t; 174 175/*! 176 * Region in image space that this mask covers. 177 */ 178typedef struct vit_mask { 179 //! In pixels. 180 float x, y, w, h; 181} vit_mask_t; 182 183/*! 184 * Image sample type feed into VIT tracker 185 * 186 * Can easily be converted into an OpenCV Matrix for processing. 187 */ 188typedef struct vit_img_sample { 189 uint32_t cam_index; 190 191 //! In nanoseconds, must increase monotonically. 192 int64_t timestamp; 193 194 // !Image data 195 uint8_t *data; 196 uint32_t width, height; 197 uint32_t stride, size; 198 vit_image_format_t format; 199 200 //! Regions to ignore 201 uint32_t mask_count; 202 vit_mask_t *masks; 203} vit_img_sample_t; 204 205/*! 206 * Data that is always returned from tracker. 207 */ 208typedef struct vit_pose_data { 209 //! In nanoseconds, must increase monotonically. 210 int64_t timestamp; 211 212 //! Position vector. 213 float px, py, pz; 214 215 //! Orientation quaternion. 216 float ox, oy, oz, ow; 217 218 //! Linear velocity. 219 float vx, vy, vz; 220} vit_pose_data_t; 221 222/*! 223 * Result of pose timing request function. 224 */ 225typedef struct vit_pose_timing { 226 uint32_t count; 227 const int64_t *timestamps; 228} vit_pose_timing_t; 229 230/*! 231 * One single feature, element of @ref vit_pose_features result. 232 */ 233typedef struct vit_pose_feature { 234 int64_t id; 235 float u, v, depth; 236} vit_pose_feature_t; 237 238/*! 239 * Result of pose feature request function. 240 */ 241typedef struct vit_pose_features { 242 uint32_t count; 243 const struct vit_pose_feature *features; 244} vit_pose_features_t; 245 246/*! 247 * Container of parameters for a pinhole camera calibration (fx, fy, cx, cy) 248 * with an optional distortion. 249 * 250 *`distortion_model` and its corresponding `distortion` parameters are not 251 * standardized in this struct to facilitate implementation prototyping. 252 */ 253typedef struct vit_camera_calibration { 254 uint32_t camera_index; // <! For multi-camera setup. For stereo 0 ~ left, 1 ~ right. 255 256 int width, height; //<! Resolution 257 double frequency; //<! Frames per second 258 double fx, fy; //<! Focal point 259 double cx, cy; //<! Principal point 260 enum vit_camera_distortion model; 261 uint32_t distortion_count; 262 double distortion[VIT_CAMERA_CALIBRATION_DISTORTION_MAX_COUNT]; //!< Parameters for the distortion model 263 double transform[4 * 4]; //!< Row-major 4x4 camera transform w.r.t. the IMU (i.e., T_imu_cam) 264} vit_camera_calibration_t; 265 266typedef struct vit_inertial_calibration { 267 // Calibration intrinsics to apply to each raw measurement. 268 269 //! Row major 3x3 linear transformation for raw measurements alignment and scaling. 270 double transform[3 * 3]; 271 272 //! Offset to add to raw measurements; called bias in other contexts. 273 double offset[3]; 274 275 // Parameters for the random processes that model this IMU. See section "2.1 276 // Gyro Noise Model" of N. Trawny and S. I. Roumeliotis, "Indirect Kalman 277 // Filter for 3D Attitude Estimation". Analogous for accelerometers. 278 // http://mars.cs.umn.edu/tr/reports/Trawny05b.pdf#page=15 279 280 //! IMU internal bias ~ wiener process with steps N(0, σ²); this field is σ; 281 //! [σ] = U / sqrt(sec³) with U = rad if gyroscope, U = m/s if accelerometer. 282 double bias_std[3]; 283 284 //! IMU measurement noise ~ N(0, σ²); this field is σ. 285 //! [σ] = U / sqrt(sec) with U = rad if gyroscope, U = m/s if accelerometer. 286 double noise_std[3]; 287} vit_inertial_calibration_t; 288 289/*! 290 * Calibration for one IMU. 291 */ 292typedef struct vit_imu_calibration { 293 uint32_t imu_index; //!< For multi-imu setup, usually just 0. 294 295 double frequency; //!< Samples per second 296 struct vit_inertial_calibration accel; 297 struct vit_inertial_calibration gyro; 298} vit_imu_calibration_t; 299 300/* 301 * 302 * Function prototypes. 303 * 304 */ 305 306typedef vit_result_t (*PFN_vit_api_get_version)(uint32_t *out_major, uint32_t *out_minor, uint32_t *out_patch); 307typedef vit_result_t (*PFN_vit_tracker_create)(const vit_config_t *config, vit_tracker_t **out_tracker); 308typedef void (*PFN_vit_tracker_destroy)(vit_tracker_t *tracker); 309typedef vit_result_t (*PFN_vit_tracker_has_image_format)(const vit_tracker_t *tracker, vit_image_format_t image_format, 310 bool *out_supported); 311typedef vit_result_t (*PFN_vit_tracker_get_supported_extensions)(const vit_tracker_t *tracker, 312 vit_tracker_extension_set_t *out_exts); 313typedef vit_result_t (*PFN_vit_tracker_get_enabled_extensions)(const vit_tracker_t *tracker, 314 vit_tracker_extension_set_t *out_exts); 315typedef vit_result_t (*PFN_vit_tracker_enable_extension)(vit_tracker_t *tracker, vit_tracker_extension_t ext, 316 bool enable); 317typedef vit_result_t (*PFN_vit_tracker_start)(vit_tracker_t *tracker); 318typedef vit_result_t (*PFN_vit_tracker_stop)(vit_tracker_t *tracker); 319typedef vit_result_t (*PFN_vit_tracker_reset)(vit_tracker_t *tracker); 320typedef vit_result_t (*PFN_vit_tracker_is_running)(const vit_tracker_t *tracker, bool *out_bool); 321typedef vit_result_t (*PFN_vit_tracker_push_imu_sample)(vit_tracker_t *tracker, const vit_imu_sample_t *sample); 322typedef vit_result_t (*PFN_vit_tracker_push_img_sample)(vit_tracker_t *tracker, const vit_img_sample_t *sample); 323typedef vit_result_t (*PFN_vit_tracker_add_imu_calibration)(vit_tracker_t *tracker, 324 const vit_imu_calibration_t *calibration); 325typedef vit_result_t (*PFN_vit_tracker_add_camera_calibration)(vit_tracker_t *tracker, 326 const vit_camera_calibration_t *calibration); 327typedef vit_result_t (*PFN_vit_tracker_pop_pose)(vit_tracker_t *tracker, vit_pose_t **out_pose); 328typedef vit_result_t (*PFN_vit_tracker_get_timing_titles)(const vit_tracker_t *tracker, 329 vit_tracker_timing_titles *out_titles); 330typedef void (*PFN_vit_pose_destroy)(vit_pose_t *pose); 331typedef vit_result_t (*PFN_vit_pose_get_data)(const vit_pose_t *pose, vit_pose_data_t *out_data); 332typedef vit_result_t (*PFN_vit_pose_get_timing)(const vit_pose_t *pose, vit_pose_timing_t *out_timing); 333typedef vit_result_t (*PFN_vit_pose_get_features)(const vit_pose_t *pose, uint32_t camera_index, 334 vit_pose_features_t *out_features); 335 336/* 337 * 338 * Functions. 339 * 340 */ 341 342#ifdef VIT_INTERFACE_IMPLEMENTATION 343 344/*! 345 * Returns the API version implemented by the VIT system. 346 */ 347vit_result_t vit_api_get_version(uint32_t *out_major, uint32_t *out_minor, uint32_t *out_patch); 348 349/*! 350 * Creates a new VIT tracker. The caller is responsible of destroying it when done. 351 */ 352vit_result_t vit_tracker_create(const vit_config_t *config, vit_tracker_t **out_tracker); 353 354/*! 355 * Destroys the VIT tracker and free all resources allocated. 356 */ 357void vit_tracker_destroy(vit_tracker_t *tracker); 358 359/*! 360 * Verifies if the tracker supports a given `vit_image_format_t`. 361 */ 362vit_result_t vit_tracker_has_image_format(const vit_tracker_t *tracker, vit_image_format_t image_format, 363 bool *out_supported); 364 365/*! 366 * Returns a set with the extensions supported by this tracker. 367 * 368 * @see vit_tracker_extension_t 369 */ 370 371vit_result_t vit_tracker_get_supported_extensions(const vit_tracker_t *tracker, vit_tracker_extension_set_t *out_exts); 372 373/*! 374 * Returns a set with the extensions enabled in this tracker. 375 * 376 * @see vit_tracker_extension_t 377 */ 378 379vit_result_t vit_tracker_get_enabled_extensions(const vit_tracker_t *tracker, vit_tracker_extension_set_t *out_exts); 380 381/*! 382 * Enables or disables a tracker extension. 383 * 384 * @see vit_tracker_extension_t 385 */ 386vit_result_t vit_tracker_enable_extension(vit_tracker_t *tracker, vit_tracker_extension_t ext, bool value); 387 388/*! 389 * Starts the VIT tracker. Image and IMU samples can be pushed and pose can be retrieved. 390 * 391 * This function must be non blocking. The VIT system implementing it is expected to start its own event loop. 392 */ 393vit_result_t vit_tracker_start(vit_tracker_t *tracker); 394 395/*! 396 * Stops the VIT tracker. The tracker wont accept image and IMU samples, and will not return poses. 397 */ 398vit_result_t vit_tracker_stop(vit_tracker_t *tracker); 399 400/*! 401 * Resets the VIT tracker. The tracker internal state will be set to its original state. 402 */ 403vit_result_t vit_tracker_reset(vit_tracker_t *tracker); 404 405/*! 406 * Verifies if the tracker is running. 407 */ 408vit_result_t vit_tracker_is_running(const vit_tracker_t *tracker, bool *out_bool); 409 410/*! 411 * Push an IMU sample into the tracker. 412 * 413 * There must be a single producer thread pushing samples. 414 * Samples must have monotonically increasing timestamps. 415 * The implementation must be non-blocking. 416 * Thus, a separate consumer thread should process the samples. 417 */ 418vit_result_t vit_tracker_push_imu_sample(vit_tracker_t *tracker, const vit_imu_sample_t *sample); 419 420/*! 421 * Push an image sample into the tracker. 422 * 423 * Same conditions as @ref push_imu_sample apply. 424 * When using N>1 cameras, the N frames must be pushed following @ref cam_index order. 425 * The bundle of N frames must have the same timestamps. 426 */ 427vit_result_t vit_tracker_push_img_sample(vit_tracker_t *tracker, const vit_img_sample_t *sample); 428 429/*! 430 * Adds an inertial measurement unit calibration to the tracker. The tracker must not be started. 431 * 432 * Returns `VIT_ERROR_NOT_SUPPORTED` if the tracker doesn't offer the extension. 433 * 434 * @see vit_tracker_get_supported_extensions 435 * @see vit_tracker_extension_t 436 */ 437vit_result_t vit_tracker_add_imu_calibration(vit_tracker_t *tracker, const vit_imu_calibration_t *calibration); 438 439/*! 440 * Adds a camera calibration to the tracker. The tracker must not be started. 441 * 442 * Returns `VIT_ERROR_NOT_SUPPORTED` if the tracker doesn't offer the extension. 443 * 444 * @see vit_tracker_get_supported_extensions 445 * @see vit_tracker_extension_t 446 */ 447vit_result_t vit_tracker_add_camera_calibration(vit_tracker_t *tracker, const vit_camera_calibration_t *calibration); 448 449/*! 450 * Get the pose from the front of the tracking queue from the VIT tracker 451 * 452 * This function must be non-blocking and consumed by a single consummer. 453 * 454 * If @p out_pose is NULL the pose will be immediately destroyed. 455 * 456 * @param[out] out_pose Pose returned to the caller, NULL if there is not pose available or on error. 457 */ 458vit_result_t vit_tracker_pop_pose(vit_tracker_t *tracker, vit_pose_t **out_pose); 459 460/*! 461 * Get the titles of the timestamps measured by the pose timings. 462 * 463 * Returns `VIT_ERROR_NOT_SUPPORTED` if the tracker doesn't offer the pose timing extension. 464 */ 465vit_result_t vit_tracker_get_timing_titles(const vit_tracker_t *tracker, vit_tracker_timing_titles *out_titles); 466 467/*! 468 * Destroys a pose. All of the data, timing and features associated to it will be invalidated. 469 */ 470void vit_pose_destroy(vit_pose_t *pose); 471 472/*! 473 * Gets the data form a given `vit_pose_t`. 474 * 475 * The data becomes invalid when the associated pose gets destroyed. 476 */ 477vit_result_t vit_pose_get_data(const vit_pose_t *pose, vit_pose_data_t *out_data); 478 479/*! 480 * Gets the timing form a given `vit_pose_t`. 481 * 482 * The timing data becomes invalid when the associated pose gets destroyed. 483 */ 484vit_result_t vit_pose_get_timing(const vit_pose_t *pose, vit_pose_timing_t *out_timing); 485 486/*! 487 * Gets the features form a given `vit_pose_t`. 488 * 489 * The features data becomes invalid when the associated pose gets destroyed. 490 */ 491vit_result_t vit_pose_get_features(const vit_pose_t *pose, uint32_t camera_index, vit_pose_features_t *out_features); 492 493#endif 494 495#if defined(__cplusplus) 496} 497#endif