utils.cpp
Go to the documentation of this file.
1#include "utils.h"
2
3#include <filesystem>
4#include <fstream>
5#include <iostream>
6#include <memory>
7#include <optional>
8#include <type_traits>
9
10#include <boost/tokenizer.hpp>
11
12#include <VirtualRobot/MathTools.h>
13
16
18
20{
21
22 /// helpers
23
24 Eigen::Vector4f
26 {
27 /// Define the constraint matrix for the null space transition function
28 ///
29 /// in transition state (state between full locking and unrestricted movement for a contin-
30 /// uous control law) a third-order polynomial with four weight values is required
31 /// In this method the weights are calculated in the preactivate method based on the set
32 /// threshold parameters z1 and z2
33 ///
34 /// z1: state of full locking starts with this value
35 /// z2: state of unrestricted movement starts with this value
36 Eigen::Matrix4f constraintMatrix;
37 constraintMatrix << std::pow(z1, 3), std::pow(z1, 2), z1, 1, std::pow(z2, 3),
38 std::pow(z2, 2), z2, 1, 3 * std::pow(z1, 2), 2 * z1, 1, 0, 3 * std::pow(z2, 2), 2 * z2,
39 1, 0;
40
41 /// Define the constraint result values for the null space transition function
42 Eigen::Vector4f b;
43 b << 0, 1, 0, 0;
44
45 /// weights for continuous task transition
46 return constraintMatrix.colPivHouseholderQr().solve(b);
47 }
48
49 Eigen::VectorXf
50 getEigenVec(nlohmann::json& userConfig,
51 nlohmann::json& defaultConfig,
52 const std::string& entryName,
53 int size,
54 int value)
55 {
56 if (userConfig.find(entryName) != userConfig.end())
57 {
58 auto vec = userConfig[entryName].get<std::vector<float>>();
59 if (vec.size() > 0)
60 {
61 return Eigen::Map<Eigen::VectorXf>(vec.data(), vec.size());
62 }
63 if (size > 0)
64 {
65 return Eigen::VectorXf::Ones(size) * value;
66 }
67 ARMARX_IMPORTANT << "user defined parameter " << entryName
68 << " have size 0, fall back to default";
69 }
70
71 auto vec = defaultConfig[entryName].get<std::vector<float>>();
72 return Eigen::Map<Eigen::VectorXf>(vec.data(), vec.size());
73 }
74
75 void
76 getEigenMatrix(nlohmann::json& userConfig, const std::string& entryName, Eigen::MatrixXf& mat)
77 {
78 if (userConfig.find(entryName) != userConfig.end())
79 {
80 auto vec = userConfig[entryName].get<std::vector<std::vector<float>>>();
81 int rows = vec.size();
82 int cols = vec[0].size();
83 ARMARX_VERBOSE << VAROUT(rows) << VAROUT(cols);
86 mat.resize(rows, cols);
87 for (int i = 0; i < rows; i++)
88 {
89 for (int j = 0; j < cols; j++)
90 {
91 mat(i, j) = vec[i][j];
92 }
93 }
94 // memcpy(mat.data(), vec.data(), rows * cols * sizeof(float));
95 }
96 else
97 {
98 ARMARX_ERROR << "values not found in user config";
99 }
100 }
101
102 Eigen::VectorXf
103 getEigenVecWithDefault(nlohmann::json& userConfig,
104 Eigen::VectorXf defaultValue,
105 const std::string& entryName)
106 {
107 if (userConfig.find(entryName) != userConfig.end())
108 {
109 auto vec = userConfig[entryName].get<std::vector<float>>();
110 if (vec.size() == static_cast<unsigned>(defaultValue.size()))
111 {
112 return Eigen::Map<Eigen::VectorXf>(vec.data(), vec.size());
113 }
114 ARMARX_WARNING << "size of the user defined parameter " << entryName
115 << " doesn't correspond to default size, use default value instead";
116 }
117 return defaultValue;
118 }
119
120 void
121 getError(Eigen::Matrix4f& currentPose,
122 Eigen::Vector3d& targetPosition,
123 Eigen::Quaterniond& targetQuaternion,
124 double& posiError,
125 double& oriError)
126 {
127 Eigen::Matrix4d currentPosed = currentPose.cast<double>();
128 Eigen::Vector3d currentPosid = currentPosed.block<3, 1>(0, 3);
129 posiError = (currentPosid - targetPosition).norm();
130
131 Eigen::Quaterniond currentOrientation = Eigen::Quaterniond{currentPosed.block<3, 3>(0, 0)};
132 oriError = targetQuaternion.angularDistance(currentOrientation);
133 if (oriError > M_PI)
134 {
135 oriError = 2 * M_PI - oriError;
136 }
137 }
138
139 void
140 debugEigenPose(StringVariantBaseMap& datafields, const std::string& name, Eigen::Matrix4f pose)
141 {
142 Eigen::Vector3f rpy = VirtualRobot::MathTools::eigen4f2rpy(pose);
143 datafields[name + "_x"] = new Variant(pose(0, 3));
144 datafields[name + "_y"] = new Variant(pose(1, 3));
145 datafields[name + "_z"] = new Variant(pose(2, 3));
146 datafields[name + "_rx"] = new Variant(rpy(0));
147 datafields[name + "_ry"] = new Variant(rpy(1));
148 datafields[name + "_rz"] = new Variant(rpy(2));
149 }
150
151 void
153 const std::string& name,
154 const Eigen::MatrixXd& mat)
155 {
156 // Pass by const reference (&) to avoid copying the matrix data
157 for (int r = 0; r < mat.rows(); ++r)
158 {
159 for (int c = 0; c < mat.cols(); ++c)
160 {
161 // Construct key: "name_row_col" -> e.g., "covariance_0_1"
162 std::string key = name + "_" + std::to_string(r) + "_" + std::to_string(c);
163
164 // Access matrix element at (row, col)
165 datafields[key] = new Variant(mat(r, c));
166 }
167 }
168 }
169
170 void
172 const std::string& name,
173 const Eigen::MatrixXf& mat)
174 {
175 // Pass by const reference (&) to avoid copying the matrix data
176 for (int r = 0; r < mat.rows(); ++r)
177 {
178 for (int c = 0; c < mat.cols(); ++c)
179 {
180 // Construct key: "name_row_col" -> e.g., "covariance_0_1"
181 std::string key = name + "_" + std::to_string(r) + "_" + std::to_string(c);
182
183 // Access matrix element at (row, col)
184 datafields[key] = new Variant(mat(r, c));
185 }
186 }
187 }
188
189 void
190 debugEigenVec(StringVariantBaseMap& datafields, const std::string& name, Eigen::VectorXf vec)
191 {
192 for (int i = 0; i < vec.size(); i++)
193 {
194 datafields[name + "_" + std::to_string(i)] = new Variant(vec(i));
195 }
196 }
197
198 void
199 debugStdVec(StringVariantBaseMap& datafields, const std::string& name, std::vector<float> vec)
200 {
201 for (size_t i = 0; i < vec.size(); i++)
202 {
203 datafields[name + "_" + std::to_string(i)] = new Variant(vec[i]);
204 }
205 }
206
207 void
208 to_json(nlohmann::json& j, const Pose& fp)
209 {
210 j = nlohmann::json{{"qw", fp.orientation->qw},
211 {"qx", fp.orientation->qx},
212 {"qy", fp.orientation->qy},
213 {"qz", fp.orientation->qz},
214 {"x", fp.position->x},
215 {"y", fp.position->y},
216 {"z", fp.position->z}};
217 }
218
219 void
220 from_json(const nlohmann::json& j, Pose& fp)
221 {
222 j.at("qw").get_to(fp.orientation->qw);
223 j.at("qx").get_to(fp.orientation->qx);
224 j.at("qy").get_to(fp.orientation->qy);
225 j.at("qz").get_to(fp.orientation->qz);
226 j.at("x").get_to(fp.position->x);
227 j.at("y").get_to(fp.position->y);
228 j.at("z").get_to(fp.position->z);
229 }
230
231 void
232 to_json(nlohmann::json& j, const PosePtr& fp)
233 {
234 if (fp)
235 {
236 to_json(j, *fp);
237 }
238 }
239
240 void
241 to_json(nlohmann::json& j, const PoseBasePtr& fp)
242 {
243 if (fp)
244 {
245 to_json(j, PosePtr::dynamicCast(fp));
246 }
247 }
248
249 void
250 from_json(const nlohmann::json& j, PoseBasePtr& fp)
251 {
252 PosePtr p = new Pose();
253 from_json(j, p);
254 fp = p;
255 }
256
257 void
258 from_json(const nlohmann::json& j, PosePtr& fp)
259 {
260 fp = new Pose();
261 from_json(j, *fp);
262 }
263
264 Eigen::Block<Eigen::Matrix4f, 3, 3>
265 getOri(Eigen::Matrix4f& matrix)
266 {
267 return matrix.block<3, 3>(0, 0);
268 }
269
270 Eigen::Matrix3f
271 getOri(const Eigen::Matrix4f& matrix)
272 {
273 return matrix.block<3, 3>(0, 0);
274 }
275
276 void
277 skew(const Eigen::Vector3f& vec, Eigen::Ref<Eigen::Matrix3f> result)
278 {
279 result.setZero();
280 result(1, 2) = -vec(0);
281 result(0, 2) = vec(1);
282 result(0, 1) = -vec(2);
283 result(2, 1) = vec(0);
284 result(2, 0) = -vec(1);
285 result(1, 0) = vec(2);
286 }
287
288 Eigen::Matrix3f
289 getOriT(const Eigen::Matrix4f& matrix)
290 {
291 return matrix.block<3, 3>(0, 0).transpose();
292 }
293
294 void
295 setOri(Eigen::Matrix4f& matrix, const Eigen::Ref<const Eigen::Matrix3f>& ori)
296 {
297 matrix.block<3, 3>(0, 0) = ori;
298 }
299
300 Eigen::Block<Eigen::Matrix4f, 3, 1>
301 getPos(Eigen::Matrix4f& matrix)
302 {
303 return matrix.block<3, 1>(0, 3);
304 }
305
306 void
307 setPos(Eigen::Matrix4f& matrix, const Eigen::Ref<const Eigen::Vector3f>& pos)
308 {
309 matrix.block<3, 1>(0, 3) = pos;
310 }
311
312 Eigen::Vector3f
313 getPos(const Eigen::Matrix4f& matrix)
314 {
315 return matrix.block<3, 1>(0, 3);
316 }
317
318 PosePtr
319 dVecToPose(const DVec& dvec)
320 {
321 return new Pose(dVecToMat4(dvec));
322 }
323
324 Eigen::Matrix4f
325 dVecToMat4(const DVec& dvec)
326 {
327 ARMARX_CHECK_EQUAL(dvec.size(), 7);
328 Eigen::Matrix4f mat = VirtualRobot::MathTools::quat2eigen4f(static_cast<float>(dvec[4]),
329 static_cast<float>(dvec[5]),
330 static_cast<float>(dvec[6]),
331 static_cast<float>(dvec[3]));
332 mat(0, 3) = static_cast<float>(dvec[0]);
333 mat(1, 3) = static_cast<float>(dvec[1]);
334 mat(2, 3) = static_cast<float>(dvec[2]);
335
336 return mat;
337 }
338
339 Eigen::Matrix4f
340 vec7fToMat4f(const Eigen::VectorXf& vec)
341 {
342 ARMARX_CHECK_EQUAL(vec.size(), 7);
343 Eigen::Matrix4f mat = VirtualRobot::MathTools::quat2eigen4f(vec[4], vec[5], vec[6], vec[3]);
344 mat(0, 3) = vec[0];
345 mat(1, 3) = vec[1];
346 mat(2, 3) = vec[2];
347
348 return mat;
349 }
350
351 DVec
353 {
354 Eigen::Matrix4f poseMat = pose->toEigen();
355 return mat4ToDVec(poseMat);
356 }
357
358 DVec
359 mat4ToDVec(const Eigen::Matrix4f& mat)
360 {
361 std::vector<double> result;
362 result.resize(7);
363
364 for (size_t i = 0; i < 3; ++i)
365 {
366 result.at(i) = static_cast<double>(mat(i, 3));
367 }
368
369 VirtualRobot::MathTools::Quaternion quat = VirtualRobot::MathTools::eigen4f2quat(mat);
370
371 result.at(3) = static_cast<double>(quat.w);
372 result.at(4) = static_cast<double>(quat.x);
373 result.at(5) = static_cast<double>(quat.y);
374 result.at(6) = static_cast<double>(quat.z);
375
376 return result;
377 }
378
379 std::vector<float>
381 {
382 Eigen::Matrix4f poseMat = pose->toEigen();
383 return mat4ToFVec(poseMat);
384 }
385
386 std::vector<float>
387 mat4ToFVec(const Eigen::Matrix4f& mat)
388 {
389 std::vector<float> result;
390 result.resize(7);
391
392 for (size_t i = 0; i < 3; ++i)
393 {
394 result.at(i) = mat(i, 3);
395 }
396
397 VirtualRobot::MathTools::Quaternion quat = VirtualRobot::MathTools::eigen4f2quat(mat);
398
399 result.at(3) = quat.w;
400 result.at(4) = quat.x;
401 result.at(5) = quat.y;
402 result.at(6) = quat.z;
403
404 return result;
405 }
406
407 std::string
408 dVecToString(const DVec& dvec)
409 {
410 std::string s = "";
411 for (const double& d : dvec)
412 {
413 s = s + std::to_string(d) + " | ";
414 }
415 return s;
416 }
417
418 Eigen::VectorXf
419 vecToEigen(std::vector<float>& vec)
420 {
421 return Eigen::Map<Eigen::VectorXf>(vec.data(), vec.size());
422 }
423
424 void
425 dvecToEigenf(std::vector<double>& vec, Eigen::VectorXf& result)
426 {
427 // Check size match
428 ARMARX_CHECK_EQUAL(result.size(), static_cast<Eigen::Index>(vec.size()))
429 << "Size of result VectorXf does not match input vector size.";
430
431 // Copy and cast
432 for (size_t i = 0; i < vec.size(); ++i)
433 {
434 result[i] = static_cast<float>(vec[i]);
435 }
436 }
437
438 std::string
439 sVecToString(const std::vector<std::string>& vec, const std::string& delimiter)
440 {
441 std::string s;
442 for (size_t i = 0; i < vec.size(); ++i)
443 {
444 if (i != 0)
445 {
446 s += delimiter;
447 }
448 s += vec[i];
449 }
450 return s;
451 }
452
453 mp::arondto::MPTraj
454 mpTrajFromFile(std::string filepath, bool containsHeader, bool noTimeStamp)
455 {
456 std::vector<double> timesteps;
457 std::vector<std::vector<double>> trajPoses;
458
459 std::ifstream f(filepath.c_str());
460
461 if (!f.is_open())
462 {
463 ARMARX_ERROR << "Could not open file: " + filepath;
464 }
465
466 using Tokenizer = boost::tokenizer<boost::escaped_list_separator<char>>;
467
468
469 // unsigned int stateDim = double().size();
470 unsigned int i = 1;
471
472 double current_time = 0;
473 std::string line;
474 std::vector<std::string> stringVec;
475 while (getline(f, line))
476 {
477 if (containsHeader && i == 1)
478 {
479 i++;
480 continue;
481 }
482
483 Tokenizer tok(line);
484 stringVec.assign(tok.begin(), tok.end());
485
486 if (stringVec.size() == 0)
487 {
488 std::cout << "Line " << i << " is invalid skipping: " << line << std::endl;
489 continue;
490 }
491
492 unsigned int j = 1;
493
494 armarx::control::common::mp::arondto::MPTraj traj;
495
496 //TrajData entry(*this);
497 // int size = stringVec.size() - 1;
498 if (noTimeStamp)
499 {
500 j = 0;
501 //entry.timestamp = current_time;
502 timesteps.push_back(current_time);
503 current_time += 0.01;
504 // size = stringVec.size();
505 }
506 else
507 {
508 //entry.timestamp = math::util::fromString<double>(stringVec[0]);
509 timesteps.push_back(std::stod(stringVec[0]));
510 }
511
512 // DVec values(int(ceil(size/stateDim)*stateDim), 0.0);
513 //DVec values(size, 0.0);
514 std::vector<double> currentPose;
515
516 for (unsigned int k = j; k < stringVec.size(); ++k)
517 {
518 currentPose.push_back(std::stod(stringVec[k]));
519 //values.at(sd) = (math::util::fromString<double>(stringVec[j]));
520 //math::util::checkValue(values.at(sd));
521 }
522 trajPoses.push_back(currentPose);
523
524 i++;
525 }
526
527 // convert to aron types
528 if (timesteps.size() != trajPoses.size())
529 {
530 ARMARX_ERROR << "consistency error in reading trajectory";
531 }
532 armarx::control::common::mp::arondto::MPTraj taskTraj;
533 taskTraj.time.setZero(timesteps.size());
534 taskTraj.traj.setZero(timesteps.size(), trajPoses.at(0).size());
535 // ARMARX_INFO << "no timesteps" << timesteps.size();
536 // ARMARX_INFO << "traj pose dim " << trajPoses.at(0).size();
537 for (unsigned int l = 0; l < timesteps.size(); l++)
538 {
539 taskTraj.time(l) = timesteps.at(l);
540 for (size_t j = 0; j < trajPoses.at(0).size(); ++j)
541 taskTraj.traj(l, j) = trajPoses.at(l).at(j);
542 }
543 return taskTraj;
544 }
545
546 mp::arondto::MPTraj
547 createDummyTraj(const int dimension, const int timesteps)
548 {
549 mp::arondto::MPTraj traj;
550 traj.time = Eigen::VectorXd::LinSpaced(timesteps, 0, 1);
551 traj.traj = Eigen::MatrixXd::Zero(timesteps, dimension);
552 return traj;
553 }
554
555 mp::arondto::MPConfig
557 const std::string& name,
558 const std::string& nodeSetName,
559 const double& durationSec,
560 const std::vector<mp::arondto::MPTraj>& mpTraj,
561 const std::vector<mp::arondto::ListViaPoint>& viaPointList)
562 {
563 const std::string className = mpTypeToString.to_name(mpType);
564 const armarx::PackagePath configPath(
565 "armarx_control", "controller_config/mp/default_mp_" + className + ".json");
566 ARMARX_INFO << "using default config as base: " << configPath.toSystemPath();
567
569 cfg.name = name;
570 cfg.nodeSetName = nodeSetName;
571 if (durationSec > 0.0)
572 {
573 ARMARX_INFO << "set duration to " << durationSec << " sec";
574 cfg.durationSec = durationSec;
575 }
576 if (mpTraj.size() > 0)
577 {
578 ARMARX_INFO << "set trajectory with " << mpTraj.size() << " segments";
579 cfg.trajectoryList = mpTraj;
580 }
581 if (viaPointList.size() > 0)
582 {
583 ARMARX_INFO << "set " << viaPointList.size() << " via points";
584 cfg.viaPoints = viaPointList;
585 }
586 return cfg;
587 }
588
589 mp::arondto::MPConfig
591 const std::string& name,
592 const std::string& nodeSetName,
593 const double& durationSec,
594 const std::vector<std::string>& mpTraj,
595 const std::vector<mp::arondto::ListViaPoint>& viaPointList)
596 {
597 std::vector<mp::arondto::MPTraj> mpTrajList{};
598 for (auto& f : mpTraj)
599 {
600 mpTrajList.push_back(mpTrajFromFile(f));
601 }
602 return getDefaultMPConfig(mpType, name, nodeSetName, durationSec, mpTrajList, viaPointList);
603 }
604
605 void
606 addViaPoint(mp::arondto::MPConfig& cfg,
607 const double& canValue,
608 const std::vector<double>& viaPoint)
609 {
610 auto vp = mp::arondto::ListViaPoint();
611 vp.canonicalValue = canValue;
612 vp.viaPointValue = viaPoint;
613 cfg.viaPoints.push_back(vp);
614 }
615
616 void
617 addViaPoint(mp::arondto::MPConfig& cfg,
618 const double& canValue,
619 const std::vector<float>& viaPoint)
620 {
621 std::vector<double> viaPointVec;
622 std::transform(viaPoint.begin(),
623 viaPoint.end(),
624 std::back_inserter(viaPointVec),
625 [](float value) { return static_cast<double>(value); });
626 addViaPoint(cfg, canValue, viaPointVec);
627 }
628
629 void
630 addViaPoint(mp::arondto::MPConfig& cfg, const double& canValue, const Eigen::VectorXf& viaPoint)
631 {
632 std::vector<double> viaPointVec;
633 std::transform(viaPoint.data(),
634 viaPoint.data() + viaPoint.size(),
635 std::back_inserter(viaPointVec),
636 [](float value) { return static_cast<double>(value); });
637 addViaPoint(cfg, canValue, viaPointVec);
638 }
639
640 void
641 addViaPoint(mp::arondto::MPConfig& cfg, const double& canValue, const Eigen::Matrix4f& viaPose)
642 {
643 auto viaPointVec = mat4ToDVec(viaPose);
644 addViaPoint(cfg, canValue, viaPointVec);
645 }
646
647 void
648 validateTSViaPoint(std::vector<double>& viaPoint, std::vector<double>& viaPointReference)
649 {
650 if (viaPoint.size() != 7 || viaPointReference.size() != 7)
651 {
652 ARMARX_ERROR << "Both viapoints must have exactly 7 elements";
653 }
654
655 bool allDifferentSigns = true;
656
657 // Check signs for the last 4 elements
658 for (int i = 3; i < 7; ++i)
659 {
660 if ((viaPoint[i] * viaPointReference[i]) >= 0)
661 {
662 allDifferentSigns = false;
663 break;
664 }
665 }
666
667 // If all last 4 elements have different signs, flip their signs
668 if (allDifferentSigns)
669 {
670 ARMARX_VERBOSE << "===> Viapoints for TS Orientation on two hemisphere, flipping sign";
671 for (int i = 3; i < 7; ++i)
672 {
673 viaPoint[i] = -viaPoint[i];
674 }
675 }
676 }
677
678 void
679 appendToViapointList(std::vector<mp::arondto::ListViaPoint>& vpList,
680 const double canonicalValue,
681 const std::vector<double>& viaPoint)
682 {
683 mp::arondto::ListViaPoint vp;
684 vp.canonicalValue = canonicalValue;
685 vp.viaPointValue = viaPoint;
686 vpList.push_back(vp);
687 }
688
689 void
690 appendToViapointList(std::vector<mp::arondto::ListViaPoint>& vpList,
691 const double canonicalValue,
692 const std::vector<float>& viaPoint)
693 {
694 std::vector<double> viaPointVec;
695 std::transform(viaPoint.begin(),
696 viaPoint.end(),
697 std::back_inserter(viaPointVec),
698 [](float value) { return static_cast<double>(value); });
699 appendToViapointList(vpList, canonicalValue, viaPointVec);
700 }
701
702 void
703 appendToViapointList(std::vector<mp::arondto::ListViaPoint>& vpList,
704 const double canonicalValue,
705 const Eigen::VectorXf& viaPoint)
706 {
707 std::vector<double> viaPointVec;
708 std::transform(viaPoint.data(),
709 viaPoint.data() + viaPoint.size(),
710 std::back_inserter(viaPointVec),
711 [](float value) { return static_cast<double>(value); });
712 appendToViapointList(vpList, canonicalValue, viaPointVec);
713 }
714
715 void
716 appendToViapointList(std::vector<mp::arondto::ListViaPoint>& vpList,
717 const double canonicalValue,
718 const Eigen::Matrix4f& viaPose)
719 {
720 auto viaPointVec = mat4ToDVec(viaPose);
721 appendToViapointList(vpList, canonicalValue, viaPointVec);
722 }
723
724 float
725 getDeltaAngleBetweenRotMat(const Eigen::Matrix3f& rotMat1, const Eigen::Matrix3f& rotMat2)
726 {
727 Eigen::Matrix3f poseDiffMatImp = rotMat1 * rotMat2.transpose();
728 Eigen::AngleAxisf oriDiffAngleAxis;
729 oriDiffAngleAxis.fromRotationMatrix(poseDiffMatImp);
730 float angle = VirtualRobot::MathTools::angleModPI(oriDiffAngleAxis.angle());
731 angle = std::fminf(angle, 2 * M_PI - angle);
732 return angle;
733 }
734
735 float
736 getDeltaAngleBetweenPose(const Eigen::Matrix4f& pose1, const Eigen::Matrix4f& pose2)
737 {
738 return getDeltaAngleBetweenRotMat(pose1.block<3, 3>(0, 0), pose2.block<3, 3>(0, 0));
739 }
740
741 bool
742 poseDeviationTooLarge(const Eigen::Matrix4f& currentPose,
743 const Eigen::Matrix4f& desiredPose,
744 float positionThrMM,
745 float angleThrDeg)
746 {
747 float angle = getDeltaAngleBetweenPose(currentPose, desiredPose);
748 return (desiredPose.block<3, 1>(0, 3) - currentPose.block<3, 1>(0, 3)).norm() >
749 positionThrMM or
750 angle > VirtualRobot::MathTools::deg2rad(angleThrDeg);
751 }
752
753 void
754 reportPoseDeviationWarning(const std::string& who,
755 const Eigen::Matrix4f& pose1,
756 const Eigen::Matrix4f& pose2,
757 const std::string& namePose1,
758 const std::string& namePose2)
759 {
760 auto quat1 = VirtualRobot::MathTools::eigen4f2quat(pose1);
761 auto quat2 = VirtualRobot::MathTools::eigen4f2quat(pose2);
762 ARMARX_INFO << deactivateSpam(2) << "-- " << who << " " << namePose2
763 << " (x, y, z, qw, qx, qy, qz) \n\n"
764 << " [ " << pose2(0, 3) << ", " << pose2(1, 3) << ", " << pose2(2, 3) << ", "
765 << quat2.w << ", " << quat2.x << ", " << quat2.y << ", " << quat2.z << " ]\n\n"
766 << " is too far away from the " << namePose1
767 << " (x, y, z, qw, qx, qy, qz) \n\n"
768 << " [ " << pose1(0, 3) << ", " << pose1(1, 3) << ", " << pose1(2, 3) << ", "
769 << quat1.w << ", " << quat1.x << ", " << quat1.y << ", " << quat1.z << " ].";
770 }
771
772 bool
773 detectAndReportPoseDeviationWarning(const Eigen::Matrix4f& pose1,
774 const Eigen::Matrix4f& pose2,
775 const std::string& namePose1,
776 const std::string& namePose2,
777 float positionThrMM,
778 float angleThrDeg,
779 const std::string& who)
780 {
781 float angle = getDeltaAngleBetweenPose(pose1, pose2);
782 float dist = (pose2.block<3, 1>(0, 3) - pose1.block<3, 1>(0, 3)).norm();
783
784 bool flagToReport =
785 dist > positionThrMM or angle > VirtualRobot::MathTools::deg2rad(angleThrDeg);
786 if (flagToReport)
787 {
788 reportPoseDeviationWarning(who, pose1, pose2, namePose1, namePose2);
789 ARMARX_INFO << deactivateSpam(2) << "-- Delta distance (mm) " << dist << " > "
790 << positionThrMM << " or angle (rad) " << angle << " > "
791 << VirtualRobot::MathTools::deg2rad(angleThrDeg);
792 }
793 return flagToReport;
794 }
795
796 Eigen::Matrix4f
797 mirrorLeftRightPose(Eigen::Matrix4f& sourcePose)
798 {
799 Eigen::Matrix4f convert;
800 convert << 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1;
801 return sourcePose.cwiseProduct(convert);
802 }
803
804 Eigen::Matrix4f
805 mirrorLeftRightOri(Eigen::Matrix4f& sourcePose)
806 {
807 Eigen::Matrix4f convert;
808 convert << 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1;
809 return sourcePose.cwiseProduct(convert);
810 }
811
812 Eigen::Matrix3f
813 mirrorLeftRightOri(Eigen::Matrix3f& sourcePose)
814 {
815 Eigen::Matrix3f convert;
816 convert << 1, -1, -1, -1, 1, 1, -1, 1, 1;
817 return sourcePose.cwiseProduct(convert);
818 }
819
820} // namespace armarx::control::common
SpamFilterDataPtr deactivateSpam(SpamFilterDataPtr const &spamFilter, float deactivationDurationSec, const std::string &identifier, bool deactivate)
Definition Logging.cpp:75
#define M_PI
Definition MathTools.h:17
#define VAROUT(x)
constexpr T c
static std::filesystem::path toSystemPath(const data::PackagePath &pp)
The Pose class.
Definition Pose.h:243
The Variant class is described here: Variants.
Definition Variant.h:224
#define ARMARX_CHECK_GREATER_EQUAL(lhs, rhs)
This macro evaluates whether lhs is greater or equal (>=) rhs and if it turns out to be false it will...
#define ARMARX_CHECK_EQUAL(lhs, rhs)
This macro evaluates whether lhs is equal (==) rhs and if it turns out to be false it will throw an E...
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
#define ARMARX_IMPORTANT
The logging level for always important information, but expected behaviour (in contrast to ARMARX_WAR...
Definition Logging.h:190
#define ARMARX_ERROR
The logging level for unexpected behaviour, that must be fixed.
Definition Logging.h:196
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
Definition Logging.h:193
#define ARMARX_VERBOSE
The logging level for verbose information.
Definition Logging.h:187
Quaternion< double, 0 > Quaterniond
Eigen::Vector4f calculateTransitionWeights(float z1, float z2)
helper functions
Definition utils.cpp:25
This file is part of ArmarX.
void reportPoseDeviationWarning(const std::string &who, const Eigen::Matrix4f &pose1, const Eigen::Matrix4f &pose2, const std::string &namePose1, const std::string &namePose2)
Definition utils.cpp:754
void from_json(const nlohmann::json &j, Pose &fp)
Definition utils.cpp:220
Eigen::Matrix4f mirrorLeftRightOri(Eigen::Matrix4f &sourcePose)
Definition utils.cpp:805
Eigen::VectorXf getEigenVec(nlohmann::json &userConfig, nlohmann::json &defaultConfig, const std::string &entryName, int size, int value)
Definition utils.cpp:50
void addViaPoint(mp::arondto::MPConfig &cfg, const double &canValue, const std::vector< double > &viaPoint)
Definition utils.cpp:606
DVec poseToDVec(PosePtr &pose)
Definition utils.cpp:352
bool detectAndReportPoseDeviationWarning(const Eigen::Matrix4f &pose1, const Eigen::Matrix4f &pose2, const std::string &namePose1, const std::string &namePose2, float positionThrMM, float angleThrDeg, const std::string &who)
Definition utils.cpp:773
Eigen::Matrix3f getOriT(const Eigen::Matrix4f &matrix)
Definition utils.cpp:289
bool poseDeviationTooLarge(const Eigen::Matrix4f &currentPose, const Eigen::Matrix4f &desiredPose, float positionThrMM, float angleThrDeg)
Definition utils.cpp:742
void getError(Eigen::Matrix4f &currentPose, Eigen::Vector3d &targetPosition, Eigen::Quaterniond &targetQuaternion, double &posiError, double &oriError)
Definition utils.cpp:121
void setOri(Eigen::Matrix4f &matrix, const Eigen::Ref< const Eigen::Matrix3f > &ori)
Definition utils.cpp:295
void debugEigenVec(StringVariantBaseMap &datafields, const std::string &name, Eigen::VectorXf vec)
Definition utils.cpp:190
mp::arondto::MPTraj mpTrajFromFile(std::string filepath, bool containsHeader, bool noTimeStamp)
Definition utils.cpp:454
mp::arondto::MPConfig getDefaultMPConfig(MPType mpType, const std::string &name, const std::string &nodeSetName, const double &durationSec, const std::vector< mp::arondto::MPTraj > &mpTraj, const std::vector< mp::arondto::ListViaPoint > &viaPointList)
Definition utils.cpp:556
PosePtr dVecToPose(const DVec &dvec)
Definition utils.cpp:319
float getDeltaAngleBetweenPose(const Eigen::Matrix4f &pose1, const Eigen::Matrix4f &pose2)
Definition utils.cpp:736
Eigen::Block< Eigen::Matrix4f, 3, 3 > getOri(Eigen::Matrix4f &matrix)
Definition utils.cpp:265
Eigen::Matrix4f vec7fToMat4f(const Eigen::VectorXf &vec)
Definition utils.cpp:340
Eigen::Matrix4f dVecToMat4(const DVec &dvec)
create Eigen:Matrix4f from 7D double vector.
Definition utils.cpp:325
void getEigenMatrix(nlohmann::json &userConfig, const std::string &entryName, Eigen::MatrixXf &mat)
Definition utils.cpp:76
const simox::meta::EnumNames< MPType > mpTypeToString
Definition type.h:112
void validateTSViaPoint(std::vector< double > &viaPoint, std::vector< double > &viaPointReference)
Definition utils.cpp:648
void debugEigenPose(StringVariantBaseMap &datafields, const std::string &name, Eigen::Matrix4f pose)
Definition utils.cpp:140
std::vector< double > DVec
Definition utils.h:47
float getDeltaAngleBetweenRotMat(const Eigen::Matrix3f &rotMat1, const Eigen::Matrix3f &rotMat2)
Definition utils.cpp:725
void setPos(Eigen::Matrix4f &matrix, const Eigen::Ref< const Eigen::Vector3f > &pos)
Definition utils.cpp:307
Eigen::VectorXf vecToEigen(std::vector< float > &vec)
Definition utils.cpp:419
void to_json(nlohmann::json &j, const Pose &fp)
Definition utils.cpp:208
DVec mat4ToDVec(const Eigen::Matrix4f &mat)
convert Eigen:Matrix4f to 7D double vector.
Definition utils.cpp:359
void dvecToEigenf(std::vector< double > &vec, Eigen::VectorXf &result)
Definition utils.cpp:425
Eigen::VectorXf getEigenVecWithDefault(nlohmann::json &userConfig, Eigen::VectorXf defaultValue, const std::string &entryName)
Definition utils.cpp:103
void appendToViapointList(std::vector< mp::arondto::ListViaPoint > &vpList, const double canonicalValue, const std::vector< double > &viaPoint)
Definition utils.cpp:679
Eigen::Matrix4f mirrorLeftRightPose(Eigen::Matrix4f &sourcePose)
Definition utils.cpp:797
void skew(const Eigen::Vector3f &vec, Eigen::Ref< Eigen::Matrix3f > result)
Definition utils.cpp:277
std::vector< float > mat4ToFVec(const Eigen::Matrix4f &mat)
Definition utils.cpp:387
mp::arondto::MPTraj createDummyTraj(const int dimension, const int timesteps)
create a dummy trajectory that only has zeros for every dimension.
Definition utils.cpp:547
void debugEigenMat(StringVariantBaseMap &datafields, const std::string &name, const Eigen::MatrixXd &mat)
Definition utils.cpp:152
std::string sVecToString(const std::vector< std::string > &vec, const std::string &delimiter)
Definition utils.cpp:439
void debugStdVec(StringVariantBaseMap &datafields, const std::string &name, std::vector< float > vec)
Definition utils.cpp:199
Eigen::Block< Eigen::Matrix4f, 3, 1 > getPos(Eigen::Matrix4f &matrix)
Definition utils.cpp:301
std::string dVecToString(const DVec &dvec)
Definition utils.cpp:408
std::vector< float > poseToFVec(PosePtr &pose)
Definition utils.cpp:380
std::map< std::string, VariantBasePtr > StringVariantBaseMap
AronDTO readFromJson(const std::filesystem::path &filename)
IceInternal::Handle< Pose > PosePtr
Definition Pose.h:306
std::vector< std::vector< T > > transpose(const std::vector< std::vector< T > > &src, Thrower thrower)
armem::articulated_object::ArticulatedObject convert(const VirtualRobot::Robot &obj, const armem::Time &timestamp)
double norm(const Point &a)
Definition point.hpp:102
double angle(const Point &a, const Point &b, const Point &c)
Definition point.hpp:109