1use std::{
2 convert::Infallible,
3 fmt::{Debug, Display},
4 time::Duration,
5};
6
7pub use glam;
8pub use wide;
9
10mod fk;
11mod path;
12mod q;
13mod traj;
14mod validator;
15mod validator_dynamic;
16
17pub use fk::{
18 BoxFK, DHChain, DHJoint, DynamicDHChain, DynamicHPChain, DynamicURDFChain, FKChain, FKScalar,
19 FPDispatch, HPChain, HPJoint, PrismaticFK, TransformedFK, URDFBuildError, URDFChain,
20 URDFJoint, URDFJointType, compose_fixed_joints, compose_fixed_joints_f64,
21};
22pub use path::{RobotPath, SRobotPath};
23pub use q::{RobotQ, SRobotQ, robotq, SRobotQLike};
24pub use traj::{RobotTraj, SRobotTraj};
25pub use validator::{JointValidator, Validator, ValidatorAnd, ValidatorNot, ValidatorOr, MaybeValidator, ValidatorContext, Leaf, FromFlattened};
26pub use validator_dynamic::DynamicJointValidator;
27
28use crate::validator::ValidatorRet;
29
30#[derive(Debug, Clone, thiserror::Error)]
31pub enum DekeError {
32 #[error("Expected {expected} joints, but found {found}")]
33 ShapeMismatch { expected: usize, found: usize },
34 #[error("Path has {0} waypoints, needs at least 2")]
35 PathTooShort(usize),
36 #[error("Joints contain non-finite values")]
37 JointsNonFinite,
38 #[error("Self-collision detected between joints {0} and {1}")]
39 SelfCollision(i16, i16),
40 #[error("Environment collision detected between joint {0} and object {1}")]
41 EnvironmentCollision(i16, i16),
42 #[error("Joints exceed their limits")]
43 ExceedJointLimits,
44 #[error("Out of iterations")]
45 OutOfIterations,
46 #[error("Locked-prefix constraint violated at waypoint {waypoint} joint {joint}")]
47 LockedPrefixViolation { waypoint: u32, joint: u8 },
48 #[error("Boundary conditions not parallel to path tangent (residual {0})")]
49 BoundaryInfeasible(f32),
50 #[error("Path has consecutive zero-length segments")]
51 DuplicateWaypoints,
52 #[error("Retimer failed: {0}")]
53 RetimerFailed(String),
54 #[error(
55 "Retimer output exceeds {limit_type} limit on dof {dof}: observed {observed_value}, limit {limit_value} (dt_in={dt_in:?})"
56 )]
57 ExceedsDynamicsLimits {
58 dt_in: Duration,
59 limit_type: &'static str,
60 dof: u8,
61 limit_value: f64,
62 observed_value: f64,
63 },
64 #[error(
65 "URDF joint at index {index} has an unexpected type: expected {expected}, found {found}"
66 )]
67 URDFJointTypeMismatch {
68 index: usize,
69 expected: &'static str,
70 found: &'static str,
71 },
72 #[error("URDFChain<{expected}> requires {expected} revolute joints, found {found}")]
73 URDFRevoluteCountMismatch { expected: usize, found: usize },
74 #[error("Super error")]
75 SuperError,
76}
77
78impl From<Infallible> for DekeError {
79 fn from(_: Infallible) -> Self {
80 unreachable!()
81 }
82}
83
84pub type DekeResult<T> = Result<T, DekeError>;
85
86pub trait Planner<const N: usize, F: fk::FKScalar = f32, R: ValidatorRet = ()>: Sized + Clone + Debug + Send + Sync + 'static {
87 type Diagnostic: Display + Send + Sync;
88 type Config;
89
90 fn plan<
91 E: Into<DekeError>,
92 A: SRobotQLike<N, E, F>,
93 B: SRobotQLike<N, E, F>,
94 V: Validator<N, R, F>,
95 >(
96 &self,
97 config: &Self::Config,
98 start: A,
99 goal: B,
100 validator: &V,
101 ctx: &V::Context<'_>,
102 ) -> (DekeResult<SRobotPath<N, F>>, Self::Diagnostic);
103}
104
105pub trait Retimer<const N: usize, F: fk::FKScalar = f32, R: ValidatorRet = ()>: Sized + Clone + Debug + Send + Sync + 'static {
106 type Diagnostic: Display + Send + Sync;
107 type Constraints;
108
109 fn retime<V: Validator<N, R, F>>(
110 &self,
111 constraints: &Self::Constraints,
112 path: &SRobotPath<N, F>,
113 fk: &impl FKChain<N, F>,
114 validator: &V,
115 ctx: &V::Context<'_>,
116 ) -> (DekeResult<SRobotTraj<N, F>>, Self::Diagnostic);
117}