1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
//! Constant-TCP-speed Cartesian polyline following for serial manipulators.
//!
//! Where the `deke-topp*` retimers are time-optimal (maximise speed under caps),
//! `deke-linear` holds a *constant* TCP travel speed — the requirement for
//! welding and similar process motions — and degrades gracefully near
//! singularities. It is a CNC-style constant-feedrate interpolator in three
//! stages:
//!
//! - **Stage A** ([`path`]) conditions the raw polyline into smooth, arc-length
//! parameterised [`CartesianRun`]s, splitting at sharp corners.
//! - **Stage B** ([`planner`]) resolves each run to a continuous joint path by
//! analytic-IK branch tracking, steering away from singularities
//! ([`CartesianLinearPlanner`], implements [`deke_types::Planner`]).
//! - **Stage C** ([`retimer`]) holds the commanded speed wherever the joint
//! v/a/j limits allow and dips smoothly where they don't
//! ([`ConstantSpeedRetimer`], implements [`deke_types::Retimer`]).
//!
//! Each stage is a standalone, trait-conforming component; the caller drives
//! them. [`condition`] splits the polyline into runs, then for each run the
//! [`CartesianLinearPlanner`] resolves a joint path and the
//! [`ConstantSpeedRetimer`] times it:
//!
//! ```no_run
//! # use deke_linear::*;
//! # use deke_types::{Planner, Retimer};
//! # use deke_types::glam::DAffine3;
//! # fn run<FK: deke_types::ContinuousFKChain<6, f64> + deke_types::IkSolver<6, f64>>(
//! # fk: &FK, poses: &[DAffine3], cond: &PathConditioning,
//! # opts: &PlannerOptions<6>, cons: &LinearConstraints<6>) {
//! let planner = CartesianLinearPlanner::new(fk);
//! let retimer = ConstantSpeedRetimer::new(fk);
//! // `NoopValidator` plans without obstacle checks; pass a real `Validator`
//! // (and its context) to route the arm around obstacles inside the planner.
//! for run in condition(poses, cond).unwrap() {
//! let (path, _) = planner.plan::<deke_types::DekeError, _>(opts, &run, &NoopValidator::<6>, &());
//! let (traj, _) = retimer.retime(cons, &path.unwrap(), &NoopValidator::<6>, &());
//! let _ = traj;
//! }
//! # }
//! ```
//!
//! For a symmetric welding torch, the [`RedundantLinearPlanner`] treats the free
//! tool-axis yaw as a DOF and resolves it globally to dodge singularities — and,
//! with a real `Validator`, obstacles.
pub use ;
pub use ;
pub use LinearError;
pub use ;
pub use CartesianLinearPlanner;
pub use ;
pub use ConstantSpeedRetimer;
pub use NoopValidator;