10 #include <boost/tokenizer.hpp>
12 #include <VirtualRobot/MathTools.h>
24 nlohmann::json& defaultConfig,
25 const std::string& entryName,
29 if (userConfig.find(entryName) != userConfig.end())
31 auto vec = userConfig[entryName].get<std::vector<float>>();
34 return Eigen::Map<Eigen::VectorXf>(vec.data(), vec.size());
38 return Eigen::VectorXf::Ones(size) *
value;
41 <<
" have size 0, fall back to default";
44 auto vec = defaultConfig[entryName].get<std::vector<float>>();
45 return Eigen::Map<Eigen::VectorXf>(vec.data(), vec.size());
49 getEigenMatrix(nlohmann::json& userConfig,
const std::string& entryName, Eigen::MatrixXf& mat)
51 if (userConfig.find(entryName) != userConfig.end())
53 auto vec = userConfig[entryName].get<std::vector<std::vector<float>>>();
54 int rows = vec.size();
55 int cols = vec[0].size();
59 mat.resize(rows, cols);
60 for (
int i = 0; i < rows; i++)
62 for (
int j = 0; j < cols; j++)
64 mat(i, j) = vec[i][j];
77 Eigen::VectorXf defaultValue,
78 const std::string& entryName)
80 if (userConfig.find(entryName) != userConfig.end())
82 auto vec = userConfig[entryName].get<std::vector<float>>();
83 if (vec.size() ==
static_cast<unsigned>(defaultValue.size()))
85 return Eigen::Map<Eigen::VectorXf>(vec.data(), vec.size());
87 ARMARX_WARNING <<
"size of the user defined parameter " << entryName
88 <<
" doesn't correspond to default size, use default value instead";
95 Eigen::Vector3d& targetPosition,
100 Eigen::Matrix4d currentPosed = currentPose.cast<
double>();
101 Eigen::Vector3d currentPosid = currentPosed.block<3, 1>(0, 3);
102 posiError = (currentPosid - targetPosition).
norm();
105 oriError = targetQuaternion.angularDistance(currentOrientation);
108 oriError = 2 *
M_PI - oriError;
115 Eigen::Vector3f rpy = VirtualRobot::MathTools::eigen4f2rpy(pose);
116 datafields[name +
"_x"] =
new Variant(pose(0, 3));
117 datafields[name +
"_y"] =
new Variant(pose(1, 3));
118 datafields[name +
"_z"] =
new Variant(pose(2, 3));
119 datafields[name +
"_rx"] =
new Variant(rpy(0));
120 datafields[name +
"_ry"] =
new Variant(rpy(1));
121 datafields[name +
"_rz"] =
new Variant(rpy(2));
127 for (
int i = 0; i < vec.size(); i++)
136 for (
size_t i = 0; i < vec.size(); i++)
145 j = nlohmann::json{{
"qw", fp.orientation->qw},
146 {
"qx", fp.orientation->qx},
147 {
"qy", fp.orientation->qy},
148 {
"qz", fp.orientation->qz},
149 {
"x", fp.position->x},
150 {
"y", fp.position->y},
151 {
"z", fp.position->z}};
157 j.at(
"qw").get_to(fp.orientation->qw);
158 j.at(
"qx").get_to(fp.orientation->qx);
159 j.at(
"qy").get_to(fp.orientation->qy);
160 j.at(
"qz").get_to(fp.orientation->qz);
161 j.at(
"x").get_to(fp.position->x);
162 j.at(
"y").get_to(fp.position->y);
163 j.at(
"z").get_to(fp.position->z);
176 to_json(nlohmann::json& j,
const PoseBasePtr& fp)
180 to_json(j, PosePtr::dynamicCast(fp));
199 Eigen::Block<Eigen::Matrix4f, 3, 3>
202 return matrix.block<3, 3>(0, 0);
205 Eigen::Block<Eigen::Matrix4f, 3, 1>
208 return matrix.block<3, 1>(0, 3);
221 Eigen::Matrix4f mat = VirtualRobot::MathTools::quat2eigen4f(
static_cast<float>(dvec[4]),
222 static_cast<float>(dvec[5]),
223 static_cast<float>(dvec[6]),
224 static_cast<float>(dvec[3]));
225 mat(0, 3) =
static_cast<float>(dvec[0]);
226 mat(1, 3) =
static_cast<float>(dvec[1]);
227 mat(2, 3) =
static_cast<float>(dvec[2]);
242 std::vector<double> result;
245 for (
size_t i = 0; i < 3; ++i)
247 result.at(i) =
static_cast<double>(mat(i, 3));
252 result.at(3) =
static_cast<double>(quat.w);
253 result.at(4) =
static_cast<double>(quat.x);
254 result.at(5) =
static_cast<double>(quat.y);
255 result.at(6) =
static_cast<double>(quat.z);
270 std::vector<float> result;
273 for (
size_t i = 0; i < 3; ++i)
275 result.at(i) = mat(i, 3);
280 result.at(3) = quat.w;
281 result.at(4) = quat.x;
282 result.at(5) = quat.y;
283 result.at(6) = quat.z;
292 for (
const double& d : dvec)
302 return Eigen::Map<Eigen::VectorXf>(vec.data(), vec.size());
306 sVecToString(
const std::vector<std::string>& vec,
const std::string& delimiter)
309 for (
size_t i = 0; i < vec.size(); ++i)
323 std::vector<double> timesteps;
324 std::vector<std::vector<double>> trajPoses;
326 std::ifstream f(filepath.c_str());
333 using Tokenizer = boost::tokenizer<boost::escaped_list_separator<char>>;
339 double current_time = 0;
341 std::vector<std::string> stringVec;
342 while (getline(f, line))
344 if (containsHeader && i == 1)
351 stringVec.assign(tok.begin(), tok.end());
353 if (stringVec.size() == 0)
355 std::cout <<
"Line " << i <<
" is invalid skipping: " << line << std::endl;
361 armarx::control::common::mp::arondto::MPTraj traj;
364 int size = stringVec.size() - 1;
369 timesteps.push_back(current_time);
370 current_time += 0.01;
371 size = stringVec.size();
376 timesteps.push_back(std::stod(stringVec[0]));
381 std::vector<double> currentPose;
383 for (
unsigned int k = j; k < stringVec.size(); ++k)
385 currentPose.push_back(std::stod(stringVec[k]));
389 trajPoses.push_back(currentPose);
395 if (timesteps.size() != trajPoses.size())
397 ARMARX_ERROR <<
"consistency error in reading trajectory";
399 armarx::control::common::mp::arondto::MPTraj taskTraj;
400 taskTraj.time.setZero(timesteps.size());
401 taskTraj.traj.setZero(timesteps.size(), trajPoses.at(0).size());
403 ARMARX_INFO <<
"traj pose dim " << trajPoses.at(0).size();
404 for (
unsigned int l = 0; l < timesteps.size(); l++)
406 taskTraj.time(l) = timesteps.at(l);
407 for (
size_t j = 0; j < trajPoses.at(0).size(); ++j)
408 taskTraj.traj(l, j) = trajPoses.at(l).at(j);
416 mp::arondto::MPTraj traj;
417 traj.time = Eigen::VectorXd::LinSpaced(timesteps, 0, 1);
418 traj.traj = Eigen::MatrixXd::Zero(timesteps, dimension);
422 mp::arondto::MPConfig
424 const std::string& name,
425 const std::string& nodeSetName,
426 const double& durationSec,
427 const std::vector<mp::arondto::MPTraj>& mpTraj,
428 const std::vector<mp::arondto::ListViaPoint>& viaPointList)
432 "armarx_control",
"controller_config/mp/default_mp_" + className +
".json");
434 auto cfg = armarx::readFromJson<mp::arondto::MPConfig>(configPath.
toSystemPath());
436 cfg.nodeSetName = nodeSetName;
437 if (durationSec > 0.0)
438 cfg.durationSec = durationSec;
439 if (mpTraj.size() > 0)
440 cfg.trajectoryList = mpTraj;
441 if (viaPointList.size() > 0)
442 cfg.viaPoints = viaPointList;
446 mp::arondto::MPConfig
448 const std::string& name,
449 const std::string& nodeSetName,
450 const double& durationSec,
451 const std::vector<std::string>& mpTraj,
452 const std::vector<mp::arondto::ListViaPoint>& viaPointList)
454 std::vector<mp::arondto::MPTraj> mpTrajList{};
455 for (
auto& f : mpTraj)
459 return getDefaultMPConfig(mpType, name, nodeSetName, durationSec, mpTrajList, viaPointList);
464 const double& canValue,
465 const std::vector<double>& viaPoint)
467 auto vp = mp::arondto::ListViaPoint();
468 vp.canonicalValue = canValue;
469 vp.viaPointValue = viaPoint;
470 cfg.viaPoints.push_back(vp);
475 const double& canValue,
476 const std::vector<float>& viaPoint)
478 std::vector<double> viaPointVec;
481 std::back_inserter(viaPointVec),
482 [](
float value) { return static_cast<double>(value); });
487 addViaPoint(mp::arondto::MPConfig& cfg,
const double& canValue,
const Eigen::VectorXf& viaPoint)
489 std::vector<double> viaPointVec;
491 viaPoint.data() + viaPoint.size(),
492 std::back_inserter(viaPointVec),
493 [](
float value) { return static_cast<double>(value); });
506 const double canonicalValue,
507 const std::vector<double>& viaPoint)
509 mp::arondto::ListViaPoint vp;
510 vp.canonicalValue = canonicalValue;
511 vp.viaPointValue = viaPoint;
512 vpList.push_back(vp);
517 const double canonicalValue,
518 const std::vector<float>& viaPoint)
520 std::vector<double> viaPointVec;
523 std::back_inserter(viaPointVec),
524 [](
float value) { return static_cast<double>(value); });
530 const double canonicalValue,
531 const Eigen::VectorXf& viaPoint)
533 std::vector<double> viaPointVec;
535 viaPoint.data() + viaPoint.size(),
536 std::back_inserter(viaPointVec),
537 [](
float value) { return static_cast<double>(value); });
543 const double canonicalValue,
555 Eigen::AngleAxisf oriDiffAngleAxis;
556 oriDiffAngleAxis.fromRotationMatrix(poseDiffMatImp);
557 float angle = VirtualRobot::MathTools::angleModPI(oriDiffAngleAxis.angle());
576 return (desiredPose.block<3, 1>(0, 3) - currentPose.block<3, 1>(0, 3)).norm() > positionThrMM or
577 angle > VirtualRobot::MathTools::deg2rad(angleThrDeg);
582 const std::string& who,
585 const std::string& namePose1,
586 const std::string& namePose2)
588 auto quat1 = VirtualRobot::MathTools::eigen4f2quat(pose1);
589 auto quat2 = VirtualRobot::MathTools::eigen4f2quat(pose2);
591 << pose2(0, 3) <<
", " << pose2(1, 3) <<
", " << pose2(2, 3) <<
", "
592 << quat2.w <<
", " << quat2.x <<
", " << quat2.y <<
", " << quat2.z
593 <<
" ]\n\n is too far away from the " << namePose1 <<
" \n\n[ "
594 << pose1(0, 3) <<
", " << pose1(1, 3) <<
", " << pose1(2, 3) <<
", "
595 << quat1.w <<
", " << quat1.x <<
", " << quat1.y <<
", " << quat1.z
603 const std::string& namePose1,
604 const std::string& namePose2,
607 const std::string& who)
610 float dist = (pose2.block<3, 1>(0, 3) - pose1.block<3, 1>(0, 3)).
norm();
612 bool flagToReport = dist > positionThrMM or
angle > VirtualRobot::MathTools::deg2rad(angleThrDeg);
624 convert << 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1;
625 return sourcePose.cwiseProduct(
convert);
631 convert << 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1;
632 return sourcePose.cwiseProduct(
convert);
638 convert << 1, -1, -1, -1, 1, 1, -1, 1, 1;
639 return sourcePose.cwiseProduct(
convert);