Skip to main content

deke_linear/
error.rs

1use deke_types::DekeError;
2
3/// Errors surfaced by the constant-speed Cartesian follower.
4#[derive(Debug, thiserror::Error)]
5pub enum LinearError {
6    #[error("need at least 2 poses to define a path, got {0}")]
7    TooFewPoses(usize),
8    #[error("run {run}: every vertex coincides — nothing to follow")]
9    DegenerateRun { run: usize },
10    #[error("run {run}: Cartesian pose at arc length {s:.4} m has no reachable IK solution")]
11    Unreachable { run: usize, s: f64 },
12    #[error(
13        "run {run}: every reachable configuration at arc length {s:.4} m is rejected by the validator (obstructed)"
14    )]
15    Obstructed { run: usize, s: f64 },
16    #[error("run {run}: could not route a continuous joint track through the IK candidates")]
17    NoContinuousTrack { run: usize },
18    #[error(
19        "retimer stalled on run {run} near arc length {s:.4} m (path likely passes through a singularity)"
20    )]
21    Stalled { run: usize, s: f64 },
22    #[error(
23        "run {run}: holding constant TCP speed forbids the interior dip at arc length {s:.4} m (max feasible {feasible_speed:.4} m/s < commanded {commanded:.4} m/s)"
24    )]
25    SpeedDipRequired {
26        run: usize,
27        s: f64,
28        feasible_speed: f64,
29        commanded: f64,
30    },
31    #[error(transparent)]
32    Deke(#[from] DekeError),
33}
34
35impl From<LinearError> for DekeError {
36    fn from(e: LinearError) -> Self {
37        match e {
38            LinearError::Deke(d) => d,
39            other => DekeError::RetimerFailed(other.to_string()),
40        }
41    }
42}