GCC Code Coverage Report


Directory: ./
File: src/conversions.cc
Date: 2025-05-11 11:10:19
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