1use std::fmt::Display;
8
9use crate::{motion::SpatialRotation, vector3d::Vector3D};
10use nalgebra::{IsometryMatrix3, Matrix3, Matrix6, Translation3};
11
12#[derive(Clone, Debug, Copy, PartialEq, Default)]
17pub struct SE3(pub(crate) IsometryMatrix3<f64>);
18
19impl SE3 {
20 #[must_use]
22 pub fn new(translation: Vector3D, axis_angle: Vector3D) -> Self {
23 let rotation = SpatialRotation::from_axis_angle(&axis_angle, axis_angle.norm());
24 SE3::from_parts(
25 Vector3D::new(translation.0.x, translation.0.y, translation.0.z),
26 rotation,
27 )
28 }
29
30 #[must_use]
32 pub fn from_parts(translation: Vector3D, rotation: SpatialRotation) -> Self {
33 SE3(IsometryMatrix3::from_parts(
34 Translation3::from(translation.0),
35 rotation.0,
36 ))
37 }
38
39 #[must_use]
41 pub fn identity() -> Self {
42 SE3(IsometryMatrix3::identity())
43 }
44
45 #[must_use]
47 pub fn inverse(&self) -> Self {
48 SE3(self.0.inverse())
49 }
50
51 #[must_use]
53 pub fn translation(&self) -> Vector3D {
54 Vector3D(self.0.translation.vector)
55 }
56
57 #[must_use]
59 pub fn rotation(&self) -> SpatialRotation {
60 SpatialRotation(self.0.rotation)
61 }
62
63 pub fn action_matrix(&self) -> Matrix6<f64> {
69 let r = self.rotation();
72 let r = r.0.matrix();
73 let t = self.translation().0;
74 let mut action_matrix = Matrix6::zeros();
75 action_matrix
76 .fixed_view_mut::<3, 3>(0, 0)
77 .copy_from(&r.transpose());
78 action_matrix
79 .fixed_view_mut::<3, 3>(3, 3)
80 .copy_from(&r.transpose());
81
82 let skew_t = Matrix3::new(0.0, -t[2], t[1], t[2], 0.0, -t[0], -t[1], t[0], 0.0);
84
85 action_matrix
86 .fixed_view_mut::<3, 3>(3, 0)
87 .copy_from(&(skew_t * r).transpose());
88 action_matrix
89 }
90
91 pub fn dual_matrix(&self) -> Matrix6<f64> {
97 let r = self.rotation();
100 let r = r.0.matrix();
101 let t = self.translation().0;
102 let mut action_matrix = Matrix6::zeros();
103 action_matrix
104 .fixed_view_mut::<3, 3>(0, 0)
105 .copy_from(&r.transpose());
106 action_matrix
107 .fixed_view_mut::<3, 3>(3, 3)
108 .copy_from(&r.transpose());
109
110 let skew_t = Matrix3::new(0.0, -t[2], t[1], t[2], 0.0, -t[0], -t[1], t[0], 0.0);
112
113 action_matrix
114 .fixed_view_mut::<3, 3>(0, 3)
115 .copy_from(&(skew_t * r).transpose());
116 action_matrix
117 }
118
119 pub fn inv_matrix(&self) -> Matrix6<f64> {
121 let r = self.rotation().0;
124 let r_inv = r.matrix();
125 let t = self.translation().0;
126
127 let mut inv_matrix = nalgebra::Matrix6::zeros();
128 inv_matrix.fixed_view_mut::<3, 3>(0, 0).copy_from(r_inv);
129 inv_matrix.fixed_view_mut::<3, 3>(3, 3).copy_from(r_inv);
130
131 let skew_t = Matrix3::new(0.0, -t[2], t[1], t[2], 0.0, -t[0], -t[1], t[0], 0.0);
133
134 inv_matrix
135 .fixed_view_mut::<3, 3>(3, 0)
136 .copy_from(&(-skew_t.transpose() * r_inv));
137 inv_matrix
138 }
139}
140
141impl std::ops::Mul for SE3 {
142 type Output = SE3;
143
144 fn mul(self, rhs: Self) -> Self::Output {
145 SE3(self.0 * rhs.0)
146 }
147}
148
149impl std::ops::Mul<&SE3> for &SE3 {
150 type Output = SE3;
151
152 fn mul(self, rhs: &SE3) -> Self::Output {
153 SE3(self.0 * rhs.0)
154 }
155}
156
157impl std::ops::Mul<SE3> for &SE3 {
158 type Output = SE3;
159
160 fn mul(self, rhs: SE3) -> Self::Output {
161 SE3(self.0 * rhs.0)
162 }
163}
164
165impl std::ops::Mul<&SE3> for SE3 {
166 type Output = SE3;
167
168 fn mul(self, rhs: &SE3) -> Self::Output {
169 SE3(self.0 * rhs.0)
170 }
171}
172
173impl Display for SE3 {
174 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
175 let r = self.0.rotation.matrix();
176
177 writeln!(f, "SE3: R=┌ ┐ t=┌ ┐")?;
178 for i in 0..3 {
179 writeln!(
180 f,
181 " │ {:>+8.5} {:>+8.5} {:>+8.5} │ │ {:>+8.5} │",
182 r[(i, 0)],
183 r[(i, 1)],
184 r[(i, 2)],
185 self.0.translation.vector[i]
186 )?;
187 }
188 writeln!(f, " └ ┘ └ ┘")?;
189 Ok(())
190 }
191}
192
193pub trait ActSE3 {
195 fn act(&self, se3: &SE3) -> Self;
197
198 fn act_inv(&self, se3: &SE3) -> Self;
200}
201
202impl SE3 {
203 pub fn act<T: ActSE3>(&self, obj: &T) -> T {
205 obj.act(self)
206 }
207
208 pub fn act_inv<T: ActSE3>(&self, obj: &T) -> T {
210 obj.act_inv(self)
211 }
212}