external: introduce visual-inertial tracking interface header

Co-authored-by: Jakob Bornecrantz <jakob@collabora.com>
This commit is contained in:
Simon Zeni 2023-11-28 21:53:44 -05:00
parent 32c527f057
commit c6e629b4e7
3 changed files with 733 additions and 0 deletions

View file

@ -89,6 +89,11 @@ if(XRT_FEATURE_SLAM)
)
target_include_directories(xrt-external-slam SYSTEM INTERFACE ${SLAM_INCLUDE_DIRS})
target_link_libraries(xrt-external-slam INTERFACE ${SLAM_LDFLAGS})
add_library(xrt-external-vit INTERFACE)
target_include_directories(
xrt-external-vit INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/vit_includes
)
endif()
# SDL

View file

@ -0,0 +1,216 @@
// Copyright 2023, Collabora, Ltd.
// SPDX-License-Identifier: BSL-1.0
/*!
* @file
* @brief Visual-Intertial Tracking tracker helper.
* @author Jakob Bornecrantz <jakob@collabora.com>
* @author Simon Zeni <simon.zeni@collabora.com>
*/
#pragma once
#include "vit_interface.h"
namespace vit {
typedef vit_result_t Result;
typedef vit_image_format_t ImageFormat;
typedef vit_camera_distortion_t CameraDistortion;
typedef vit_tracker_capability_t TrackerCapability;
typedef vit_tracker_pose_capability_t TrackerPoseCapability;
typedef vit_tracker_timing_titles TrackerTimingTitles;
typedef vit_tracker_t Tracker;
typedef vit_config_t Config;
typedef vit_pose_t Pose;
typedef vit_config_t Config;
typedef vit_imu_sample_t ImuSample;
typedef vit_mask_t Mask;
typedef vit_img_sample_t ImgSample;
typedef vit_pose_data_t PoseData;
typedef vit_pose_timing_t PoseTiming;
typedef vit_pose_feature_t PoseFeature;
typedef vit_pose_features_t PoseFeatures;
typedef vit_camera_calibration_t CameraCalibration;
typedef vit_inertial_calibration_t InertialCalibration;
typedef vit_imu_calibration_t ImuCalibration;
} // namespace vit
extern "C" {
struct vit_tracker
{
virtual ~vit_tracker() = default;
virtual vit_result_t has_image_format(const vit_image_format_t fmt, bool *out_supported) const = 0;
virtual vit_result_t get_capabilities(vit_tracker_capability_t *out_capabilities) const = 0;
virtual vit_result_t get_pose_capabilities(vit_tracker_pose_capability_t *out_capabilities) const = 0;
virtual vit_result_t set_pose_capabilities(const vit_tracker_pose_capability_t capabilities, bool value) = 0;
virtual vit_result_t start() = 0;
virtual vit_result_t stop() = 0;
virtual vit_result_t reset() = 0;
virtual vit_result_t is_running(bool *out_running) const = 0;
virtual vit_result_t add_imu_calibration(const vit_imu_calibration_t *calibration) = 0;
virtual vit_result_t add_camera_calibration(const vit_camera_calibration_t *calibration) = 0;
virtual vit_result_t push_imu_sample(const vit_imu_sample_t *sample) = 0;
virtual vit_result_t push_img_sample(const vit_img_sample_t *sample) = 0;
virtual vit_result_t pop_pose(vit_pose_t **pose) = 0;
virtual vit_result_t get_timing_titles(vit_tracker_timing_titles *out_titles) const = 0;
};
struct vit_pose
{
virtual ~vit_pose() = default;
virtual vit_result_t get_data(vit_pose_data *out_data) const = 0;
virtual vit_result_t get_timing(vit_pose_timing *out_timing) const = 0;
virtual vit_result_t get_features(uint32_t camera_index, vit_pose_features_t *out_features) const = 0;
};
#ifdef VIT_INTERFACE_IMPLEMENTATION
vit_result_t
vit_api_get_version(uint32_t *out_major, uint32_t *out_minor, uint32_t *out_patch)
{
*out_major = VIT_HEADER_VERSION_MAJOR;
*out_minor = VIT_HEADER_VERSION_MINOR;
*out_patch = VIT_HEADER_VERSION_PATCH;
return VIT_SUCCESS;
}
void
vit_tracker_destroy(vit_tracker_t *tracker)
{
vit::Tracker *t = static_cast<vit::Tracker *>(tracker);
delete t;
}
vit_result_t
vit_tracker_has_image_format(const vit_tracker_t *tracker, const vit_image_format_t image_format, bool *out_supported)
{
const vit::Tracker *t = static_cast<const vit::Tracker *>(tracker);
return t->has_image_format(image_format, out_supported);
}
vit_result_t
vit_tracker_get_capabilities(const vit_tracker_t *tracker, vit_tracker_capability_t *out_caps)
{
const vit::Tracker *t = static_cast<const vit::Tracker *>(tracker);
return t->get_capabilities(out_caps);
}
vit_result_t
vit_tracker_get_pose_capabilities(const vit_tracker_t *tracker, vit_tracker_pose_capability_t *out_caps)
{
const vit::Tracker *t = static_cast<const vit::Tracker *>(tracker);
return t->get_pose_capabilities(out_caps);
}
vit_result_t
vit_tracker_set_pose_capabilities(vit_tracker_t *tracker, vit_tracker_pose_capability_t caps, bool value)
{
vit::Tracker *t = static_cast<vit::Tracker *>(tracker);
return t->set_pose_capabilities(caps, value);
}
vit_result_t
vit_tracker_start(vit_tracker_t *tracker)
{
vit::Tracker *t = static_cast<vit::Tracker *>(tracker);
return t->start();
}
vit_result_t
vit_tracker_stop(vit_tracker_t *tracker)
{
vit::Tracker *t = static_cast<vit::Tracker *>(tracker);
return t->stop();
}
vit_result_t
vit_tracker_reset(vit_tracker_t *tracker)
{
vit::Tracker *t = static_cast<vit::Tracker *>(tracker);
return t->reset();
}
vit_result_t
vit_tracker_is_running(const vit_tracker *tracker, bool *out_running)
{
const vit::Tracker *t = static_cast<const vit::Tracker *>(tracker);
return t->is_running(out_running);
}
vit_result_t
vit_tracker_push_imu_sample(vit_tracker *tracker, const vit_imu_sample_t *sample)
{
vit::Tracker *t = static_cast<vit::Tracker *>(tracker);
return t->push_imu_sample(sample);
}
vit_result_t
vit_tracker_push_img_sample(vit_tracker *tracker, const vit_img_sample_t *sample)
{
vit::Tracker *t = static_cast<vit::Tracker *>(tracker);
return t->push_img_sample(sample);
}
vit_result_t
vit_tracker_add_imu_calibration(vit_tracker_t *tracker, const vit_imu_calibration_t *calibration)
{
vit::Tracker *t = static_cast<vit::Tracker *>(tracker);
return t->add_imu_calibration(calibration);
}
vit_result_t
vit_tracker_add_camera_calibration(vit_tracker_t *tracker, const vit_camera_calibration_t *calibration)
{
vit::Tracker *t = static_cast<vit::Tracker *>(tracker);
return t->add_camera_calibration(calibration);
}
vit_result_t
vit_tracker_pop_pose(vit_tracker_t *tracker, vit_pose_t **out_pose)
{
vit::Tracker *t = static_cast<vit::Tracker *>(tracker);
return t->pop_pose(out_pose);
}
vit_result_t
vit_tracker_get_timing_titles(const vit_tracker_t *tracker, vit_tracker_timing_titles *out_titles)
{
const vit::Tracker *t = static_cast<const vit::Tracker *>(tracker);
return t->get_timing_titles(out_titles);
}
void
vit_pose_destroy(vit_pose_t *pose)
{
vit::Pose *p = static_cast<vit::Pose *>(pose);
delete p;
}
vit_result_t
vit_pose_get_data(const vit_pose_t *pose, vit_pose_data_t *out_data)
{
const vit::Pose *p = static_cast<const vit::Pose *>(pose);
return p->get_data(out_data);
}
vit_result_t
vit_pose_get_timing(const vit_pose_t *pose, vit_pose_timing_t *out_timing)
{
const vit::Pose *p = static_cast<const vit::Pose *>(pose);
return p->get_timing(out_timing);
}
vit_result_t
vit_pose_get_features(const vit_pose_t *pose, uint32_t camera_index, vit_pose_features_t *out_features)
{
const vit::Pose *p = static_cast<const vit::Pose *>(pose);
return p->get_features(camera_index, out_features);
}
#endif
}

