use crate::{BehaviorNode, Context, NodeStatus};
use async_trait::async_trait;
use serde::{Deserialize, Serialize};
use serde_json::Value;
macro_rules! stub_tick_success {
($msg:literal) => {{
tracing::debug!($msg);
Ok(NodeStatus::Success)
}};
}
#[derive(Debug)]
pub struct PlanPathNode {
#[allow(dead_code)]
target_position: Vec<f64>,
#[allow(dead_code)]
algorithm: String,
}
#[derive(Debug, Serialize, Deserialize)]
struct PlanPathConfig {
target_position: Vec<f64>,
#[serde(default = "default_algorithm")]
path_planning_algorithm: String,
}
fn default_algorithm() -> String {
"a_star".to_string()
}
impl PlanPathNode {
pub fn from_json(config: Value) -> anyhow::Result<Self> {
let cfg: PlanPathConfig = serde_json::from_value(config)?;
Ok(Self {
target_position: cfg.target_position,
algorithm: cfg.path_planning_algorithm,
})
}
}
#[async_trait]
impl BehaviorNode for PlanPathNode {
async fn tick(&mut self, _ctx: &Context) -> anyhow::Result<NodeStatus> {
tracing::debug!("PlanPathNode: planning path to {:?} (stub)", self.target_position);
Ok(NodeStatus::Success)
}
fn name(&self) -> &str {
"PlanPathNode"
}
}
#[derive(Debug)]
pub struct FollowPathNode {
#[allow(dead_code)] topic: String,
#[allow(dead_code)]
max_speed: f64,
#[allow(dead_code)]
turn_rate: f64,
}
#[derive(Debug, Serialize, Deserialize)]
struct FollowPathConfig {
#[serde(default = "default_motor_topic")]
topic: String,
#[serde(default = "default_max_speed")]
max_speed: f64,
#[serde(default = "default_turn_rate")]
turn_rate: f64,
}
fn default_motor_topic() -> String {
"/motor/cmd_vel".to_string()
}
fn default_max_speed() -> f64 {
1.0
}
fn default_turn_rate() -> f64 {
0.5
}
impl FollowPathNode {
pub fn from_json(config: Value) -> anyhow::Result<Self> {
let cfg: FollowPathConfig = serde_json::from_value(config)?;
Ok(Self {
topic: cfg.topic,
max_speed: cfg.max_speed,
turn_rate: cfg.turn_rate,
})
}
}
#[async_trait]
impl BehaviorNode for FollowPathNode {
async fn tick(&mut self, _ctx: &Context) -> anyhow::Result<NodeStatus> {
stub_tick_success!("FollowPathNode: following path (stub)")
}
fn name(&self) -> &str {
"FollowPathNode"
}
}
#[derive(Debug)]
pub struct CheckArrivalNode {
#[allow(dead_code)]
position_tolerance: f64,
#[allow(dead_code)]
angular_tolerance: f64,
}
#[derive(Debug, Serialize, Deserialize)]
struct CheckArrivalConfig {
position_tolerance: f64,
angular_tolerance: f64,
}
impl CheckArrivalNode {
pub fn from_json(config: Value) -> anyhow::Result<Self> {
let cfg: CheckArrivalConfig = serde_json::from_value(config)?;
Ok(Self {
position_tolerance: cfg.position_tolerance,
angular_tolerance: cfg.angular_tolerance,
})
}
}
#[async_trait]
impl BehaviorNode for CheckArrivalNode {
async fn tick(&mut self, _ctx: &Context) -> anyhow::Result<NodeStatus> {
stub_tick_success!("CheckArrivalNode: checking arrival (stub)")
}
fn name(&self) -> &str {
"CheckArrivalNode"
}
}