1use crate::{DekeError, DekeResult, JointValidator, SRobotQ, SRobotQLike, Validator};
2
3macro_rules! dynamic_joint_new {
4 ($lower:ident, $upper:ident, $($variant:ident $n:literal),+) => {
5 match $lower.len() {
6 $($n => {
7 let lo: [f32; $n] = $lower.as_slice().try_into().map_err(|_| DekeError::ShapeMismatch { expected: $n, found: $lower.len() })?;
8 let hi: [f32; $n] = $upper.as_slice().try_into().map_err(|_| DekeError::ShapeMismatch { expected: $n, found: $upper.len() })?;
9 Ok(DynamicJointValidator::$variant(JointValidator::new(SRobotQ(lo), SRobotQ(hi))))
10 }),+,
11 _ => Err(DekeError::ShapeMismatch { expected: 8, found: $lower.len() }),
12 }
13 };
14}
15
16#[derive(Debug, Clone)]
17pub enum DynamicJointValidator {
18 J1(JointValidator<1>),
19 J2(JointValidator<2>),
20 J3(JointValidator<3>),
21 J4(JointValidator<4>),
22 J5(JointValidator<5>),
23 J6(JointValidator<6>),
24 J7(JointValidator<7>),
25 J8(JointValidator<8>),
26}
27
28impl DynamicJointValidator {
29 pub fn try_new(lower: Vec<f32>, upper: Vec<f32>) -> DekeResult<Self> {
30 if lower.len() != upper.len() {
31 return Err(DekeError::ShapeMismatch {
32 expected: lower.len(),
33 found: upper.len(),
34 });
35 }
36 dynamic_joint_new!(lower, upper, J1 1, J2 2, J3 3, J4 4, J5 5, J6 6, J7 7, J8 8)
37 }
38
39 pub fn dof(&self) -> usize {
40 match self {
41 Self::J1(_) => 1,
42 Self::J2(_) => 2,
43 Self::J3(_) => 3,
44 Self::J4(_) => 4,
45 Self::J5(_) => 5,
46 Self::J6(_) => 6,
47 Self::J7(_) => 7,
48 Self::J8(_) => 8,
49 }
50 }
51
52 pub fn validate_dyn(&self, q: &[f32]) -> DekeResult<()> {
53 match self {
54 Self::J1(v) => {
55 let arr: &[f32; 1] = q.try_into().map_err(|_| DekeError::ShapeMismatch {
56 expected: 1,
57 found: q.len(),
58 })?;
59 v.validate(SRobotQ(*arr), &())
60 }
61 Self::J2(v) => {
62 let arr: &[f32; 2] = q.try_into().map_err(|_| DekeError::ShapeMismatch {
63 expected: 2,
64 found: q.len(),
65 })?;
66 v.validate(SRobotQ(*arr), &())
67 }
68 Self::J3(v) => {
69 let arr: &[f32; 3] = q.try_into().map_err(|_| DekeError::ShapeMismatch {
70 expected: 3,
71 found: q.len(),
72 })?;
73 v.validate(SRobotQ(*arr), &())
74 }
75 Self::J4(v) => {
76 let arr: &[f32; 4] = q.try_into().map_err(|_| DekeError::ShapeMismatch {
77 expected: 4,
78 found: q.len(),
79 })?;
80 v.validate(SRobotQ(*arr), &())
81 }
82 Self::J5(v) => {
83 let arr: &[f32; 5] = q.try_into().map_err(|_| DekeError::ShapeMismatch {
84 expected: 5,
85 found: q.len(),
86 })?;
87 v.validate(SRobotQ(*arr), &())
88 }
89 Self::J6(v) => {
90 let arr: &[f32; 6] = q.try_into().map_err(|_| DekeError::ShapeMismatch {
91 expected: 6,
92 found: q.len(),
93 })?;
94 v.validate(SRobotQ(*arr), &())
95 }
96 Self::J7(v) => {
97 let arr: &[f32; 7] = q.try_into().map_err(|_| DekeError::ShapeMismatch {
98 expected: 7,
99 found: q.len(),
100 })?;
101 v.validate(SRobotQ(*arr), &())
102 }
103 Self::J8(v) => {
104 let arr: &[f32; 8] = q.try_into().map_err(|_| DekeError::ShapeMismatch {
105 expected: 8,
106 found: q.len(),
107 })?;
108 v.validate(SRobotQ(*arr), &())
109 }
110 }
111 }
112
113 pub fn validate_motion_dyn(&self, qs: &[&[f32]]) -> DekeResult<()> {
114 for q in qs {
115 self.validate_dyn(q)?;
116 }
117 Ok(())
118 }
119}
120
121macro_rules! impl_dynamic_joint {
122 ($($n:literal $variant:ident),+) => {
123 $(
124 impl Validator<$n> for DynamicJointValidator {
125 type Context<'ctx> = ();
126
127 fn validate<'ctx, E: Into<DekeError>, A: SRobotQLike<$n, E>>(
128 &self,
129 q: A,
130 ctx: &Self::Context<'ctx>,
131 ) -> DekeResult<()> {
132 match self {
133 Self::$variant(v) => v.validate(q, ctx),
134 _ => Err(DekeError::ShapeMismatch {
135 expected: self.dof(),
136 found: $n,
137 }),
138 }
139 }
140
141 fn validate_motion<'ctx>(
142 &self,
143 qs: &[SRobotQ<$n>],
144 ctx: &Self::Context<'ctx>,
145 ) -> DekeResult<()> {
146 match self {
147 Self::$variant(v) => v.validate_motion(qs, ctx),
148 _ => Err(DekeError::ShapeMismatch {
149 expected: self.dof(),
150 found: $n,
151 }),
152 }
153 }
154 }
155
156 impl From<JointValidator<$n>> for DynamicJointValidator {
157 fn from(v: JointValidator<$n>) -> Self {
158 Self::$variant(v)
159 }
160 }
161 )+
162 };
163}
164
165impl_dynamic_joint!(1 J1, 2 J2, 3 J3, 4 J4, 5 J5, 6 J6, 7 J7, 8 J8);
166
167impl DynamicJointValidator {
168 pub fn from_validator(v: impl Into<Self>) -> Self {
169 v.into()
170 }
171}