Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
CovTransformPose.cpp
1 #include "CovTransformPose.hh"
2 
3 #include <Base/Math/Vector3.hh>
4 #include <Base/Math/Matrix.hh>
5 #include <Geometry/RMatrix.hh>
6 #include <Base/Geometry/Quaternion.hh>
7 
8 using namespace std;
9 using namespace BIAS;
10 
11 CovTransformPose::CovTransformPose()
12 {
13  tType_ = NONE;
14 }
15 
16 int CovTransformPose::
17 PoseQuatToEulerZYX(const Vector3<double> &posQ, const Quaternion<double> &rotQ,
18  const Matrix<double> &covQ,
19  Vector3<double> &posE, Vector3<double> &rotE,
20  Matrix<double> &covE)
21 {
22  int res = 0;
23 
24  //tell Transform_ what we want to do
25  tType_ = Quat2EulerZYX;
26 
27  //generate source vector
28  Vector<double> src(7), dst;
29  for (unsigned int i = 0; i < 3; i++) src[i] = posQ[i];
30  for (unsigned int i = 0; i < 4; i++) src[i+3] = rotQ[i];
31  BIASASSERT(covQ.num_rows() == 7 && covQ.num_cols() == 7);
32 
33  //call unscented transform (uses Transform_ to transform src and samplepoints)
34  if (Transform(src, covQ, dst, covE) != 0) {
35  BIASERR("Error in Unscented Transform!");
36  res = -1;
37  } else {
38  //get resulting pose from target vector
39  for (unsigned int i = 0; i < 3; i++) posE[i] = dst[i];
40  for (unsigned int i = 0; i < 3; i++) rotE[i] = dst[i+3];
41  }
42 
43  //transformation is done
44  tType_ = NONE;
45 
46  return res;
47 }
48 
49 int CovTransformPose::
50 PoseEulerZYXToQuat(const Vector3<double> &posE, const Vector3<double> &rotE,
51  const Matrix<double> &covE,
53  Matrix<double> &covQ)
54 {
55  int res = 0;
56 
57  //tell Transform_ what we want to do
58  tType_ = EulerZYX2Quat;
59 
60  //generate source vector
61  Vector<double> src(6), dst;
62  for (unsigned int i = 0; i < 3; i++) src[i] = posE[i];
63  for (unsigned int i = 0; i < 3; i++) src[i+3] = rotE[i];
64  BIASASSERT(covE.num_rows() == 7 && covE.num_cols() == 7);
65 
66  //call unscented transform (uses Transform_ to transform src and samplepoints)
67  if (Transform(src, covE, dst, covQ) != 0) {
68  BIASERR("Error in Unscented Transform!");
69  res = -1;
70  } else {
71  //get resulting pose from target vector
72  for (unsigned int i = 0; i < 3; i++) posQ[i] = dst[i];
73  for (unsigned int i = 0; i < 4; i++) rotQ[i] = dst[i+3];
74  }
75 
76  //transformation is done
77  tType_ = NONE;
78 
79  return res;
80 }
81 
82 
83 int CovTransformPose::
84 TransformPose(const Vector3<double> &inputPos,
85  const Quaternion<double> &inputRot,
86  const Matrix<double> &inputCov,
87  const Vector3<double> &translate,
88  const Quaternion<double> &rotate,
89  const Matrix<double> &transformCov,
90  Vector3<double> &resultPos,
91  Quaternion<double> &resultRot,
92  Matrix<double> &resultCov)
93 {
94  int res = 0;
95 
96  //tell Transform_ what we want to do
97  tType_ = PoseTransform;
98 
99  //generate source vector
100  Vector<double> src(14), dst;
101  for (unsigned int i = 0; i < 3; i++) {
102  src[i] = inputPos[i];
103  src[i+7] = translate[i];
104  }
105  for (unsigned int i = 0; i < 4; i++) {
106  src[i+3] = inputRot[i];
107  src[i+10] = rotate[i];
108  }
109 
110  //generate source covariance matrix
111  BIASASSERT(inputCov.num_rows() == 7 && inputCov.num_cols() == 7 &&
112  transformCov.num_rows() == 7 && transformCov.num_cols() == 7);
113  Matrix<double> srcCov(14, 14, MatrixZero), dstCov;
114  for (unsigned int i = 0; i < 7; i++) {
115  for (unsigned int j = 0; j < 7; j++) {
116  srcCov[i][j] = inputCov[i][j];
117  srcCov[i+7][j+7] = transformCov[i][j];
118  }
119  }
120 
121  //call unscented transform (uses Transform_ to transform src and samplepoints)
122  if (Transform(src, srcCov, dst, dstCov) != 0) {
123  BIASERR("Error in Unscented Transform!");
124  res = -1;
125  } else {
126  //get resulting pose from target vector
127  for (unsigned int i = 0; i < 3; i++) resultPos[i] = dst[i];
128  for (unsigned int i = 0; i < 4; i++) resultRot[i] = dst[i+3];
129  resultCov = dstCov;
130  }
131 
132  //transformation is done
133  tType_ = NONE;
134 
135  return res;
136 }
137 
138 
139 int CovTransformPose::
140 TransformPoint3D(const Vector3<double> &point3D,
141  const Matrix3x3<double> &cov3D,
142  const Vector3<double> &translate,
143  const Quaternion<double> &rotate,
144  const Matrix<double> &transformCov,
145  Vector3<double> &resultPoint3D,
146  Matrix3x3<double> &resultCov3D)
147 {
148  int res = 0;
149 
150  //tell Transform_ what we want to do
151  tType_ = Point3DTransform;
152 
153  //generate source vector
154  Vector<double> src(10), dst;
155  for (unsigned int i = 0; i < 3; i++) src[i] = point3D[i];
156  for (unsigned int i = 0; i < 3; i++) src[i+3] = translate[i];
157  for (unsigned int i = 0; i < 4; i++) src[i+6] = rotate[i];
158 
159  //generate source covariance matrix
160  BIASASSERT(transformCov.num_rows() == 7 && transformCov.num_cols() == 7);
161  Matrix<double> srcCov(10, 10, MatrixZero), dstCov;
162  for (unsigned int i = 0; i < 3; i++) {
163  for (unsigned int j = 0; j < 3; j++) {
164  srcCov[i][j] = cov3D[i][j];
165  }
166  }
167  for (unsigned int i = 0; i < 7; i++) {
168  for (unsigned int j = 0; j < 7; j++) {
169  srcCov[i+3][j+3] = transformCov[i][j];
170  }
171  }
172 
173  // [HACK] Enfore symmetry of covariance matrix!!
174  srcCov.MakeSymmetric();
175 
176  //call unscented transform (uses Transform_ to transform src and samplepoints)
177  if (Transform(src, srcCov, dst, dstCov) != 0) {
178  BIASERR("Error in Unscented Transform!");
179  res = -1;
180  } else {
181  //get resulting 3D point from target vector
182  for (unsigned int i = 0; i < 3; i++) resultPoint3D[i] = dst[i];
183  for (unsigned int i = 0; i < 3; i++) {
184  for (unsigned int j = 0; j < 3; j++) {
185  resultCov3D[i][j] = dstCov[i][j];
186  }
187  }
188  }
189 
190  //transformation is done
191  tType_ = NONE;
192 
193  return res;
194 }
195 
196 
197 int CovTransformPose::
198 Transform_(const Vector<double>& src, Vector<double>& dst) const
199 {
200  int res = 0;
201 
202  //switch what's to do
203  switch (tType_) {
204 
205  //Convert quaternion to euler-angles
206  case Quat2EulerZYX:
207  {
208  //get rotation-matrix from quaternion
209  RMatrix R;
210  R.SetFromQuaternion(Quaternion<double>(src[3], src[4], src[5], src[6]));
211  //get ratation-angles from RMatrix
212  double xPhi, yPhi, zPhi;
213  if (R.GetRotationAnglesZYX(xPhi, yPhi, zPhi) != 0) {
214  //decomposition failed, return error
215  BIASERR("Error in matrix decomposition!");
216  res = -1;
217  } else {
218  //decomposition successfull, compose destination-vector...
219  dst.newsize(6);
220  //...copy position...
221  for (unsigned int i=0; i<3; i++) dst[i] = src[i];
222  //...and set euler-angles
223  dst[3] = xPhi;
224  dst[4] = yPhi;
225  dst[5] = zPhi;
226  res = 0;
227  }
228  }
229  break;
230 
231  //Convert euler-angles to quaternion
232  case EulerZYX2Quat:
233  {
234  //generate quaternion from given euler-angles...
236  q.SetZYX(src[3], src[4], src[5]);
237  //compose destination-vector...
238  dst.newsize(7);
239  //...copy position...
240  for (unsigned int i=0; i<3; i++) dst[i] = src[i];
241  //...set quaternion-values
242  for (unsigned int i=0; i<4; i++) dst[i+3] = q[i];
243  res = 0;
244  }
245  break;
246 
247  //Convert pose by a rigid transformation (rotation + translation)
248  case PoseTransform:
249  {
250  //fetch old pose C,Q and rigid transformation dC,dQ
251  Vector3<double> C(src[0],src[1],src[2]);
252  Quaternion<double> Q(src[3],src[4],src[5],src[6]);
253  Vector3<double> dt(src[7],src[8],src[9]);
254  Quaternion<double> dQ(src[10],src[11],src[12],src[13]);
255  //transform pose to dQ*Q, dQ*C*dQ'+dt
256  Quaternion<double> resQ = dQ * Q;
257  Vector3<double> resC = dQ.MultVec(C) + dt;
258  dst.newsize(7);
259  //...copy position...
260  for (unsigned int i = 0; i < 3; i++) dst[i] = resC[i];
261  //...set quaternion-values
262  for (unsigned int i = 0; i < 4; i++) dst[i+3] = resQ[i];
263  res = 0;
264  }
265  break;
266 
267  //Convert 3D point by a rigid transformation (rotation + translation)
268  case Point3DTransform:
269  {
270  //fetch 3D point X and rigid transformation Q,t
271  Vector3<double> X(src[0],src[1],src[2]);
272  Vector3<double> t(src[3],src[4],src[5]);
273  Quaternion<double> Q(src[6],src[7],src[8],src[9]);
274  //transform X to Q*X*Q'+t
275  Vector3<double> resX = Q.MultVec(X) + t;
276  dst.newsize(3);
277  //copy 3D point
278  for (unsigned int i = 0; i < 3; i++) dst[i] = resX[i];
279  res = 0;
280  }
281  break;
282 
283  default:
284  BIASERR("We should't end up here!!!");
285  BIASABORT;
286  }
287 
288  return res;
289 }
int GetRotationAnglesZYX(double &PhiX, double &PhiY, double &PhiZ) const
Get Euler angles for this rotation matrix in order ZYX.
Subscript num_cols() const
Definition: cmat.h:320
int SetFromQuaternion(const Quaternion< ROTATION_MATRIX_TYPE > &q)
Set rotation matrix from a quaternion.
int SetZYX(QUAT_TYPE radX, QUAT_TYPE radY, QUAT_TYPE radZ)
Sets quaternion as concatenated rotations around x,y,z-axis; this = q_z * q_y * q_x (BIAS-RMatrix con...
int MultVec(const Vector3< QUAT_TYPE > &vec, Vector3< QUAT_TYPE > &res) const
rotates the given Vector qith the quaternion ( q v q* ) the resulting vector is given in res ...
Definition: Quaternion.hh:136
3D rotation matrix
Definition: RMatrix.hh:49
Vector< T > & newsize(Subscript N)
Definition: vec.h:220
Subscript num_rows() const
Definition: cmat.h:319
void MakeSymmetric()
componentwise: this = 0.5(this + this^T) yields symmetric matrix only allowed for square shaped matri...
Definition: Matrix.hh:522