use kornia_3d::pose::Pose3d;
use crate::frame::Frame;
use crate::initialization::AlignedTrackingState;
use kornia_algebra::Vec3F64;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum TrackingStatus {
Tracked,
Skipped,
KeyframeAccepted,
}
#[derive(Debug, Clone)]
pub struct TrackingResult {
pub pose_world_to_cam: Pose3d,
pub status: TrackingStatus,
}
#[derive(Debug, Clone)]
pub(crate) struct SystemState {
pub pose_world_to_cam: Pose3d,
pub velocity: Option<Pose3d>,
pub velocity_world: Vec3F64,
pub last_frame_timestamp_sec: f64,
pub imu_initialized: bool,
pub imu_init_timestamp_sec: Option<f64>,
pub current_keyframe_idx: Option<usize>,
pub last_keyframe_idx: Option<usize>,
pub lost_since_sec: Option<f64>,
pub bootstrap_frame: Option<Frame>,
pub mode: SystemMode,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) enum SystemMode {
Bootstrap,
ImuInit,
Tracking,
}
impl SystemState {
pub fn new() -> Self {
Self {
pose_world_to_cam: Pose3d::IDENTITY,
velocity: None,
velocity_world: Vec3F64::ZERO,
current_keyframe_idx: None,
last_keyframe_idx: None,
lost_since_sec: None,
bootstrap_frame: None,
imu_initialized: false,
imu_init_timestamp_sec: None,
last_frame_timestamp_sec: 0.0,
mode: SystemMode::Bootstrap,
}
}
pub fn reset(&mut self) {
self.mode = SystemMode::Bootstrap;
self.current_keyframe_idx = None;
self.last_keyframe_idx = None;
self.velocity = None;
self.lost_since_sec = None;
self.bootstrap_frame = None;
self.imu_initialized = false;
self.imu_init_timestamp_sec = None;
self.velocity_world = Vec3F64::ZERO;
}
pub(crate) fn adopt_inertial_initialization(&mut self, aligned: Option<AlignedTrackingState>) {
if let Some(aligned) = aligned {
self.velocity_world = aligned.velocity_world;
self.pose_world_to_cam = aligned.pose_world_to_cam;
}
self.velocity = None;
self.imu_initialized = true;
}
}
impl Default for SystemState {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::SystemState;
use crate::initialization::AlignedTrackingState;
use kornia_3d::pose::Pose3d;
use kornia_algebra::Vec3F64;
#[test]
fn adopting_an_initialization_resumes_from_the_aligned_keyframe() {
let mut state = SystemState::new();
state.velocity = Some(Pose3d::IDENTITY);
let mut pose = Pose3d::IDENTITY;
pose.translation = Vec3F64::new(1.0, 2.0, 3.0);
state.adopt_inertial_initialization(Some(AlignedTrackingState {
pose_world_to_cam: pose,
velocity_world: Vec3F64::new(0.5, 0.0, 0.0),
}));
assert!(state.imu_initialized);
assert!(
state.velocity.is_none(),
"the visual motion model is dropped"
);
assert_eq!(state.pose_world_to_cam, pose);
assert_eq!(state.velocity_world, Vec3F64::new(0.5, 0.0, 0.0));
}
}