use super::perception::Pose;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct NavigationGoal {
pub timestamp: u64,
pub goal_id: String,
pub target: Pose,
#[serde(skip_serializing_if = "Option::is_none")]
pub max_linear_velocity: Option<f32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub max_angular_velocity: Option<f32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub position_tolerance: Option<f32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub orientation_tolerance: Option<f32>,
}
impl NavigationGoal {
pub fn new_2d(goal_id: String, x: f32, y: f32, yaw: f32) -> Self {
Self {
timestamp: crate::prelude::now_micros(),
goal_id,
target: Pose::new_2d(x, y, yaw),
max_linear_velocity: None,
max_angular_velocity: None,
position_tolerance: None,
orientation_tolerance: None,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Path {
pub timestamp: u64,
pub waypoints: Vec<Waypoint>,
pub total_length: f32,
#[serde(skip_serializing_if = "Option::is_none")]
pub estimated_time: Option<f32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub frame_id: Option<String>,
}
impl Path {
pub fn empty() -> Self {
Self {
timestamp: crate::prelude::now_micros(),
waypoints: Vec::new(),
total_length: 0.0,
estimated_time: None,
frame_id: None,
}
}
pub fn is_empty(&self) -> bool {
self.waypoints.is_empty()
}
pub fn len(&self) -> usize {
self.waypoints.len()
}
pub fn calculate_length(&mut self) {
let mut length = 0.0;
for i in 1..self.waypoints.len() {
let prev = &self.waypoints[i - 1];
let curr = &self.waypoints[i];
let dx = curr.pose.position[0] - prev.pose.position[0];
let dy = curr.pose.position[1] - prev.pose.position[1];
let dz = curr.pose.position[2] - prev.pose.position[2];
length += (dx * dx + dy * dy + dz * dz).sqrt();
}
self.total_length = length;
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Waypoint {
pub pose: Pose,
#[serde(skip_serializing_if = "Option::is_none")]
pub velocity: Option<f32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub distance_along_path: Option<f32>,
}
impl Waypoint {
pub fn new_2d(x: f32, y: f32, yaw: f32) -> Self {
Self {
pose: Pose::new_2d(x, y, yaw),
velocity: None,
distance_along_path: None,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct NavigationStatus {
pub timestamp: u64,
pub goal_id: String,
pub state: NavigationState,
pub distance_remaining: f32,
#[serde(skip_serializing_if = "Option::is_none")]
pub time_remaining: Option<f32>,
pub progress: f32,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum NavigationState {
Planning,
Moving,
Succeeded,
Failed,
Waiting,
Recovering,
}