10#include <boost/tokenizer.hpp>
12#include <VirtualRobot/MathTools.h>
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,
46 return constraintMatrix.colPivHouseholderQr().solve(b);
51 nlohmann::json& defaultConfig,
52 const std::string& entryName,
56 if (userConfig.find(entryName) != userConfig.end())
58 auto vec = userConfig[entryName].get<std::vector<float>>();
61 return Eigen::Map<Eigen::VectorXf>(vec.data(), vec.size());
65 return Eigen::VectorXf::Ones(size) * value;
68 <<
" have size 0, fall back to default";
71 auto vec = defaultConfig[entryName].get<std::vector<float>>();
72 return Eigen::Map<Eigen::VectorXf>(vec.data(), vec.size());
76 getEigenMatrix(nlohmann::json& userConfig,
const std::string& entryName, Eigen::MatrixXf& mat)
78 if (userConfig.find(entryName) != userConfig.end())
80 auto vec = userConfig[entryName].get<std::vector<std::vector<float>>>();
81 int rows = vec.size();
82 int cols = vec[0].size();
86 mat.resize(rows, cols);
87 for (
int i = 0; i < rows; i++)
89 for (
int j = 0; j < cols; j++)
91 mat(i, j) = vec[i][j];
104 Eigen::VectorXf defaultValue,
105 const std::string& entryName)
107 if (userConfig.find(entryName) != userConfig.end())
109 auto vec = userConfig[entryName].get<std::vector<float>>();
110 if (vec.size() ==
static_cast<unsigned>(defaultValue.size()))
112 return Eigen::Map<Eigen::VectorXf>(vec.data(), vec.size());
114 ARMARX_WARNING <<
"size of the user defined parameter " << entryName
115 <<
" doesn't correspond to default size, use default value instead";
122 Eigen::Vector3d& targetPosition,
127 Eigen::Matrix4d currentPosed = currentPose.cast<
double>();
128 Eigen::Vector3d currentPosid = currentPosed.block<3, 1>(0, 3);
129 posiError = (currentPosid - targetPosition).
norm();
132 oriError = targetQuaternion.angularDistance(currentOrientation);
135 oriError = 2 *
M_PI - oriError;
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));
153 const std::string& name,
154 const Eigen::MatrixXd& mat)
157 for (
int r = 0; r < mat.rows(); ++r)
159 for (
int c = 0;
c < mat.cols(); ++
c)
162 std::string key = name +
"_" + std::to_string(r) +
"_" + std::to_string(
c);
165 datafields[key] =
new Variant(mat(r,
c));
172 const std::string& name,
173 const Eigen::MatrixXf& mat)
176 for (
int r = 0; r < mat.rows(); ++r)
178 for (
int c = 0;
c < mat.cols(); ++
c)
181 std::string key = name +
"_" + std::to_string(r) +
"_" + std::to_string(
c);
184 datafields[key] =
new Variant(mat(r,
c));
192 for (
int i = 0; i < vec.size(); i++)
194 datafields[name +
"_" + std::to_string(i)] =
new Variant(vec(i));
201 for (
size_t i = 0; i < vec.size(); i++)
203 datafields[name +
"_" + std::to_string(i)] =
new Variant(vec[i]);
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}};
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);
241 to_json(nlohmann::json& j,
const PoseBasePtr& fp)
245 to_json(j, PosePtr::dynamicCast(fp));
264 Eigen::Block<Eigen::Matrix4f, 3, 3>
267 return matrix.block<3, 3>(0, 0);
273 return matrix.block<3, 3>(0, 0);
277 skew(
const Eigen::Vector3f& vec, Eigen::Ref<Eigen::Matrix3f> result)
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);
291 return matrix.block<3, 3>(0, 0).
transpose();
295 setOri(Eigen::Matrix4f& matrix,
const Eigen::Ref<const Eigen::Matrix3f>& ori)
297 matrix.block<3, 3>(0, 0) = ori;
300 Eigen::Block<Eigen::Matrix4f, 3, 1>
303 return matrix.block<3, 1>(0, 3);
307 setPos(Eigen::Matrix4f& matrix,
const Eigen::Ref<const Eigen::Vector3f>& pos)
309 matrix.block<3, 1>(0, 3) = pos;
315 return matrix.block<3, 1>(0, 3);
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]);
343 Eigen::Matrix4f mat = VirtualRobot::MathTools::quat2eigen4f(vec[4], vec[5], vec[6], vec[3]);
354 Eigen::Matrix4f poseMat = pose->toEigen();
361 std::vector<double> result;
364 for (
size_t i = 0; i < 3; ++i)
366 result.at(i) =
static_cast<double>(mat(i, 3));
369 VirtualRobot::MathTools::Quaternion quat = VirtualRobot::MathTools::eigen4f2quat(mat);
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);
382 Eigen::Matrix4f poseMat = pose->toEigen();
389 std::vector<float> result;
392 for (
size_t i = 0; i < 3; ++i)
394 result.at(i) = mat(i, 3);
397 VirtualRobot::MathTools::Quaternion quat = VirtualRobot::MathTools::eigen4f2quat(mat);
399 result.at(3) = quat.w;
400 result.at(4) = quat.x;
401 result.at(5) = quat.y;
402 result.at(6) = quat.z;
411 for (
const double& d : dvec)
413 s = s + std::to_string(d) +
" | ";
421 return Eigen::Map<Eigen::VectorXf>(vec.data(), vec.size());
429 <<
"Size of result VectorXf does not match input vector size.";
432 for (
size_t i = 0; i < vec.size(); ++i)
434 result[i] =
static_cast<float>(vec[i]);
439 sVecToString(
const std::vector<std::string>& vec,
const std::string& delimiter)
442 for (
size_t i = 0; i < vec.size(); ++i)
456 std::vector<double> timesteps;
457 std::vector<std::vector<double>> trajPoses;
459 std::ifstream f(filepath.c_str());
466 using Tokenizer = boost::tokenizer<boost::escaped_list_separator<char>>;
472 double current_time = 0;
474 std::vector<std::string> stringVec;
475 while (getline(f, line))
477 if (containsHeader && i == 1)
484 stringVec.assign(tok.begin(), tok.end());
486 if (stringVec.size() == 0)
488 std::cout <<
"Line " << i <<
" is invalid skipping: " << line << std::endl;
494 armarx::control::common::mp::arondto::MPTraj traj;
502 timesteps.push_back(current_time);
503 current_time += 0.01;
509 timesteps.push_back(std::stod(stringVec[0]));
514 std::vector<double> currentPose;
516 for (
unsigned int k = j; k < stringVec.size(); ++k)
518 currentPose.push_back(std::stod(stringVec[k]));
522 trajPoses.push_back(currentPose);
528 if (timesteps.size() != trajPoses.size())
530 ARMARX_ERROR <<
"consistency error in reading trajectory";
532 armarx::control::common::mp::arondto::MPTraj taskTraj;
533 taskTraj.time.setZero(timesteps.size());
534 taskTraj.traj.setZero(timesteps.size(), trajPoses.at(0).size());
537 for (
unsigned int l = 0; l < timesteps.size(); l++)
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);
549 mp::arondto::MPTraj traj;
550 traj.time = Eigen::VectorXd::LinSpaced(timesteps, 0, 1);
551 traj.traj = Eigen::MatrixXd::Zero(timesteps, dimension);
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)
565 "armarx_control",
"controller_config/mp/default_mp_" + className +
".json");
570 cfg.nodeSetName = nodeSetName;
571 if (durationSec > 0.0)
573 ARMARX_INFO <<
"set duration to " << durationSec <<
" sec";
574 cfg.durationSec = durationSec;
576 if (mpTraj.size() > 0)
578 ARMARX_INFO <<
"set trajectory with " << mpTraj.size() <<
" segments";
579 cfg.trajectoryList = mpTraj;
581 if (viaPointList.size() > 0)
583 ARMARX_INFO <<
"set " << viaPointList.size() <<
" via points";
584 cfg.viaPoints = viaPointList;
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)
597 std::vector<mp::arondto::MPTraj> mpTrajList{};
598 for (
auto& f : mpTraj)
602 return getDefaultMPConfig(mpType, name, nodeSetName, durationSec, mpTrajList, viaPointList);
607 const double& canValue,
608 const std::vector<double>& viaPoint)
610 auto vp = mp::arondto::ListViaPoint();
611 vp.canonicalValue = canValue;
612 vp.viaPointValue = viaPoint;
613 cfg.viaPoints.push_back(vp);
618 const double& canValue,
619 const std::vector<float>& viaPoint)
621 std::vector<double> viaPointVec;
622 std::transform(viaPoint.begin(),
624 std::back_inserter(viaPointVec),
625 [](
float value) { return static_cast<double>(value); });
630 addViaPoint(mp::arondto::MPConfig& cfg,
const double& canValue,
const Eigen::VectorXf& viaPoint)
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); });
641 addViaPoint(mp::arondto::MPConfig& cfg,
const double& canValue,
const Eigen::Matrix4f& viaPose)
650 if (viaPoint.size() != 7 || viaPointReference.size() != 7)
652 ARMARX_ERROR <<
"Both viapoints must have exactly 7 elements";
655 bool allDifferentSigns =
true;
658 for (
int i = 3; i < 7; ++i)
660 if ((viaPoint[i] * viaPointReference[i]) >= 0)
662 allDifferentSigns =
false;
668 if (allDifferentSigns)
670 ARMARX_VERBOSE <<
"===> Viapoints for TS Orientation on two hemisphere, flipping sign";
671 for (
int i = 3; i < 7; ++i)
673 viaPoint[i] = -viaPoint[i];
680 const double canonicalValue,
681 const std::vector<double>& viaPoint)
683 mp::arondto::ListViaPoint vp;
684 vp.canonicalValue = canonicalValue;
685 vp.viaPointValue = viaPoint;
686 vpList.push_back(vp);
691 const double canonicalValue,
692 const std::vector<float>& viaPoint)
694 std::vector<double> viaPointVec;
695 std::transform(viaPoint.begin(),
697 std::back_inserter(viaPointVec),
698 [](
float value) { return static_cast<double>(value); });
704 const double canonicalValue,
705 const Eigen::VectorXf& viaPoint)
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); });
717 const double canonicalValue,
718 const Eigen::Matrix4f& viaPose)
727 Eigen::Matrix3f poseDiffMatImp = rotMat1 * rotMat2.transpose();
728 Eigen::AngleAxisf oriDiffAngleAxis;
729 oriDiffAngleAxis.fromRotationMatrix(poseDiffMatImp);
730 float angle = VirtualRobot::MathTools::angleModPI(oriDiffAngleAxis.angle());
743 const Eigen::Matrix4f& desiredPose,
748 return (desiredPose.block<3, 1>(0, 3) - currentPose.block<3, 1>(0, 3)).norm() >
750 angle > VirtualRobot::MathTools::deg2rad(angleThrDeg);
755 const Eigen::Matrix4f& pose1,
756 const Eigen::Matrix4f& pose2,
757 const std::string& namePose1,
758 const std::string& namePose2)
760 auto quat1 = VirtualRobot::MathTools::eigen4f2quat(pose1);
761 auto quat2 = VirtualRobot::MathTools::eigen4f2quat(pose2);
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 <<
" ].";
774 const Eigen::Matrix4f& pose2,
775 const std::string& namePose1,
776 const std::string& namePose2,
779 const std::string& who)
782 float dist = (pose2.block<3, 1>(0, 3) - pose1.block<3, 1>(0, 3)).
norm();
785 dist > positionThrMM or
angle > VirtualRobot::MathTools::deg2rad(angleThrDeg);
790 << positionThrMM <<
" or angle (rad) " <<
angle <<
" > "
791 << VirtualRobot::MathTools::deg2rad(angleThrDeg);
800 convert << 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1;
801 return sourcePose.cwiseProduct(
convert);
808 convert << 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1;
809 return sourcePose.cwiseProduct(
convert);
816 convert << 1, -1, -1, -1, 1, 1, -1, 1, 1;
817 return sourcePose.cwiseProduct(
convert);
SpamFilterDataPtr deactivateSpam(SpamFilterDataPtr const &spamFilter, float deactivationDurationSec, const std::string &identifier, bool deactivate)
static std::filesystem::path toSystemPath(const data::PackagePath &pp)
The Variant class is described here: Variants.
#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.
#define ARMARX_IMPORTANT
The logging level for always important information, but expected behaviour (in contrast to ARMARX_WAR...
#define ARMARX_ERROR
The logging level for unexpected behaviour, that must be fixed.
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
#define ARMARX_VERBOSE
The logging level for verbose information.
Quaternion< double, 0 > Quaterniond
Eigen::Vector4f calculateTransitionWeights(float z1, float z2)
helper functions
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)
void from_json(const nlohmann::json &j, Pose &fp)
Eigen::Matrix4f mirrorLeftRightOri(Eigen::Matrix4f &sourcePose)
Eigen::VectorXf getEigenVec(nlohmann::json &userConfig, nlohmann::json &defaultConfig, const std::string &entryName, int size, int value)
void addViaPoint(mp::arondto::MPConfig &cfg, const double &canValue, const std::vector< double > &viaPoint)
DVec poseToDVec(PosePtr &pose)
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)
Eigen::Matrix3f getOriT(const Eigen::Matrix4f &matrix)
bool poseDeviationTooLarge(const Eigen::Matrix4f ¤tPose, const Eigen::Matrix4f &desiredPose, float positionThrMM, float angleThrDeg)
void getError(Eigen::Matrix4f ¤tPose, Eigen::Vector3d &targetPosition, Eigen::Quaterniond &targetQuaternion, double &posiError, double &oriError)
void setOri(Eigen::Matrix4f &matrix, const Eigen::Ref< const Eigen::Matrix3f > &ori)
void debugEigenVec(StringVariantBaseMap &datafields, const std::string &name, Eigen::VectorXf vec)
mp::arondto::MPTraj mpTrajFromFile(std::string filepath, bool containsHeader, bool noTimeStamp)
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)
PosePtr dVecToPose(const DVec &dvec)
float getDeltaAngleBetweenPose(const Eigen::Matrix4f &pose1, const Eigen::Matrix4f &pose2)
Eigen::Block< Eigen::Matrix4f, 3, 3 > getOri(Eigen::Matrix4f &matrix)
Eigen::Matrix4f vec7fToMat4f(const Eigen::VectorXf &vec)
Eigen::Matrix4f dVecToMat4(const DVec &dvec)
create Eigen:Matrix4f from 7D double vector.
void getEigenMatrix(nlohmann::json &userConfig, const std::string &entryName, Eigen::MatrixXf &mat)
const simox::meta::EnumNames< MPType > mpTypeToString
void validateTSViaPoint(std::vector< double > &viaPoint, std::vector< double > &viaPointReference)
void debugEigenPose(StringVariantBaseMap &datafields, const std::string &name, Eigen::Matrix4f pose)
std::vector< double > DVec
float getDeltaAngleBetweenRotMat(const Eigen::Matrix3f &rotMat1, const Eigen::Matrix3f &rotMat2)
void setPos(Eigen::Matrix4f &matrix, const Eigen::Ref< const Eigen::Vector3f > &pos)
Eigen::VectorXf vecToEigen(std::vector< float > &vec)
void to_json(nlohmann::json &j, const Pose &fp)
DVec mat4ToDVec(const Eigen::Matrix4f &mat)
convert Eigen:Matrix4f to 7D double vector.
void dvecToEigenf(std::vector< double > &vec, Eigen::VectorXf &result)
Eigen::VectorXf getEigenVecWithDefault(nlohmann::json &userConfig, Eigen::VectorXf defaultValue, const std::string &entryName)
void appendToViapointList(std::vector< mp::arondto::ListViaPoint > &vpList, const double canonicalValue, const std::vector< double > &viaPoint)
Eigen::Matrix4f mirrorLeftRightPose(Eigen::Matrix4f &sourcePose)
void skew(const Eigen::Vector3f &vec, Eigen::Ref< Eigen::Matrix3f > result)
std::vector< float > mat4ToFVec(const Eigen::Matrix4f &mat)
mp::arondto::MPTraj createDummyTraj(const int dimension, const int timesteps)
create a dummy trajectory that only has zeros for every dimension.
void debugEigenMat(StringVariantBaseMap &datafields, const std::string &name, const Eigen::MatrixXd &mat)
std::string sVecToString(const std::vector< std::string > &vec, const std::string &delimiter)
void debugStdVec(StringVariantBaseMap &datafields, const std::string &name, std::vector< float > vec)
Eigen::Block< Eigen::Matrix4f, 3, 1 > getPos(Eigen::Matrix4f &matrix)
std::string dVecToString(const DVec &dvec)
std::vector< float > poseToFVec(PosePtr &pose)
std::map< std::string, VariantBasePtr > StringVariantBaseMap
AronDTO readFromJson(const std::filesystem::path &filename)
IceInternal::Handle< Pose > PosePtr
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 ×tamp)
double norm(const Point &a)
double angle(const Point &a, const Point &b, const Point &c)