···24#include <stdint.h>
2526//! Compatibility with these values should be checked against @ref vit_api_get_version.
27-#define VIT_HEADER_VERSION_MAJOR 1 //!< 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···57 VIT_ERROR_ALLOCATION_FAILURE = -3,
5859 /*!
60- * The operation requires a capability that is not supported.
61 */
62 VIT_ERROR_NOT_SUPPORTED = -4,
6364 /*!
65- * The operation requires a capability that is not enabled.
66 */
67 VIT_ERROR_NOT_ENABLED = -5,
68} vit_result_t;
···96} vit_camera_distortion_t;
9798/*!
99- * Capabilities of the tracker.
100 */
101-typedef enum vit_tracker_capability {
102- //! Does the tracker support per pose (frame) timing data.
103- VIT_TRACKER_CAPABILITY_CAMERA_CALIBRATION = 1 << 0,
104- //! Does the tracker support per pose (frame) and per camera features.
105- VIT_TRACKER_CAPABILITY_IMU_CALIBRATION = 1 << 1,
106-} vit_tracker_capability_t;
000000107108/*!
109- * Capabilities of the poses that this tracker produces.
110 */
111-typedef enum vit_tracker_pose_capability {
112- //! Does the tracker support per pose (frame) timing data.
113- VIT_TRACKER_POSE_CAPABILITY_TIMING = 1 << 0,
114- //! Does the tracker support per pose (frame) and per camera features.
115- VIT_TRACKER_POSE_CAPABILITY_FEATURES = 1 << 1,
116-} vit_tracker_pose_capability_t;
117118/*!
119- * @brief Visual-Inertial Tracking interface, opaque type.
120 */
121struct vit_tracker;
122typedef struct vit_tracker vit_tracker_t;
123124/*!
125- * @brief Pose interface, opaque type.
126 */
127struct vit_pose;
128typedef struct vit_pose vit_pose_t;
129130/*!
131- * @brief Names of the timestamps returned by `vit_pose_get_timings`
132 */
133typedef struct vit_tracker_timing_titles {
134 uint32_t count; //! Number of titles
···136} vit_tracker_timing_titles;
137138/*!
139- * @brief Parameters for creating the system pipeline.
140 */
141typedef struct vit_config {
142 //! Path to a implementation-specific config file. If null, use defaults.
···153} vit_config_t;
154155/*!
156- * @brief IMU sample type feed into VIT tracker
157 */
158typedef struct vit_imu_sample {
159 //! In nanoseconds
···175} vit_mask_t;
176177/*!
178- * @brief Image sample type feed into VIT tracker
179 *
180 * Can easily be converted into an OpenCV Matrix for processing.
181 */
···302typedef void (*PFN_vit_tracker_destroy)(vit_tracker_t *tracker);
303typedef vit_result_t (*PFN_vit_tracker_has_image_format)(const vit_tracker_t *tracker, vit_image_format_t image_format,
304 bool *out_supported);
305-typedef vit_result_t (*PFN_vit_tracker_get_capabilities)(const vit_tracker_t *tracker,
306- vit_tracker_capability_t *out_caps);
307-typedef vit_result_t (*PFN_vit_tracker_get_pose_capabilities)(const vit_tracker_t *tracker,
308- vit_tracker_pose_capability_t *out_caps);
309-typedef vit_result_t (*PFN_vit_tracker_set_pose_capabilities)(vit_tracker_t *tracker,
310- vit_tracker_pose_capability_t caps, bool value);
311typedef vit_result_t (*PFN_vit_tracker_start)(vit_tracker_t *tracker);
312typedef vit_result_t (*PFN_vit_tracker_stop)(vit_tracker_t *tracker);
313typedef vit_result_t (*PFN_vit_tracker_reset)(vit_tracker_t *tracker);
···336#ifdef VIT_INTERFACE_IMPLEMENTATION
337338/*!
339- * @brief Returns the API version implemented by the VIT system.
340 */
341vit_result_t vit_api_get_version(uint32_t *out_major, uint32_t *out_minor, uint32_t *out_patch);
342343/*!
344- * @brief Creates a new VIT tracker. The caller is responsible of destroying it when done.
345 */
346vit_result_t vit_tracker_create(const vit_config_t *config, vit_tracker_t **out_tracker);
347348/*!
349- * @brief Destroys the VIT tracker and free all resources allocated.
350 */
351void vit_tracker_destroy(vit_tracker_t *tracker);
352353/*!
354- * @brief Verifies if the tracker supports a given `vit_image_format_t`.
355 */
356vit_result_t vit_tracker_has_image_format(const vit_tracker_t *tracker, vit_image_format_t image_format,
357 bool *out_supported);
358359/*!
360- * @brief Returns a bitfield of capabilities supported by the tracker.
361 *
362- * @see vit_tracker_capability_t
363 */
364365-vit_result_t vit_tracker_get_capabilities(const vit_tracker_t *tracker, vit_tracker_capability_t *out_caps);
366367/*!
368- * @brief Returns a bitfield of pose capabilities supported by the tracker.
369 *
370- * @see vit_tracker_pose_capability_t
371 */
372-vit_result_t vit_tracker_get_pose_capabilities(const vit_tracker_t *tracker, vit_tracker_pose_capability_t *out_caps);
0373374/*!
375- * @brief Enables or disables multiple tracker pose capabilities.
376 *
377- * @p caps can be a bitfield of `vit_tracker_pose_capability_t`.
378- *
379- * @see vit_tracker_pose_capability_t
380 */
381-vit_result_t vit_tracker_set_pose_capabilities(vit_tracker_t *tracker, vit_tracker_pose_capability_t caps, bool value);
382383/*!
384- * @brief Starts the VIT tracker. Image and IMU samples can be pushed and pose can be retrieved.
385 *
386 * This function must be non blocking. The VIT system implementing it is expected to start its own event loop.
387 */
388vit_result_t vit_tracker_start(vit_tracker_t *tracker);
389390/*!
391- * @brief Stops the VIT tracker. The tracker wont accept image and IMU samples, and will not return poses.
392 */
393vit_result_t vit_tracker_stop(vit_tracker_t *tracker);
394395/*!
396- * @brief Resets the VIT tracker. The tracker internal state will be set to its original state.
397 */
398vit_result_t vit_tracker_reset(vit_tracker_t *tracker);
399400/*!
401- * @brief Verifies if the tracker is running.
402 */
403vit_result_t vit_tracker_is_running(const vit_tracker_t *tracker, bool *out_bool);
404405/*!
406- * @brief Push an IMU sample into the tracker.
407 *
408 * There must be a single producer thread pushing samples.
409 * Samples must have monotonically increasing timestamps.
···413vit_result_t vit_tracker_push_imu_sample(vit_tracker_t *tracker, const vit_imu_sample_t *sample);
414415/*!
416- * @brief Push an image sample into the tracker.
417 *
418 * Same conditions as @ref push_imu_sample apply.
419 * When using N>1 cameras, the N frames must be pushed following @ref cam_index order.
···422vit_result_t vit_tracker_push_img_sample(vit_tracker_t *tracker, const vit_img_sample_t *sample);
423424/*!
425- * @brief Adds an inertial measurement unit calibration to the tracker. The tracker must not be started.
426 *
427- * Returns `VIT_ERROR_NOT_SUPPORTED` if the tracker doesn't offer the capability.
428 *
429- * @see vit_tracker_get_capabilities
430- * @see vit_tracker_capability_t
431 */
432vit_result_t vit_tracker_add_imu_calibration(vit_tracker_t *tracker, const vit_imu_calibration_t *calibration);
433434/*!
435- * @brief Adds a camera calibration to the tracker. The tracker must not be started.
436 *
437- * Returns `VIT_ERROR_NOT_SUPPORTED` if the tracker doesn't offer the capability.
438 *
439- * @see vit_tracker_get_capabilities
440- * @see vit_tracker_capability_t
441 */
442vit_result_t vit_tracker_add_camera_calibration(vit_tracker_t *tracker, const vit_camera_calibration_t *calibration);
443444/*!
445- * @brief Get the pose from the front of the tracking queue from the VIT tracker
446 *
447 * This function must be non-blocking and consumed by a single consummer.
448 *
···453vit_result_t vit_tracker_pop_pose(vit_tracker_t *tracker, vit_pose_t **out_pose);
454455/*!
456- * @brief Get the titles of the timestamps measured by the pose timings.
457 *
458- * Returns `VIT_ERROR_NOT_SUPPORTED` if the tracker doesn't offer the pose timing capability.
459 */
460vit_result_t vit_tracker_get_timing_titles(const vit_tracker_t *tracker, vit_tracker_timing_titles *out_titles);
461462/*!
463- * @brief Destroys a pose. All of the data, timing and features associated to it will be invalidated.
464 */
465void vit_pose_destroy(vit_pose_t *pose);
466467/*!
468- * @brief Gets the data form a given `vit_pose_t`.
469 *
470 * The data becomes invalid when the associated pose gets destroyed.
471 */
472vit_result_t vit_pose_get_data(const vit_pose_t *pose, vit_pose_data_t *out_data);
473474/*!
475- * @brief Gets the timing form a given `vit_pose_t`.
476 *
477 * The timing data becomes invalid when the associated pose gets destroyed.
478 */
479vit_result_t vit_pose_get_timing(const vit_pose_t *pose, vit_pose_timing_t *out_timing);
480481/*!
482- * @brief Gets the features form a given `vit_pose_t`.
483 *
484 * The features data becomes invalid when the associated pose gets destroyed.
485 */
···24#include <stdint.h>
2526//! 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···57 VIT_ERROR_ALLOCATION_FAILURE = -3,
5859 /*!
60+ * The operation requires an extension that is not supported.
61 */
62 VIT_ERROR_NOT_SUPPORTED = -4,
6364 /*!
65+ * The operation requires an extension that is not enabled.
66 */
67 VIT_ERROR_NOT_ENABLED = -5,
68} vit_result_t;
···96} vit_camera_distortion_t;
9798/*!
99+ * Optional functionality a tracker can provide.
100 */
101+typedef 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;
113114/*!
115+ * Set of extensions. Field order matches enumerators in @ref vit_tracker_extension.
116 */
117+typedef 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;
123124/*!
125+ * Visual-Inertial Tracking interface, opaque type.
126 */
127struct vit_tracker;
128typedef struct vit_tracker vit_tracker_t;
129130/*!
131+ * Pose interface, opaque type.
132 */
133struct vit_pose;
134typedef struct vit_pose vit_pose_t;
135136/*!
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
···142} vit_tracker_timing_titles;
143144/*!
145+ * Parameters for creating the system pipeline.
146 */
147typedef struct vit_config {
148 //! Path to a implementation-specific config file. If null, use defaults.
···159} vit_config_t;
160161/*!
162+ * IMU sample type feed into VIT tracker
163 */
164typedef struct vit_imu_sample {
165 //! In nanoseconds
···181} vit_mask_t;
182183/*!
184+ * Image sample type feed into VIT tracker
185 *
186 * Can easily be converted into an OpenCV Matrix for processing.
187 */
···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);
311+typedef vit_result_t (*PFN_vit_tracker_get_supported_extensions)(const vit_tracker_t *tracker,
312+ vit_tracker_extension_set_t *out_exts);
313+typedef vit_result_t (*PFN_vit_tracker_get_enabled_extensions)(const vit_tracker_t *tracker,
314+ vit_tracker_extension_set_t *out_exts);
315+typedef 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);
···342#ifdef VIT_INTERFACE_IMPLEMENTATION
343344/*!
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);
348349/*!
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);
353354/*!
355+ * Destroys the VIT tracker and free all resources allocated.
356 */
357void vit_tracker_destroy(vit_tracker_t *tracker);
358359/*!
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);
364365/*!
366+ * Returns a set with the extensions supported by this tracker.
367 *
368+ * @see vit_tracker_extension_t
369 */
370371+vit_result_t vit_tracker_get_supported_extensions(const vit_tracker_t *tracker, vit_tracker_extension_set_t *out_exts);
372373/*!
374+ * Returns a set with the extensions enabled in this tracker.
375 *
376+ * @see vit_tracker_extension_t
377 */
378+379+vit_result_t vit_tracker_get_enabled_extensions(const vit_tracker_t *tracker, vit_tracker_extension_set_t *out_exts);
380381/*!
382+ * Enables or disables a tracker extension.
383 *
384+ * @see vit_tracker_extension_t
00385 */
386+vit_result_t vit_tracker_enable_extension(vit_tracker_t *tracker, vit_tracker_extension_t ext, bool value);
387388/*!
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);
394395/*!
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);
399400/*!
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);
404405/*!
406+ * Verifies if the tracker is running.
407 */
408vit_result_t vit_tracker_is_running(const vit_tracker_t *tracker, bool *out_bool);
409410/*!
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.
···418vit_result_t vit_tracker_push_imu_sample(vit_tracker_t *tracker, const vit_imu_sample_t *sample);
419420/*!
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.
···427vit_result_t vit_tracker_push_img_sample(vit_tracker_t *tracker, const vit_img_sample_t *sample);
428429/*!
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);
438439/*!
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);
448449/*!
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 *
···458vit_result_t vit_tracker_pop_pose(vit_tracker_t *tracker, vit_pose_t **out_pose);
459460/*!
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);
466467/*!
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);
471472/*!
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);
478479/*!
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);
485486/*!
487+ * Gets the features form a given `vit_pose_t`.
488 *
489 * The features data becomes invalid when the associated pose gets destroyed.
490 */
+12-21
src/xrt/auxiliary/tracking/t_tracker_slam.cpp
···257 struct xrt_tracked_slam base = {};
258 struct xrt_frame_node node = {}; //!< Will be called on destruction
259 struct t_vit_bundle vit; //!< VIT system function pointers
260- enum vit_tracker_pose_capability caps; //!< VIT tracker bitfield capabilities
261 struct vit_tracker *tracker; //!< Pointer to the tracker created by the loaded VIT system;
262263 struct xrt_slam_sinks sinks = {}; //!< Pointers to the sinks below
···416 u_var_button &btn = t->timing.enable_btn;
417 bool e = !t->timing.enabled;
418 snprintf(btn.label, sizeof(btn.label), "%s", msg[e]);
419- vit_result_t vres =
420- t->vit.tracker_set_pose_capabilities(t->tracker, VIT_TRACKER_POSE_CAPABILITY_TIMING, e);
421 if (vres != VIT_SUCCESS) {
422- U_LOG_IFL_E(t->log_level, "Failed to set tracker timing capability");
423 return;
424 }
425 t->timing.enabled = e;
426 };
427 t.timing.enable_btn.cb = cb;
428- t.timing.enable_btn.disabled = (t.caps & VIT_TRACKER_POSE_CAPABILITY_TIMING) == 0;
429 t.timing.enable_btn.ptr = &t;
430 u_var_add_button(&t, &t.timing.enable_btn, msg[t.timing.enabled]);
431···433 t.timing.columns = {"sampled", "received_by_monado"};
434435 // Only fill the timing columns if the tracker supports pose timing
436- if ((t.caps & VIT_TRACKER_POSE_CAPABILITY_TIMING) != 0) {
437 vit_tracker_timing_titles titles = {};
438 vit_result_t vres = t.vit.tracker_get_timing_titles(t.tracker, &titles);
439 if (vres != VIT_SUCCESS) {
···537 u_var_button &btn = t->features.enable_btn;
538 bool e = !t->features.enabled;
539 snprintf(btn.label, sizeof(btn.label), "%s", msg[e]);
540- vit_result_t vres =
541- t->vit.tracker_set_pose_capabilities(t->tracker, VIT_TRACKER_POSE_CAPABILITY_FEATURES, e);
542 if (vres != VIT_SUCCESS) {
543- U_LOG_IFL_E(t->log_level, "Failed to set tracker features capability");
544 return;
545 }
546 t->features.enabled = e;
547 };
548 t.features.enable_btn.cb = cb;
549- t.features.enable_btn.disabled = (t.caps & VIT_TRACKER_POSE_CAPABILITY_FEATURES) == 0;
550 t.features.enable_btn.ptr = &t;
551 u_var_add_button(&t, &t.features.enable_btn, msg[t.features.enabled]);
552···1193static void
1194send_calibration(const TrackerSlam &t, const t_slam_calibration &c)
1195{
1196- vit_tracker_capability_t caps;
1197- vit_result_t vres = t.vit.tracker_get_capabilities(t.tracker, &caps);
1198- if (vres != VIT_SUCCESS) {
1199- SLAM_ERROR("Failed to get VIT tracker capabilities");
1200- return;
1201- }
1202-1203 // Try to send camera calibration data to the SLAM system
1204- if ((caps & VIT_TRACKER_CAPABILITY_CAMERA_CALIBRATION) != 0) {
1205 for (int i = 0; i < c.cam_count; i++) {
1206 SLAM_INFO("Sending Camera %d calibration from Monado", i);
1207 add_camera_calibration(t, &c.cams[i], i);
···1211 }
12121213 // Try to send IMU calibration data to the SLAM system
1214- if ((caps & VIT_TRACKER_CAPABILITY_IMU_CALIBRATION) != 0) {
1215 SLAM_INFO("Sending IMU calibration from Monado");
1216 add_imu_calibration(t, &c.imu);
1217 } else {
···1561 return -1;
1562 }
15631564- vres = t.vit.tracker_get_pose_capabilities(t.tracker, &t.caps);
1565 if (vres != VIT_SUCCESS) {
1566- SLAM_ERROR("Failed to get VIT tracker pose capabilities (%d)", vres);
1567 return -1;
1568 }
1569
···257 struct xrt_tracked_slam base = {};
258 struct xrt_frame_node node = {}; //!< Will be called on destruction
259 struct t_vit_bundle vit; //!< VIT system function pointers
260+ struct vit_tracker_extension_set exts; //!< VIT tracker supported extensions
261 struct vit_tracker *tracker; //!< Pointer to the tracker created by the loaded VIT system;
262263 struct xrt_slam_sinks sinks = {}; //!< Pointers to the sinks below
···416 u_var_button &btn = t->timing.enable_btn;
417 bool e = !t->timing.enabled;
418 snprintf(btn.label, sizeof(btn.label), "%s", msg[e]);
419+ vit_result_t vres = t->vit.tracker_enable_extension(t->tracker, VIT_TRACKER_EXTENSION_POSE_TIMING, e);
0420 if (vres != VIT_SUCCESS) {
421+ U_LOG_IFL_E(t->log_level, "Failed to set tracker timing extension");
422 return;
423 }
424 t->timing.enabled = e;
425 };
426 t.timing.enable_btn.cb = cb;
427+ t.timing.enable_btn.disabled = !t.exts.has_pose_timing;
428 t.timing.enable_btn.ptr = &t;
429 u_var_add_button(&t, &t.timing.enable_btn, msg[t.timing.enabled]);
430···432 t.timing.columns = {"sampled", "received_by_monado"};
433434 // Only fill the timing columns if the tracker supports pose timing
435+ if (t.exts.has_pose_timing) {
436 vit_tracker_timing_titles titles = {};
437 vit_result_t vres = t.vit.tracker_get_timing_titles(t.tracker, &titles);
438 if (vres != VIT_SUCCESS) {
···536 u_var_button &btn = t->features.enable_btn;
537 bool e = !t->features.enabled;
538 snprintf(btn.label, sizeof(btn.label), "%s", msg[e]);
539+ vit_result_t vres = t->vit.tracker_enable_extension(t->tracker, VIT_TRACKER_EXTENSION_POSE_FEATURES, e);
0540 if (vres != VIT_SUCCESS) {
541+ U_LOG_IFL_E(t->log_level, "Failed to set tracker features extension");
542 return;
543 }
544 t->features.enabled = e;
545 };
546 t.features.enable_btn.cb = cb;
547+ t.features.enable_btn.disabled = !t.exts.has_pose_features;
548 t.features.enable_btn.ptr = &t;
549 u_var_add_button(&t, &t.features.enable_btn, msg[t.features.enabled]);
550···1191static void
1192send_calibration(const TrackerSlam &t, const t_slam_calibration &c)
1193{
00000001194 // Try to send camera calibration data to the SLAM system
1195+ if (t.exts.has_add_camera_calibration) {
1196 for (int i = 0; i < c.cam_count; i++) {
1197 SLAM_INFO("Sending Camera %d calibration from Monado", i);
1198 add_camera_calibration(t, &c.cams[i], i);
···1202 }
12031204 // Try to send IMU calibration data to the SLAM system
1205+ if (t.exts.has_add_imu_calibration) {
1206 SLAM_INFO("Sending IMU calibration from Monado");
1207 add_imu_calibration(t, &c.imu);
1208 } else {
···1552 return -1;
1553 }
15541555+ vres = t.vit.tracker_get_supported_extensions(t.tracker, &t.exts);
1556 if (vres != VIT_SUCCESS) {
1557+ SLAM_ERROR("Failed to get VIT tracker supported extensions (%d)", vres);
1558 return -1;
1559 }
1560