GCC Code Coverage Report


Directory: ./
File: src/conversions.cc
Date: 2024-12-13 15:50:05
Exec Total Coverage
Lines: 34 237 14.3%
Branches: 25 421 5.9%

Line Branch Exec Source
1 // Copyright (c) 2016, Joseph Mirabel
2 // Authors: Joseph Mirabel (joseph.mirabel@laas.fr)
3 //
4
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 // 1. Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 //
12 // 2. Redistributions in binary form must reproduce the above copyright
13 // notice, this list of conditions and the following disclaimer in the
14 // documentation and/or other materials provided with the distribution.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
27 // DAMAGE.
28
29 #include <boost/mpl/for_each.hpp>
30 #include <boost/mpl/vector.hpp>
31 #include <hpp/constraints/comparison-types.hh>
32 #include <hpp/corbaserver/config.hh>
33 #include <hpp/corbaserver/conversions.hh>
34 #include <hpp/pinocchio/configuration.hh>
35 #include <hpp/pinocchio/device.hh>
36 #include <pinocchio/spatial/se3.hpp>
37
38 namespace hpp {
39 namespace corbaServer {
40 using CORBA::ULong;
41
42 25 void toTransform3s(const Transform_ in, Transform3s& out) {
43
1/2
✓ Branch 1 taken 25 times.
✗ Branch 2 not taken.
25 Transform3s::Quaternion Q(in[6], in[3], in[4], in[5]);
44 25 const value_type eps = 1e-8;
45
2/4
✓ Branch 1 taken 25 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 25 times.
25 if (std::fabs(Q.squaredNorm() - 1) > eps)
46 throw Error("Quaternion is not normalized.");
47
4/8
✓ Branch 1 taken 25 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 25 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 25 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 25 times.
✗ Branch 11 not taken.
25 out.translation() << in[0], in[1], in[2];
48
2/4
✓ Branch 1 taken 25 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 25 times.
✗ Branch 5 not taken.
25 out.rotation() = Q.matrix();
49 25 }
50
51 25 Transform3s toTransform3s(const Transform_ in) {
52 25 Transform3s out;
53 25 toTransform3s(in, out);
54 25 return out;
55 }
56
57 std::vector<Transform3s> toTransform3s(const TransformSeq in) {
58 std::vector<Transform3s> out(in.length());
59 for (std::size_t i = 0; i < out.size(); ++i)
60 toTransform3s(in[(ULong)i], out[i]);
61 return out;
62 }
63
64 void toHppTransform(const Transform3s& in, Transform_ out) {
65 Transform3s::Quaternion q(in.rotation());
66 out[3] = q.x();
67 out[4] = q.y();
68 out[5] = q.z();
69 out[6] = q.w();
70 for (int i = 0; i < 3; i++) out[i] = in.translation()[i];
71 }
72
73 Transform__slice* toHppTransform(const Transform3s& in) {
74 Transform__slice* out = Transform__alloc();
75 toHppTransform(in, out);
76 return out;
77 }
78
79 void toIntSeq(std::vector<int> const& input, intSeq& output) {
80 ULong size = (ULong)input.size();
81 output.length(size);
82
83 for (std::size_t i = 0; i < size; ++i) {
84 output[(ULong)i] = input[i];
85 }
86 }
87
88 intSeq* toIntSeq(std::vector<int> const& in) {
89 return toIntSeq(in.begin(), in.end());
90 }
91
92 6 floatSeq* vectorToFloatSeq(core::vectorIn_t input) {
93
1/2
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
6 floatSeq* q_ptr = new floatSeq();
94
1/2
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
6 vectorToFloatSeq(input, *q_ptr);
95 6 return q_ptr;
96 }
97
98 6 void vectorToFloatSeq(core::vectorIn_t input, floatSeq& output) {
99 6 ULong size = (ULong)input.size();
100 6 output.length(size);
101
102
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 6 times.
34 for (std::size_t i = 0; i < size; ++i) {
103 28 output[(ULong)i] = input[i];
104 }
105 6 }
106
107 floatSeqSeq* matrixToFloatSeqSeq(core::matrixIn_t input) {
108 floatSeqSeq* res = new floatSeqSeq;
109 res->length((ULong)input.rows());
110 for (size_type i = 0; i < input.rows(); ++i) {
111 floatSeq row;
112 row.length((ULong)input.cols());
113 for (size_type j = 0; j < input.cols(); ++j) {
114 row[(ULong)j] = input(i, j);
115 }
116 (*res)[(ULong)i] = row;
117 }
118 return res;
119 }
120
121 intSeqSeq* matrixToIntSeqSeq(Eigen::Ref<const IntMatrix_t> input) {
122 intSeqSeq* res = new intSeqSeq;
123 res->length((ULong)input.rows());
124 for (size_type i = 0; i < input.rows(); ++i) {
125 intSeq row;
126 row.length((ULong)input.cols());
127 for (size_type j = 0; j < input.cols(); ++j) {
128 row[(ULong)j] = input(i, j);
129 }
130 (*res)[(ULong)i] = row;
131 }
132 return res;
133 }
134
135 std::vector<int> intSeqToVector(const intSeq& input) {
136 std::vector<int> res(input.length());
137 for (unsigned int i = 0; i < input.length(); ++i) res[i] = input[i];
138 return res;
139 }
140
141 vector3_t floatSeqToVector3(const floatSeq& dofArray) {
142 if (dofArray.length() != 3) {
143 HPP_THROW(Error, "Expecting vector of size 3, got vector of size "
144 << dofArray.length() << ".");
145 }
146 // Fill dof vector with dof array.
147 vector3_t result;
148 for (unsigned int iDof = 0; iDof < 3; ++iDof) {
149 result[iDof] = dofArray[iDof];
150 }
151 return result;
152 }
153
154 5 vector_t floatSeqToVector(const floatSeq& dofArray,
155 const size_type expectedSize) {
156 5 size_type inputDim = (size_type)dofArray.length();
157
3/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
5 if (expectedSize >= 0 && inputDim != expectedSize) {
158 HPP_THROW(std::runtime_error,
159 "size of input array ("
160 << inputDim << ") is different from the expected size ("
161 << expectedSize << ")");
162 }
163 // Fill dof vector with dof array.
164
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 vector_t result(inputDim);
165
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 5 times.
26 for (size_type iDof = 0; iDof < inputDim; ++iDof) {
166
2/4
✓ Branch 1 taken 21 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 21 times.
✗ Branch 5 not taken.
21 result[iDof] = dofArray[(CORBA::ULong)iDof];
167 }
168 10 return result;
169 }
170
171 2 Configuration_t floatSeqToConfig(const DevicePtr_t& robot,
172 const floatSeq& dofArray,
173 bool throwIfNotNormalized) {
174 2 Configuration_t q(floatSeqToVector(dofArray, robot->configSize()));
175
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (throwIfNotNormalized) {
176 2 const value_type eps = 1e-8;
177
3/6
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 2 times.
2 if (!pinocchio::isNormalized(robot, q, eps))
178 throw Error(
179 "Configuration is not normalized (wrong quaternion or complex "
180 "norm).");
181 }
182 2 return q;
183 }
184
185 core::matrix_t floatSeqSeqToMatrix(const floatSeqSeq& input,
186 const size_type expectedRows,
187 const size_type expectedCols) {
188 size_type rows = (size_type)input.length();
189 if (expectedRows >= 0 && rows != expectedRows) {
190 HPP_THROW(std::runtime_error,
191 "number of rows of input floatSeqSeq ("
192 << rows << ") is different from the expected number of rows ("
193 << expectedRows << ")");
194 }
195 if (rows == 0) return matrix_t(rows, std::max(size_type(0), expectedCols));
196 size_type cols = (size_type)input[0].length();
197 if (expectedCols >= 0 && cols != expectedCols) {
198 HPP_THROW(std::runtime_error,
199 "number of cols of input floatSeqSeq ("
200 << cols << ") is different from the expected number of cols ("
201 << expectedCols << ")");
202 }
203 matrix_t out(rows, cols);
204 for (size_type r = 0; r < rows; ++r) {
205 const floatSeq& row = input[(CORBA::ULong)r];
206 size_type cols_in_row = (size_type)row.length();
207 if (cols_in_row != cols)
208 HPP_THROW(std::runtime_error,
209 "number of cols of input floatSeqSeq ("
210 << cols_in_row
211 << ") is different from the expected number of cols ("
212 << expectedCols << ") in row " << r);
213 for (size_type c = 0; c < cols; ++c) {
214 out(r, c) = row[(CORBA::ULong)c];
215 }
216 }
217 return out;
218 }
219
220 IntMatrix_t intSeqSeqToMatrix(const intSeqSeq& input,
221 const size_type expectedRows,
222 const size_type expectedCols) {
223 size_type rows = (size_type)input.length();
224 if (expectedRows >= 0 && rows != expectedRows) {
225 HPP_THROW(std::runtime_error,
226 "number of rows of input floatSeqSeq ("
227 << rows << ") is different from the expected number of rows ("
228 << expectedRows << ")");
229 }
230 if (rows == 0) return IntMatrix_t(rows, std::max(size_type(0), expectedCols));
231 size_type cols = (size_type)input[0].length();
232 if (expectedCols >= 0 && cols != expectedCols) {
233 HPP_THROW(std::runtime_error,
234 "number of cols of input floatSeqSeq ("
235 << cols << ") is different from the expected number of cols ("
236 << expectedCols << ")");
237 }
238 IntMatrix_t out(rows, cols);
239 for (size_type r = 0; r < rows; ++r) {
240 const intSeq& row = input[(CORBA::ULong)r];
241 for (size_type c = 0; c < cols; ++c) out(r, c) = row[(CORBA::ULong)c];
242 }
243 return out;
244 }
245
246 std::vector<bool> boolSeqToVector(const hpp::boolSeq& mask,
247 unsigned int length) {
248 if (mask.length() != length) {
249 std::stringstream ss;
250 ss << "Mask must be of length " << length;
251 throw hpp::Error(ss.str().c_str());
252 }
253 std::vector<bool> m(length);
254 for (size_t i = 0; i < length; i++) m[i] = mask[(CORBA::ULong)i];
255 return m;
256 }
257
258 stringSeqSeq* vectorToStringSeqSeq(
259 std::vector<std::vector<std::string>> input) {
260 stringSeqSeq* seq_ptr = new stringSeqSeq();
261 ULong size = (ULong)input.size();
262 seq_ptr->length(size);
263 for (size_type i = 0; i < size; ++i) {
264 Names_t* names = toNames_t<std::vector<std::string>>(input.at(i));
265 (*seq_ptr)[(ULong)i] = *names;
266 }
267 return seq_ptr;
268 }
269
270 constraints::ComparisonTypes_t convertComparison(hpp::ComparisonTypes_t comp) {
271 constraints::ComparisonTypes_t res(comp.length());
272 for (std::size_t i = 0; i < comp.length(); ++i) {
273 switch (comp[(CORBA::ULong)i]) {
274 case Equality:
275 res[i] = constraints::Equality;
276 break;
277 case EqualToZero:
278 res[i] = constraints::EqualToZero;
279 break;
280 case Superior:
281 res[i] = constraints::Superior;
282 break;
283 case Inferior:
284 res[i] = constraints::Inferior;
285 break;
286 default:
287 abort();
288 }
289 }
290 return res;
291 }
292
293 hpp::ComparisonTypes_t* convertComparison(constraints::ComparisonTypes_t comp) {
294 hpp::ComparisonTypes_t* res_ptr = new hpp::ComparisonTypes_t();
295 hpp::ComparisonTypes_t& res(*res_ptr);
296 res.length((CORBA::ULong)comp.size());
297 for (std::size_t i = 0; i < comp.size(); ++i) {
298 switch (comp[i]) {
299 case constraints::Equality:
300 res[(CORBA::ULong)i] = Equality;
301 break;
302 case constraints::EqualToZero:
303 res[(CORBA::ULong)i] = EqualToZero;
304 break;
305 case constraints::Superior:
306 res[(CORBA::ULong)i] = Superior;
307 break;
308 case constraints::Inferior:
309 res[(CORBA::ULong)i] = Inferior;
310 break;
311 default:
312 throw Error("Unknown comparison type");
313 }
314 }
315 return res_ptr;
316 }
317
318 using core::Parameter;
319
320 Parameter toParameter(const CORBA::Any& any);
321
322 CORBA::Any toCorbaAny(const Parameter& parameter);
323
324 struct Parameter_CorbaAny {
325 private:
326 template <typename first, typename second>
327 static inline second as(const first& f) {
328 return second(f);
329 }
330
331 struct convertToParam {
332 const CORBA::Any& corbaAny;
333 Parameter& param;
334 bool& done;
335 void operator()(std::pair<vector_t, floatSeq>) {
336 if (done) return;
337 floatSeq* d = new floatSeq();
338 if (corbaAny >>= d) {
339 param = Parameter(floatSeqToVector(*d));
340 done = true;
341 } else
342 delete d;
343 }
344 void operator()(std::pair<matrix_t, floatSeqSeq>) {
345 if (done) return;
346 floatSeqSeq* d = new floatSeqSeq();
347 if (corbaAny >>= d) {
348 param = Parameter(floatSeqSeqToMatrix(*d));
349 done = true;
350 } else
351 delete d;
352 }
353 template <typename T>
354 void operator()(T) {
355 if (done) return;
356 typename T::second_type d;
357 if (corbaAny >>= d) {
358 param =
359 Parameter(as<typename T::second_type, typename T::first_type>(d));
360 done = true;
361 }
362 }
363 convertToParam(const CORBA::Any& a, Parameter& p, bool& d)
364 : corbaAny(a), param(p), done(d) {}
365 };
366 /// TODO: This list of CORBA types is not complete.
367 typedef boost::mpl::vector<
368 // There is no operator<<= (CORBA::Any, CORBA::Boolean)
369 std::pair<bool, CORBA::Boolean>,
370
371 std::pair<size_type, CORBA::LongLong>, std::pair<size_type, CORBA::Long>,
372 std::pair<size_type, CORBA::Short>,
373 std::pair<size_type, CORBA::ULongLong>,
374 std::pair<size_type, CORBA::ULong>, std::pair<size_type, CORBA::UShort>,
375
376 std::pair<value_type, CORBA::Float>, std::pair<value_type, CORBA::Double>,
377
378 std::pair<std::string, const char*>
379
380 // This two do not work because omniidl must be given the option -Wba in
381 // order to generate a DynSK.cc file containing the conversion to/from Any
382 // type.
383 ,
384 std::pair<matrix_t, floatSeqSeq>, std::pair<vector_t, floatSeq>>
385 Parameter_AnyPairs_t;
386
387 public:
388 static Parameter toParameter(const CORBA::Any& an) {
389 Parameter out;
390 bool done = false;
391 convertToParam ret(an, out, done);
392 boost::mpl::for_each<Parameter_AnyPairs_t>(ret);
393 if (!done) throw hpp::Error("Could not convert to Parameter");
394 return out;
395 }
396 static CORBA::Any toCorbaAny(const Parameter& p) {
397 CORBA::Any out;
398 switch (p.type()) {
399 case Parameter::BOOL:
400 out <<= p.boolValue();
401 break;
402 case Parameter::INT:
403 out <<= (CORBA::Long)p.intValue();
404 break;
405 case Parameter::FLOAT:
406 out <<= p.floatValue();
407 break;
408 case Parameter::STRING:
409 out <<= p.stringValue().c_str();
410 break;
411 case Parameter::VECTOR:
412 out <<= vectorToFloatSeq(p.vectorValue());
413 break;
414 case Parameter::MATRIX:
415 out <<= matrixToFloatSeqSeq(p.matrixValue());
416 break;
417 default:
418 throw hpp::Error("Could not convert to CORBA::Any");
419 break;
420 }
421 return out;
422 }
423 };
424
425 template <>
426 inline vector_t Parameter_CorbaAny::as<floatSeq, vector_t>(const floatSeq& in) {
427 return floatSeqToVector(in);
428 }
429 template <>
430 inline matrix_t Parameter_CorbaAny::as<floatSeqSeq, matrix_t>(
431 const floatSeqSeq& in) {
432 return floatSeqSeqToMatrix(in);
433 }
434
435 Parameter toParameter(const CORBA::Any& any) {
436 return Parameter_CorbaAny::toParameter(any);
437 }
438
439 CORBA::Any toCorbaAny(const Parameter& parameter) {
440 return Parameter_CorbaAny::toCorbaAny(parameter);
441 }
442 } // namespace corbaServer
443 } // namespace hpp
444