View file

@ -0,0 +1,512 @@
// Copyright 2023, Collabora, Ltd.
// SPDX-License-Identifier: BSL-1.0
/*!
* @file
* @brief Visual-Intertial Tracking interface header.
* @author Mateo de Mayo <mateo.demayo@collabora.com>
* @author Simon Zeni <simon.zeni@collabora.com>
* @author Jakob Bornecrantz <jakob@collabora.com>
*
* This file contains the declaration of the @ref vit_tracker struct. This
* header is intended to appear in both Monado and external SLAM systems. The
* implementation of `vit_interface` is provided by the external system.
* Additional data types are declared for the communication between Monado and
* the system.
*/
#pragma once
#if defined(__cplusplus)
extern "C" {
#endif
#include <stdint.h>
#include <stdbool.h>
// For implementation: same as IMPLEMENTATION_VERSION_*
// For user: expected IMPLEMENTATION_VERSION_*. Should be checked in runtime.
#define VIT_HEADER_VERSION_MAJOR 1 //!< API Breakages
#define VIT_HEADER_VERSION_MINOR 0 //!< Backwards compatible API changes
#define VIT_HEADER_VERSION_PATCH 0 //!< Backw. comp. .h-implemented changes
/*!
* Result type used by the VIT system
*
* 0 is @ref VIT_SUCCESS, positive values are non fatal results and negative values are errors.
*/
typedef enum vit_result
{
/*!
* Operation suceeded
*/
VIT_SUCCESS = 0,
/*!
* The operation is not available on the current version
*/
VIT_ERROR_INVALID_VERSION = -1,
/*!
* The operation received an invalid value.
*/
VIT_ERROR_INVALID_VALUE = -2,
/*!
* The operation was not able to allocate memory to pursue the operation.
*/
VIT_ERROR_ALLOCATION_FAILURE = -3,
/*!
* The operation requires a capability that is not supported.
*/
VIT_ERROR_NOT_SUPPORTED = -4,
/*!
* The operation requires a capability that is not enabled.
*/
VIT_ERROR_NOT_ENABLED = -5,
} vit_result_t;
/*!
* Image formats.
*/
typedef enum vit_image_format
{
//! 8-bit luminance
VIT_IMAGE_FORMAT_L8 = 1,
//! 16-bit luminance
VIT_IMAGE_FORMAT_L16 = 2,
//! 24-bit rgb, tightly packed.
VIT_IMAGE_FORMAT_R8G8B8 = 3,
} vit_image_format_t;
/*!
* Camera calibration types.
*/
typedef enum vit_camera_distortion
{
//! No distortion (pre-disotorted).
VIT_CAMERA_DISTORTION_NONE,
//! Distortion radial-tangential (OpenCV), 4 parameters.
VIT_CAMERA_DISTORTION_RT4,
//! Distortion radial-tangential (OpenCV), 5 parameters.
VIT_CAMERA_DISTORTION_RT5,
//! Distortion radial-tangential (OpenCV), 8 parameters.
VIT_CAMERA_DISTORTION_RT8,
//! Distortion Kannala-Brandt (OpenCV fisheye), 4 parameters.
VIT_CAMERA_DISTORTION_KB4,
} vit_camera_distortion_t;
/*!
* Capabilities of the tracker.
*/
typedef enum vit_tracker_capability
{
//! Does the tracker support per pose (frame) timing data.
VIT_TRACKER_CAPABILITY_CAMERA_CALIBRATION = 1 << 0,
//! Does the tracker support per pose (frame) and per camera features.
VIT_TRACKER_CAPABILITY_IMU_CALIBRATION = 1 << 1,
} vit_tracker_capability_t;
/*!
* Capabilities of the poses that this tracker produces.
*/
typedef enum vit_tracker_pose_capability
{
//! Does the tracker support per pose (frame) timing data.
VIT_TRACKER_POSE_CAPABILITY_TIMING = 1 << 0,
//! Does the tracker support per pose (frame) and per camera features.
VIT_TRACKER_POSE_CAPABILITY_FEATURES = 1 << 1,
} vit_tracker_pose_capability_t;
/*!
* @brief Visual-Inertial Tracking interface, opaque type.
*/
struct vit_tracker;
typedef struct vit_tracker vit_tracker_t;
/*!
* @brief Pose interface, opaque type.
*/
struct vit_pose;
typedef struct vit_pose vit_pose_t;
/*!
* @brief Names of the timestamps returned by `vit_pose_get_timings`
*/
typedef struct vit_tracker_timing_titles
{
uint32_t count; //! Number of titles
const char **titles; //! Names of the measures timestamps
} vit_tracker_timing_titles;
/*!
* @brief Parameters for creating the system pipeline.
*/
typedef struct vit_config {
//! Path to a implementation-specific config file. If null, use defaults.
const char *file;
//! Number of cameras to use. Required.
uint32_t cam_count;
//! Number of IMU to use. Required.
uint32_t imu_count;
//! If supported, whether to open the system's UI.
bool show_ui;
} vit_config_t;
/*!
* @brief IMU sample type feed into VIT tracker
*/
typedef struct vit_imu_sample {
//! In nanoseconds
int64_t timestamp;
//! Acceleration in meters per second squared (m/s²)
float ax, ay, az;
//! Gyro in radians per second (rad/s)
float wx, wy, wz;
} vit_imu_sample_t;
/*!
* Region in image space that this mask covers.
*/
typedef struct vit_mask
{
//! In pixels.
float x, y, w, h;
} vit_mask_t;
/*!
* @brief Image sample type feed into VIT tracker
*
* Can easily be converted into an OpenCV Matrix for processing.
*/
typedef struct vit_img_sample {
uint32_t cam_index;
//! In nanoseconds, must increase monotonically.
int64_t timestamp;
// !Image data
uint8_t *data;
uint32_t width, height;
uint32_t stride, size;
vit_image_format_t format;
//! Regions to ignore
uint32_t mask_count;
vit_mask_t *masks;
} vit_img_sample_t;
/*!
* Data that is always returned from tracker.
*/
typedef struct vit_pose_data {
//! In nanoseconds, must increase monotonically.
int64_t timestamp;
//! Position vector.
float px, py, pz;
//! Orientation quaternion.
float ox, oy, oz, ow;
//! Linear velocity.
float vx, vy, vz;
} vit_pose_data_t;
/*!
* Result of pose timing request function.
*/
typedef struct vit_pose_timing {
uint32_t count;
const int64_t *timestamps;
} vit_pose_timing_t;
/*!
* One single feature, element of @ref vit_pose_features result.
*/
typedef struct vit_pose_feature {
int64_t id;
float u, v, depth;
} vit_pose_feature_t;
/*!
* Result of pose feature request function.
*/
typedef struct vit_pose_features {
uint32_t count;
const struct vit_pose_feature *features;
} vit_pose_features_t;
/*!
* Container of parameters for a pinhole camera calibration (fx, fy, cx, cy)
* with an optional distortion.
*
*`distortion_model` and its corresponding `distortion` parameters are not
* standardized in this struct to facilitate implementation prototyping.
*/
typedef struct vit_camera_calibration {
uint32_t camera_index; // <! For multi-camera setup. For stereo 0 ~ left, 1 ~ right.
int width, height; //<! Resolution
double frequency; //<! Frames per second
double fx, fy; //<! Focal point
double cx, cy; //<! Principal point
enum vit_camera_distortion model;
uint32_t distortion_count;
double distortion[32]; //!< Parameters for the distortion model
double transform[16]; //!< Row-major 4x4 camera transform w.r.t. the IMU (i.e., T_imu_cam)
} vit_camera_calibration_t;
typedef struct vit_inertial_calibration {
// Calibration intrinsics to apply to each raw measurement.
//! Row major 3x3 linear transformation for raw measurements alignment and scaling.
double transform[9];
//! Offset to add to raw measurements; called bias in other contexts.
double offset[3];
// Parameters for the random processes that model this IMU. See section "2.1
// Gyro Noise Model" of N. Trawny and S. I. Roumeliotis, "Indirect Kalman
// Filter for 3D Attitude Estimation". Analogous for accelerometers.
// http://mars.cs.umn.edu/tr/reports/Trawny05b.pdf#page=15
//! IMU internal bias ~ wiener process with steps N(0, σ²); this field is σ;
//! [σ] = U / sqrt(sec³) with U = rad if gyroscope, U = m/s if accelerometer.
double bias_std[3];
//! IMU measurement noise ~ N(0, σ²); this field is σ.
//! [σ] = U / sqrt(sec) with U = rad if gyroscope, U = m/s if accelerometer.
double noise_std[3];
} vit_inertial_calibration_t;
/*!
* Calibration for one IMU.
*/
typedef struct vit_imu_calibration {
uint32_t imu_index; //!< For multi-imu setup, usually just 0.
double frequency; //!< Samples per second
struct vit_inertial_calibration accel;
struct vit_inertial_calibration gyro;
} vit_imu_calibration_t;
/*
*
* Function prototypes.
*
*/
typedef vit_result_t (*PFN_vit_api_get_version)(uint32_t *out_major, uint32_t *out_minor, uint32_t *out_patch);
typedef vit_result_t (*PFN_vit_tracker_create)(const vit_config_t *config, vit_tracker_t **out_tracker);
typedef void (*PFN_vit_tracker_destroy)(vit_tracker_t *tracker);
typedef vit_result_t (*PFN_vit_tracker_has_image_format)(const vit_tracker_t *tracker, const vit_image_format_t image_format, bool *out_supported);
typedef vit_result_t (*PFN_vit_tracker_get_capabilities)(const vit_tracker_t *tracker, vit_tracker_capability_t *out_caps);
typedef vit_result_t (*PFN_vit_tracker_get_pose_capabilities)(const vit_tracker_t *tracker, vit_tracker_pose_capability_t *out_caps);
typedef vit_result_t (*PFN_vit_tracker_set_pose_capabilities)(vit_tracker_t *tracker, const vit_tracker_pose_capability_t caps, bool value);
typedef vit_result_t (*PFN_vit_tracker_start)(vit_tracker_t *tracker);
typedef vit_result_t (*PFN_vit_tracker_stop)(vit_tracker_t *tracker);
typedef vit_result_t (*PFN_vit_tracker_reset)(vit_tracker_t *tracker);
typedef vit_result_t (*PFN_vit_tracker_is_running)(const vit_tracker_t *tracker, bool *out_bool);
typedef vit_result_t (*PFN_vit_tracker_push_imu_sample)(vit_tracker_t *tracker, const vit_imu_sample_t *sample);
typedef vit_result_t (*PFN_vit_tracker_push_img_sample)(vit_tracker_t *tracker, const vit_img_sample_t *sample);
typedef vit_result_t (*PFN_vit_tracker_add_imu_calibration)(vit_tracker_t *tracker, const vit_imu_calibration_t *calibration);
typedef vit_result_t (*PFN_vit_tracker_add_camera_calibration)(vit_tracker_t *tracker, const vit_camera_calibration_t *calibration);
typedef vit_result_t (*PFN_vit_tracker_pop_pose)(vit_tracker_t *tracker, vit_pose_t **out_pose);
typedef vit_result_t (*PFN_vit_tracker_get_timing_titles)(const vit_tracker_t *tracker, vit_tracker_timing_titles *out_titles);
typedef void (*PFN_vit_pose_destroy)(vit_pose_t *pose);
typedef vit_result_t (*PFN_vit_pose_get_data)(const vit_pose_t *pose, vit_pose_data_t *out_data);
typedef vit_result_t (*PFN_vit_pose_get_timing)(const vit_pose_t *pose, vit_pose_timing_t *out_timing);
typedef vit_result_t (*PFN_vit_pose_get_features)(const vit_pose_t *pose, uint32_t camera_index, vit_pose_features_t *out_features);
/*
*
* Functions.
*
*/
#ifdef VIT_INTERFACE_IMPLEMENTATION
/*!
* @brief Returns the API version implemented by the VIT system.
*/
vit_result_t
vit_api_get_version(uint32_t *out_major, uint32_t *out_minor, uint32_t *out_patch);
/*!
* @brief Creates a new VIT tracker. The caller is responsible of destroying it when done.
*/
vit_result_t
vit_tracker_create(const vit_config_t *config, vit_tracker_t **out_tracker);
/*!
* @brief Destroys the VIT tracker and free all resources allocated.
*/
void
vit_tracker_destroy(vit_tracker_t *tracker);
/*!
* @brief Verifies if the tracker supports a given `vit_image_format_t`.
*/
vit_result_t
vit_tracker_has_image_format(const vit_tracker_t *tracker, const vit_image_format_t image_format, bool *out_supported);
/*!
* @brief Returns a bitfield of capabilities supported by the tracker.
*
* @see vit_tracker_capability_t
*/
vit_result_t
vit_tracker_get_capabilities(const vit_tracker_t *tracker, vit_tracker_capability_t *out_caps);
/*!
* @brief Returns a bitfield of pose capabilities supported by the tracker.
*
* @see vit_tracker_pose_capability_t
*/
vit_result_t
vit_tracker_get_pose_capabilities(const vit_tracker_t *tracker, vit_tracker_pose_capability_t *out_caps);
/*!
* @brief Enables or disables multiple tracker pose capabilities.
*
* @p caps can be a bitfield of `vit_tracker_pose_capability_t`.
*
* @see vit_tracker_pose_capability_t
*/
vit_result_t
vit_tracker_set_pose_capabilities(vit_tracker_t *tracker, const vit_tracker_pose_capability_t caps, bool value);
/*!
* @brief Starts the VIT tracker. Image and IMU samples can be pushed and pose can be retrieved.
*
* This function must be non blocking. The VIT system implementing it is expected to start its own event loop.
*/
vit_result_t
vit_tracker_start(vit_tracker_t *tracker);
/*!
* @brief Stops the VIT tracker. The tracker wont accept image and IMU samples, and will not return poses.
*/
vit_result_t
vit_tracker_stop(vit_tracker_t *tracker);
/*!
* @brief Resets the VIT tracker. The tracker internal state will be set to its original state.
*/
vit_result_t
vit_tracker_reset(vit_tracker_t *tracker);
/*!
* @brief Verifies if the tracker is running.
*/
vit_result_t
vit_tracker_is_running(const vit_tracker_t *tracker, bool *out_bool);
/*!
* @brief Push an IMU sample into the tracker.
*
* There must be a single producer thread pushing samples.
* Samples must have monotonically increasing timestamps.
* The implementation must be non-blocking.
* Thus, a separate consumer thread should process the samples.
*/
vit_result_t
vit_tracker_push_imu_sample(vit_tracker_t *tracker, const vit_imu_sample_t *sample);
/*!
* @brief Push an image sample into the tracker.
*
* Same conditions as @ref push_imu_sample apply.
* When using N>1 cameras, the N frames must be pushed following @ref cam_index order.
* The bundle of N frames must have the same timestamps.
*/
vit_result_t
vit_tracker_push_img_sample(vit_tracker_t *tracker, const vit_img_sample_t *sample);
/*!
* @brief Adds an inertial measurement unit calibration to the tracker. The tracker must not be started.
*
* Returns `VIT_ERROR_NOT_SUPPORTED` if the tracker doesn't offer the capability.
*
* @see vit_tracker_get_capabilities
* @see vit_tracker_capability_t
*/
vit_result_t
vit_tracker_add_imu_calibration(vit_tracker_t *tracker, const vit_imu_calibration_t *calibration);
/*!
* @brief Adds a camera calibration to the tracker. The tracker must not be started.
*
* Returns `VIT_ERROR_NOT_SUPPORTED` if the tracker doesn't offer the capability.
*
* @see vit_tracker_get_capabilities
* @see vit_tracker_capability_t
*/
vit_result_t
vit_tracker_add_camera_calibration(vit_tracker_t *tracker, const vit_camera_calibration_t *calibration);
/*!
* @brief Get the pose from the front of the tracking queue from the VIT tracker
*
* This function must be non-blocking and consumed by a single consummer.
*
* If @p out_pose is NULL the pose will be immediately destroyed.
*
* @param[out] out_pose Pose returned to the caller, NULL if there is not pose available or on error.
*/
vit_result_t
vit_tracker_pop_pose(vit_tracker_t *tracker, vit_pose_t **out_pose);
/*!
* @brief Get the titles of the timestamps measured by the pose timings.
*
* Returns `VIT_ERROR_NOT_SUPPORTED` if the tracker doesn't offer the pose timing capability.
*/
vit_result_t
vit_tracker_get_timing_titles(const vit_tracker_t *tracker, vit_tracker_timing_titles *out_titles);
/*!
* @brief Destroys a pose. All of the data, timing and features associated to it will be invalidated.
*/
void
vit_pose_destroy(vit_pose_t *pose);
/*!
* @brief Gets the data form a given `vit_pose_t`.
*
* The data becomes invalid when the associated pose gets destroyed.
*/
vit_result_t
vit_pose_get_data(const vit_pose_t *pose, vit_pose_data_t *out_data);
/*!
* @brief Gets the timing form a given `vit_pose_t`.
*
* The timing data becomes invalid when the associated pose gets destroyed.
*/
vit_result_t
vit_pose_get_timing(const vit_pose_t *pose, vit_pose_timing_t *out_timing);
/*!
* @brief Gets the features form a given `vit_pose_t`.
*
* The features data becomes invalid when the associated pose gets destroyed.
*/
vit_result_t
vit_pose_get_features(const vit_pose_t *pose, uint32_t camera_index, vit_pose_features_t *out_features);
#endif
#if defined(__cplusplus)
}
#endif