Skip to main content

nabled_kinematics/
lib.rs

1//! Robot kinematics: forward kinematics, Jacobians, and inverse kinematics.
2
3#![allow(
4    clippy::missing_errors_doc,
5    clippy::missing_panics_doc,
6    clippy::many_single_char_names,
7    clippy::unreadable_literal,
8    clippy::needless_range_loop
9)]
10
11use nabled_core::errors::{IntoNabledError, NabledError, ShapeError};
12
13pub mod chain;
14pub mod error;
15pub mod fk;
16pub mod ik;
17pub mod jacobian;
18pub mod tree;
19
20pub use chain::{ChainSpec, DhConvention, JointLimits, JointType};
21pub use error::KinematicsError;
22pub use ik::{
23    IkConfig, IkResult, IkWorkspace, inverse_kinematics_dls, inverse_kinematics_dls_into,
24    inverse_kinematics_dls_with_limits, inverse_kinematics_tree_dls,
25    inverse_kinematics_tree_dls_with_limits, pose_error, pose_error_into,
26};
27
28impl IntoNabledError for KinematicsError {
29    fn into_nabled_error(self) -> NabledError {
30        match self {
31            KinematicsError::EmptyChain => NabledError::Shape(ShapeError::EmptyInput),
32            KinematicsError::DimensionMismatch => NabledError::Shape(ShapeError::DimensionMismatch),
33            KinematicsError::InvalidInput(message) => NabledError::InvalidInput(message),
34            KinematicsError::ConvergenceFailed => NabledError::ConvergenceFailed,
35            KinematicsError::NumericalInstability => NabledError::NumericalInstability,
36            KinematicsError::JointLimitViolation(joint) => {
37                NabledError::InvalidInput(format!("joint limit violated at joint {joint}"))
38            }
39        }
40    }
41}
42
43#[cfg(test)]
44mod error_mapping {
45    use nabled_core::errors::{IntoNabledError, NabledError, ShapeError};
46
47    use crate::KinematicsError;
48
49    #[test]
50    fn into_nabled_error_covers_all_variants() {
51        assert!(matches!(
52            KinematicsError::EmptyChain.into_nabled_error(),
53            NabledError::Shape(ShapeError::EmptyInput)
54        ));
55        assert!(matches!(
56            KinematicsError::DimensionMismatch.into_nabled_error(),
57            NabledError::Shape(ShapeError::DimensionMismatch)
58        ));
59        assert!(matches!(
60            KinematicsError::InvalidInput("x".into()).into_nabled_error(),
61            NabledError::InvalidInput(message) if message == "x"
62        ));
63        assert!(matches!(
64            KinematicsError::ConvergenceFailed.into_nabled_error(),
65            NabledError::ConvergenceFailed
66        ));
67        assert!(matches!(
68            KinematicsError::NumericalInstability.into_nabled_error(),
69            NabledError::NumericalInstability
70        ));
71        assert!(matches!(
72            KinematicsError::JointLimitViolation(0).into_nabled_error(),
73            NabledError::InvalidInput(message) if message.contains("joint 0")
74        ));
75    }
76}