Robotics Library  0.7.0
TransformAddons.h
Go to the documentation of this file.
1 //
2 // Copyright (c) 2009, Markus Rickert
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are met:
7 //
8 // * Redistributions of source code must retain the above copyright notice,
9 // this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above copyright notice,
11 // this list of conditions and the following disclaimer in the documentation
12 // and/or other materials provided with the distribution.
13 //
14 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
18 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 // POSSIBILITY OF SUCH DAMAGE.
25 //
26 
27 #ifndef RL_MATH_TRANSFORMADDONS_H
28 #define RL_MATH_TRANSFORMADDONS_H
29 
30 template<typename Scalar, int Dim, int Mode, int Options>
31 inline
32 Scalar
33 distance(const Transform<Scalar, Dim, Mode, Options>& other, const Scalar& weight = 1) const
34 {
35  Quaternion<Scalar> q1(rotation());
36  Quaternion<Scalar> q2(other.rotation());
37 
38  return ::std::sqrt(
39  ::std::pow(other(0, 3) - (*this)(0, 3), 2) +
40  ::std::pow(other(1, 3) - (*this)(1, 3), 2) +
41  ::std::pow(other(2, 3) - (*this)(2, 3), 2) +
42  weight * ::std::pow(q1.angularDistance(q2), 2)
43  );
44 }
45 
54 template<typename Scalar, int Dim, int Mode, int Options>
55 inline
56 void
57 fromDelta(const Transform<Scalar, Dim, Mode, Options>& other, const Matrix<Scalar, 6, 1>& delta, const bool& useApproximation = false)
58 {
59  if (useApproximation)
60  {
61  (*this)(0, 0) = other(0, 0) - delta(5) * other(1, 0) + delta(4) * other(2, 0);
62  (*this)(0, 1) = other(0, 1) - delta(5) * other(1, 1) + delta(4) * other(2, 1);
63  (*this)(0, 2) = other(0, 2) - delta(5) * other(1, 2) + delta(4) * other(2, 2);
64  (*this)(0, 3) = other(0, 3) + delta(0);
65  (*this)(1, 0) = other(1, 0) + delta(5) * other(0, 0) - delta(3) * other(2, 0);
66  (*this)(1, 1) = other(1, 1) + delta(5) * other(0, 1) - delta(3) * other(2, 1);
67  (*this)(1, 2) = other(1, 2) + delta(5) * other(0, 2) - delta(3) * other(2, 2);
68  (*this)(1, 3) = other(1, 3) + delta(1);
69  (*this)(2, 0) = other(2, 0) - delta(4) * other(0, 0) + delta(3) * other(1, 0);
70  (*this)(2, 1) = other(2, 1) - delta(4) * other(0, 1) + delta(3) * other(1, 1);
71  (*this)(2, 2) = other(2, 2) - delta(4) * other(0, 2) + delta(3) * other(1, 2);
72  (*this)(2, 3) = other(2, 3) + delta(2);
73  (*this)(3, 0) = 0;
74  (*this)(3, 1) = 0;
75  (*this)(3, 2) = 0;
76  (*this)(3, 3) = 1;
77  }
78  else
79  {
80  Transform<Scalar, Dim, Mode, Options> t;
81  t.linear() = (AngleAxis<Scalar>(delta.segment(3, 3).norm(), delta.segment(3, 3).normalized())).toRotationMatrix();
82  t.translation() = t.linear() * delta.segment(0, 3);
83  (*this) = t * other;
84  }
85 }
86 
87 inline
88 void
89 fromDenavitHartenbergPaul(const Scalar& d, const Scalar& theta, const Scalar& a, const Scalar& alpha)
90 {
91  Scalar cosAlpha = ::std::cos(alpha);
92  Scalar cosTheta = ::std::cos(theta);
93  Scalar sinAlpha = ::std::sin(alpha);
94  Scalar sinTheta = ::std::sin(theta);
95 
96  (*this)(0, 0) = cosTheta;
97  (*this)(1, 0) = sinTheta;
98  (*this)(2, 0) = Scalar(0);
99  (*this)(3, 0) = Scalar(0);
100  (*this)(0, 1) = -cosAlpha * sinTheta;
101  (*this)(1, 1) = cosAlpha * cosTheta;
102  (*this)(2, 1) = sinAlpha;
103  (*this)(3, 1) = Scalar(0);
104  (*this)(0, 2) = sinAlpha * sinTheta;
105  (*this)(1, 2) = -sinAlpha * cosTheta;
106  (*this)(2, 2) = cosAlpha;
107  (*this)(3, 2) = Scalar(0);
108  (*this)(0, 3) = a * cosTheta;
109  (*this)(1, 3) = a * sinTheta;
110  (*this)(2, 3) = d;
111  (*this)(3, 3) = Scalar(1);
112 }
113 
114 template<typename Scalar>
115 inline
116 void
117 getDelta() const
118 {
119  Matrix<Scalar, 6, 1> res;
120 
121  res(0) = (*this)(0, 3);
122  res(1) = (*this)(1, 3);
123  res(2) = (*this)(2, 3);
124  res(3) = ((*this)(2, 1) - (*this)(1, 2)) / 2.0f;
125  res(4) = ((*this)(0, 2) - (*this)(2, 0)) / 2.0f;
126  res(5) = ((*this)(1, 0) - (*this)(0, 1)) / 2.0f;
127 
128  return res;
129 }
130 
131 template<typename Scalar>
132 inline
133 void
134 setDelta(const Matrix<Scalar, 6, 1>& delta)
135 {
136  (*this)(0, 0) = 0;
137  (*this)(0, 1) = -delta(5);
138  (*this)(0, 2) = delta(4);
139  (*this)(0, 3) = delta(0);
140  (*this)(1, 0) = delta(5);
141  (*this)(1, 1) = 0;
142  (*this)(1, 2) = -delta(3);
143  (*this)(1, 3) = delta(1);
144  (*this)(2, 0) = -delta(4);
145  (*this)(2, 1) = delta(3);
146  (*this)(2, 2) = 0;
147  (*this)(2, 3) = delta(2);
148  (*this)(3, 0) = 0;
149  (*this)(3, 1) = 0;
150  (*this)(3, 2) = 0;
151  (*this)(3, 3) = 1;
152 }
153 
163 template<typename Scalar, int Dim, int Mode, int Options>
164 inline
165 Matrix<Scalar, 6, 1>
166 toDelta(const Transform<Scalar, Dim, Mode, Options>& other, const bool& useApproximation = false) const
167 {
168  Matrix<Scalar, 6, 1> res;
169 
170  res(0) = other(0, 3) - (*this)(0, 3);
171  res(1) = other(1, 3) - (*this)(1, 3);
172  res(2) = other(2, 3) - (*this)(2, 3);
173 
174  if (useApproximation)
175  {
176  res(3) = ((*this)(1, 0) * other(2, 0) - (*this)(2, 0) * other(1, 0) + (*this)(1, 1) * other(2, 1) - (*this)(2, 1) * other(1, 1) + (*this)(1, 2) * other(2, 2) - (*this)(2, 2) * other(1, 2)) / 2.0f;
177  res(4) = ((*this)(2, 0) * other(0, 0) - (*this)(0, 0) * other(2, 0) + (*this)(2, 1) * other(0, 1) - (*this)(0, 1) * other(2, 1) + (*this)(2, 2) * other(0, 2) - (*this)(0, 2) * other(2, 2)) / 2.0f;
178  res(5) = ((*this)(0, 0) * other(1, 0) - (*this)(1, 0) * other(0, 0) + (*this)(0, 1) * other(1, 1) - (*this)(1, 1) * other(0, 1) + (*this)(0, 2) * other(1, 2) - (*this)(1, 2) * other(0, 2)) / 2.0f;
179  }
180  else
181  {
182  AngleAxis<Scalar> r(Matrix<Scalar, 3, 3>(other.linear() * linear().transpose()));
183  res.segment(3, 3) = r.angle() * r.axis();
184  }
185 
186  return res;
187 }
188 
189 inline
190 void
191 toDenavitHartenbergPaul(Scalar& d, Scalar& theta, Scalar& a, Scalar& alpha) const
192 {
193  assert(::std::abs((*this)(2, 0)) <= ::std::numeric_limits<Scalar>::epsilon());
194 
195  d = (*this)(2, 3);
196 
197  theta = ::std::atan2((*this)(1, 0), (*this)(0, 0));
198 
199  if (::std::abs((*this)(0, 0)) <= ::std::numeric_limits<Scalar>::epsilon())
200  {
201  a = (*this)(1, 3) / (*this)(1, 0);
202  }
203  else if (::std::abs((*this)(1, 0)) <= ::std::numeric_limits<Scalar>::epsilon())
204  {
205  a = (*this)(0, 3) / (*this)(0, 0);
206  }
207  else
208  {
209  a = (*this)(1, 3) / (*this)(1, 0) + (*this)(0, 3) / (*this)(0, 0);
210  }
211 
212  alpha = ::std::atan2((*this)(2, 1), (*this)(2, 2));
213 }
214 
215 #endif // RL_MATH_TRANSFORMADDONS_H
pow
Quaternion< Scalar > pow(const Scalar &t) const
Definition: QuaternionBaseAddons.h:128
setDelta
void setDelta(const Matrix< Scalar, 6, 1 > &delta)
Definition: TransformAddons.h:134
toDenavitHartenbergPaul
void toDenavitHartenbergPaul(Scalar &d, Scalar &theta, Scalar &a, Scalar &alpha) const
Definition: TransformAddons.h:191
fromDelta
void fromDelta(const Transform< Scalar, Dim, Mode, Options > &other, const Matrix< Scalar, 6, 1 > &delta, const bool &useApproximation=false)
Calculate transformation from a linear and angular velocity vector.
Definition: TransformAddons.h:57
fromDenavitHartenbergPaul
void fromDenavitHartenbergPaul(const Scalar &d, const Scalar &theta, const Scalar &a, const Scalar &alpha)
Definition: TransformAddons.h:89
getDelta
void getDelta() const
Definition: TransformAddons.h:117
distance
Scalar distance(const Transform< Scalar, Dim, Mode, Options > &other, const Scalar &weight=1) const
Definition: TransformAddons.h:33
toDelta
Matrix< Scalar, 6, 1 > toDelta(const Transform< Scalar, Dim, Mode, Options > &other, const bool &useApproximation=false) const
Calculate the linear and angular velocity vector between two transformations.
Definition: TransformAddons.h:166