knowrob  2.1.0
A Knowledge Base System for Cognition-enabled Robots
algebra.cpp
Go to the documentation of this file.
1 
2 #define PL_SAFE_ARG_MACROS
3 
4 #include <Eigen/Geometry>
5 #include <SWI-cpp.h>
6 
7 void eigen2pl(const Eigen::Quaterniond &q, term_t &out) {
8  PlTail l(out);
9  l.append(q.x());
10  l.append(q.y());
11  l.append(q.z());
12  l.append(q.w());
13  l.close();
14 }
15 
16 void eigen2pl(const Eigen::Vector3d &v, term_t &out) {
17  PlTail l(out);
18  l.append(v.x());
19  l.append(v.y());
20  l.append(v.z());
21  l.close();
22 }
23 
24 void eigen2pl(const Eigen::Matrix4d &m, term_t &out) {
25  PlTail l(out);
26  for (int i = 0; i < 4; ++i) {
27  for (int j = 0; j < 4; ++j) {
28  l.append(m(i, j));
29  }
30  }
31  l.close();
32 }
33 
34 void pl2eigen(term_t &arg, Eigen::Quaterniond &q) {
35  PlTail list(arg);
36  PlTerm value;
37  list.next(value);
38  q.x() = value;
39  list.next(value);
40  q.y() = value;
41  list.next(value);
42  q.z() = value;
43  list.next(value);
44  q.w() = value;
45 }
46 
47 void pl2eigen(term_t &arg, Eigen::Vector3d &v) {
48  PlTail list(arg);
49  PlTerm value;
50  list.next(value);
51  v.x() = value;
52  list.next(value);
53  v.y() = value;
54  list.next(value);
55  v.z() = value;
56 }
57 
58 void pl2eigen(term_t &arg, Eigen::Matrix4d &m) {
59  PlTail list(arg);
60  PlTerm value;
61  for (int i = 0; i < 4; ++i) {
62  for (int j = 0; j < 4; ++j) {
63  list.next(value);
64  m(i, j) = value;
65  }
66  }
67 }
68 
69 // +Quaternion, -Inverse
70 foreign_t quaternion_inverse(term_t t_Quaternion, term_t t_Inverse) {
71  Eigen::Quaterniond q;
72  pl2eigen(t_Quaternion, q);
73  eigen2pl(q.inverse(), t_Inverse);
74  return TRUE;
75 }
76 
77 // +Quaternion, +Vector, -Transformed
78 foreign_t quaternion_transform(term_t t_Quaternion, term_t t_Vector, term_t t_Transformed) {
79  Eigen::Quaterniond q;
80  Eigen::Vector3d v;
81  pl2eigen(t_Quaternion, q);
82  pl2eigen(t_Vector, v);
83  eigen2pl(q * v, t_Transformed);
84  return TRUE;
85 }
86 
87 // +Quaternion1, +Quaternion2, -Multiplied
88 foreign_t quaternion_multiply(term_t t_Quaternion1, term_t t_Quaternion2, term_t t_Multiplied) {
89  Eigen::Quaterniond q1, q2;
90  pl2eigen(t_Quaternion1, q1);
91  pl2eigen(t_Quaternion2, q2);
92  eigen2pl(q1 * q2, t_Multiplied);
93  return TRUE;
94 }
95 
96 // +Quaternion1, +Quaternion2, -Diff
97 foreign_t quaternion_diff(term_t t_Quaternion1, term_t t_Quaternion2, term_t t_Diff) {
98  Eigen::Quaterniond q1, q2;
99  pl2eigen(t_Quaternion1, q1);
100  pl2eigen(t_Quaternion2, q2);
101  eigen2pl(q1.inverse() * q2, t_Diff);
102  return TRUE;
103 }
104 
105 // +Quaternion1, +Quaternion2, +Factor, -Interpolated
106 foreign_t quaternion_slerp(term_t t_Quaternion1, term_t t_Quaternion2, term_t t_Factor, term_t t_Interpolated) {
107  Eigen::Quaterniond q1, q2;
108  pl2eigen(t_Quaternion1, q1);
109  pl2eigen(t_Quaternion2, q2);
110  double factor = 0.0;
111  if (!PL_get_float(t_Factor, &factor)) return FALSE;
112  Eigen::Quaterniond q = q1.slerp(factor, q2);
113  eigen2pl(q, t_Interpolated);
114  return TRUE;
115 }
116 
117 // +Quaternion, +Translation, -Matrix
118 foreign_t quaternion_matrix(term_t t_Quaternion, term_t t_Translation, term_t t_Matrix) {
119  Eigen::Quaterniond q;
120  Eigen::Vector3d v;
121  pl2eigen(t_Quaternion, q);
122  pl2eigen(t_Translation, v);
123  Eigen::Matrix4d m = Eigen::Matrix4d::Identity();
124  // 3x3 block starting at (0,0)
125  m.block(0, 0, 3, 3) = q.toRotationMatrix();
126  // 3x1 block starting at (0,3)
127  m.block(0, 3, 3, 1) = v;
128  eigen2pl(m, t_Matrix);
129  return TRUE;
130 }
131 
132 // +Matrix, -Quaternion
133 foreign_t matrix_quaternion(term_t t_Matrix, term_t t_Quaternion) {
134  Eigen::Matrix4d m4;
135  pl2eigen(t_Matrix, m4);
136  Eigen::Matrix3d m3 = m4.block(0, 0, 3, 3);
137  Eigen::Quaterniond q(m3);
138  eigen2pl(q, t_Quaternion);
139  return TRUE;
140 }
141 
142 // +Matrix, -Translation
143 foreign_t matrix_translation(term_t t_Matrix, term_t t_Translation) {
144  Eigen::Matrix4d m;
145  pl2eigen(t_Matrix, m);
146  Eigen::Vector3d v = m.block<3, 1>(0, 3, 3, 1);
147  eigen2pl(v, t_Translation);
148  return TRUE;
149 }
150 
151 namespace knowrob::prolog {
152  PL_extension PL_extension_algebra[] = {
153  {"quaternion_inverse", 2, (pl_function_t) quaternion_inverse, 0},
154  {"quaternion_transform", 3, (pl_function_t) quaternion_transform, 0},
155  {"quaternion_multiply", 3, (pl_function_t) quaternion_multiply, 0},
156  {"quaternion_diff", 3, (pl_function_t) quaternion_diff, 0},
157  {"quaternion_slerp", 4, (pl_function_t) quaternion_slerp, 0},
158  {"quaternion_matrix", 4, (pl_function_t) quaternion_matrix, 0},
159  {"matrix_quaternion", 4, (pl_function_t) matrix_quaternion, 0},
160  {"matrix_translation", 2, (pl_function_t) matrix_translation, 0},
161  {nullptr, 0, nullptr, 0}
162  };
163 }
void pl2eigen(term_t &arg, Eigen::Quaterniond &q)
Definition: algebra.cpp:34
foreign_t quaternion_transform(term_t t_Quaternion, term_t t_Vector, term_t t_Transformed)
Definition: algebra.cpp:78
foreign_t matrix_translation(term_t t_Matrix, term_t t_Translation)
Definition: algebra.cpp:143
foreign_t matrix_quaternion(term_t t_Matrix, term_t t_Quaternion)
Definition: algebra.cpp:133
foreign_t quaternion_inverse(term_t t_Quaternion, term_t t_Inverse)
Definition: algebra.cpp:70
foreign_t quaternion_diff(term_t t_Quaternion1, term_t t_Quaternion2, term_t t_Diff)
Definition: algebra.cpp:97
void eigen2pl(const Eigen::Quaterniond &q, term_t &out)
Definition: algebra.cpp:7
foreign_t quaternion_multiply(term_t t_Quaternion1, term_t t_Quaternion2, term_t t_Multiplied)
Definition: algebra.cpp:88
foreign_t quaternion_matrix(term_t t_Quaternion, term_t t_Translation, term_t t_Matrix)
Definition: algebra.cpp:118
foreign_t quaternion_slerp(term_t t_Quaternion1, term_t t_Quaternion2, term_t t_Factor, term_t t_Interpolated)
Definition: algebra.cpp:106
PL_extension PL_extension_algebra[]
Definition: algebra.h:12