31#include <SimoxUtility/json/eigen_conversion.h>
32#include <SimoxUtility/json/json.hpp>
33#include <VirtualRobot/RobotNodeSet.h>
34#include <VirtualRobot/math/Helpers.h>
47#include <RobotAPI/interface/units/GraspCandidateProviderInterface.h>
57 Eigen::VectorXf vector(map.size());
59 map.begin(), map.end(), vector.data(), [](
const auto& item) { return item.second; });
67 RapidXmlWriter writer;
68 RapidXmlWriterNode root = writer.createRootNode(
"GraspTrajectory");
71 SimpleJsonLoggerEntry e;
72 e.Add(
"dt", keypoint->dt);
73 e.AddAsArr(
"Pose", keypoint->tcpTarget);
75 for (
const auto& [name, value] : keypoint->handJointsTarget)
79 e.obj->add(
"HandValues", obj);
80 root.append_string_node(
"Keypoint", e.obj->toJsonString(0,
"",
true));
82 writer.saveToFile(filename,
true);
89 RapidXmlReaderNode
const root = reader->getRoot();
92 for (
const RapidXmlReaderNode& kpNode : root.nodes(
"Keypoint"))
94 StructuralJsonParser p(kpNode.value());
96 JPathNavigator nav(p.parsedJson);
97 float dt = nav.selectSingleNode(
"dt").asFloat();
100 std::vector<JPathNavigator> rows = nav.select(
"Pose/*");
101 for (
int i = 0; i < 4; i++)
103 std::vector<JPathNavigator> cells = rows.at(i).select(
"*");
104 for (
int j = 0; j < 4; j++)
106 pose(i, j) = cells.at(j).asFloat();
110 armarx::NameValueMap handValues;
111 std::vector<JPathNavigator> cells = nav.select(
"HandValues/*");
112 for (
const auto& cell : cells)
114 handValues[cell.getKey()] = cell.asFloat();
118 const auto shapeNode = nav.selectSingleNode(
"shape");
121 std::optional<std::string> shape;
122 if (shapeNode.isString())
124 shape = nav.selectSingleNode(
"shape").asString();
131 traj = std::make_shared<GraspTrajectory>(pose, handValues, shape);
135 traj->addKeypoint(pose, handValues,
dt, shape);
145 const auto ext = std::filesystem::path(filename).extension();
166 std::optional<std::string> shape;
168 if (j.contains(
"shape"))
170 if (not j.at(
"shape").is_null())
172 shape = j.at(
"shape");
177 std::optional<std::map<std::string, float>> targetHandValues;
179 if (j.contains(
"fingerValues"))
181 if (not j.at(
"fingerValues").is_null())
183 targetHandValues = j.at(
"fingerValues");
189 const Eigen::Matrix4f tf = aronTf.transpose();
195 tf, targetHandValues.value_or(std::map<std::string, float>{}), shape);
202 ARMARX_INFO <<
"Reading from file `" << filename <<
"`";
204 std::ifstream ifs(filename);
206 const nlohmann::json j = nlohmann::json::parse(ifs);
208 std::vector<GraspTrajectoryKeypoint> traj;
209 traj = j.at(
"keypoints");
217 const float dtSeconds = duration.
toSecondsDouble() / (traj.size() - 1);
220 for (
auto& kp : traj)
225 const std::string frame = j.at(
"frame").at(
"frame");
227 auto graspTrajectory = std::make_shared<GraspTrajectory>(traj);
228 graspTrajectory->setFrame(frame);
230 return graspTrajectory;
241 const armarx::NameValueMap& handJointsStart,
242 const std::optional<std::string>& shape)
246 keypointMap[0] = keypoints.size();
247 keypoints.push_back(keypoint);
252 if (keypointz.empty())
258 keypointMap[0] = keypoints.size();
259 keypoints.push_back(std::make_shared<Keypoint>(keypointz.front()));
262 for (std::size_t i = 1; i < keypointz.size(); i++)
264 const auto& kp = keypointz.at(i);
265 addKeypoint(kp.tcpTarget, kp.handJointsTarget, kp.dt, kp.shape);
271 const armarx::NameValueMap& handJointsTarget,
273 const std::optional<std::string>& shape)
278 keypoint->updateVelocities(prev,
dt);
280 keypointMap[t] = keypoints.size();
281 keypoints.push_back(keypoint);
288 return keypoints.size();
291 const std::vector<GraspTrajectory::KeypointPtr>&
299 const Eigen::Matrix4f& tcpTarget,
300 const armarx::NameValueMap& handJointsTarget,
302 const std::optional<std::string>& shape)
307 throw LocalException(
"Index out of range" + std::to_string(
index));
311 keypoint->updateVelocities(prev,
dt);
312 if (
index < keypoints.size())
315 next->updateVelocities(keypoint, next->dt);
317 keypoints.insert(keypoints.begin() +
index, keypoint);
327 throw LocalException(
"Index out of range" + std::to_string(
index));
329 keypoints.erase(keypoints.begin() +
index);
330 if (
index < keypoints.size())
335 next->updateVelocities(prev, next->dt);
342 const Eigen::Matrix4f& tcpTarget,
343 const armarx::NameValueMap& handJointsTarget,
345 const std::optional<std::string>& shape)
350 throw LocalException(
"Index out of range" + std::to_string(
index));
354 keypoint->updateVelocities(prev,
dt);
355 keypoints.at(
index) = keypoint;
365 throw LocalException(
"Index out of range" + std::to_string(
index));
369 keypoint->updateVelocities(prev,
dt);
377 return keypoints.at(keypoints.size() - 1);
384 return keypoints.at(i);
405 std::map<float, size_t>::const_iterator it, prev;
406 it = keypointMap.upper_bound(t);
407 if (it == keypointMap.end())
409 i1 = keypoints.size() - 1;
410 i2 = keypoints.size() - 1;
414 prev = std::prev(it);
417 f = ::math::Helpers::ILerp(prev->first, it->first, t);
427 return ::math::Helpers::Lerp(
439 if (oriVel.squaredNorm() == 0)
443 Eigen::AngleAxisf aa(oriVel.norm(), oriVel.normalized());
445 return aa.toRotationMatrix() *
getKeypoint(i1)->getTargetOrientation();
455 std::vector<Eigen::Matrix4f>
459 std::vector<Eigen::Matrix4f> res;
462 res.emplace_back(keypoint->getTargetPose());
467 std::vector<Eigen::Vector3f>
471 std::vector<Eigen::Vector3f> res;
474 res.emplace_back(keypoint->getTargetPosition());
479 std::vector<Eigen::Matrix3f>
483 std::vector<Eigen::Matrix3f> res;
486 res.emplace_back(keypoint->getTargetOrientation());
498 auto handTargetsMap =
getKeypoint(i1)->handJointsTarget;
501 const Eigen::VectorXf lerpTargets = handTargets1 * (1 - f) + handTargets2 * f;
502 auto* lerpTargetsIt = lerpTargets.data();
503 for (
auto& [name, value] : handTargetsMap)
505 value = *(lerpTargetsIt++);
507 return handTargetsMap;
510 std::optional<std::string>
559 return getKeypoint(i2)->feedForwardHandJointsVelocity;
566 return keypointMap.rbegin()->first;
569 GraspTrajectory::Length
574 for (
size_t i = 1; i < keypoints.size(); i++)
579 Eigen::Vector3f pos0 = ::math::Helpers::GetPosition(k0->tcpTarget);
580 Eigen::Matrix3f ori0 = ::math::Helpers::GetOrientation(k0->tcpTarget);
582 Eigen::Vector3f pos1 = ::math::Helpers::GetPosition(k1->tcpTarget);
583 Eigen::Matrix3f ori1 = ::math::Helpers::GetOrientation(k1->tcpTarget);
585 l.pos += (pos1 - pos0).
norm();
586 l.ori += fabs(::math::Helpers::GetAngleAxisFromTo(ori0, ori1).
angle());
593 const Eigen::Matrix3f& rotation)
const
598 getKeypoint(0)->getTargetPose(), translation, rotation),
600 for (
size_t i = 1; i < keypoints.size(); i++)
604 ::math::Helpers::TranslateAndRotatePose(kp->getTargetPose(), translation, rotation),
605 kp->handJointsTarget,
618 for (
size_t i = 1; i < keypoints.size(); i++)
622 transform * kp->getTargetPose(), kp->handJointsTarget, kp->dt, kp->shape);
636 const Eigen::Vector3f& handForward)
const
640 Eigen::Vector3f targetHandForward =
641 ::math::Helpers::TransformDirection(target, handForward);
642 Eigen::Vector3f trajHandForward =
643 ::math::Helpers::TransformDirection(startPose, handForward);
644 Eigen::Vector3f up(0, 0, 1);
646 float angle = ::math::Helpers::Angle(targetHandForward, trajHandForward, up);
647 Eigen::AngleAxisf aa(
angle, up);
649 Eigen::Matrix4f
transform = ::math::Helpers::CreateTranslationRotationTranslationPose(
650 -::math::Helpers::GetPosition(startPose),
651 aa.toRotationMatrix(),
652 ::math::Helpers::GetPosition(target));
660 Eigen::Matrix3f flip_yz = Eigen::Matrix3f::Identity();
661 flip_yz(0, 0) *= -1.0;
663 start_pose.block<3, 3>(0, 0) = flip_yz * start_pose.block<3, 3>(0, 0) * flip_yz;
669 Eigen::Matrix4f target_pose = kp->getTargetPose();
670 target_pose.block<3, 3>(0, 0) = flip_yz * target_pose.block<3, 3>(0, 0) * flip_yz;
671 output_trajectory->addKeypoint(target_pose, kp->handJointsTarget, kp->dt, kp->shape);
673 return output_trajectory;
678 VirtualRobot::RobotNodePtr tcp,
687 GraspTrajectory::updateKeypointMap()
692 for (
size_t i = 0; i < keypoints.size(); i++)
704 Eigen::Vector3f pos0 = ::math::Helpers::GetPosition(prev->tcpTarget);
705 Eigen::Matrix3f ori0 = ::math::Helpers::GetOrientation(prev->tcpTarget);
708 Eigen::Vector3f pos1 = ::math::Helpers::GetPosition(
tcpTarget);
709 Eigen::Matrix3f ori1 = ::math::Helpers::GetOrientation(
tcpTarget);
712 Eigen::Vector3f dpos = pos1 - pos0;
713 Eigen::Vector3f dori = ::math::Helpers::GetRotationVector(ori0, ori1);
714 Eigen::VectorXf dhnd = hnd1 - hnd0;
726 return ::math::Helpers::GetPosition(tcpTarget);
733 return ::math::Helpers::GetOrientation(tcpTarget);
750 const std::optional<std::string>&
shape) :
763 const std::optional<std::string>&
shape) :
779 const std::optional<std::string>&
#define ARMARX_CHECK_NOT_EMPTY(c)
static Duration MicroSeconds(std::int64_t microSeconds)
Constructs a duration in microseconds.
Eigen::Matrix3f getTargetOrientation() const
void updateVelocities(const GraspTrajectoryKeypointPtr &prev, float deltat)
GraspTrajectoryKeypoint()=default
armarx::NameValueMap handJointsTarget
Eigen::VectorXf feedForwardHandJointsVelocity
Eigen::Vector3f getTargetPosition() const
Eigen::Matrix4f getTargetPose() const
Eigen::Vector3f feedForwardPosVelocity
Eigen::Vector3f feedForwardOriVelocity
Eigen::Matrix4f tcpTarget
std::optional< std::string > shape
Eigen::VectorXf GetHandValues(float t)
void removeKeypoint(size_t index)
float getDuration() const
std::optional< std::string > GetShape(float t) const
Eigen::Vector3f GetOrientationDerivative(float t)
Eigen::Matrix4f getStartPose()
Eigen::Matrix4f GetPose(float t)
const std::vector< KeypointPtr > & getAllKeypoints() const
SimpleDiffIK::Reachability calculateReachability(VirtualRobot::RobotNodeSetPtr rns, VirtualRobot::RobotNodePtr tcp=VirtualRobot::RobotNodePtr(), SimpleDiffIK::Parameters params=SimpleDiffIK::Parameters())
Eigen::Vector3f GetPositionDerivative(float t)
void addKeypoint(const Eigen::Matrix4f &tcpTarget, const Eigen::VectorXf &handJointsTarget, float dt)
void setFrame(const std::string &frame)
GraspTrajectoryPtr getClone()
static GraspTrajectoryPtr ReadFromJSON(const std::string &filename)
GraspTrajectoryPtr getTranslatedAndRotated(const Eigen::Vector3f &translation, const Eigen::Matrix3f &rotation)
static GraspTrajectoryPtr ReadFromString(const std::string &xml)
GraspTrajectoryPtr getTransformedToOtherHand() const
size_t getKeypointCount() const
const std::optional< std::string > & getFrame() const
std::vector< Eigen::Vector3f > getAllKeypointPositions()
Eigen::Vector3f GetPosition(float t)
GraspTrajectoryKeypoint Keypoint
void setKeypointDt(size_t index, float dt)
std::vector< Eigen::Matrix3f > getAllKeypointOrientations()
std::shared_ptr< Keypoint > KeypointPtr
void replaceKeypoint(size_t index, const Eigen::Matrix4f &tcpTarget, const Eigen::VectorXf &handJointsTarget, float dt)
GraspTrajectory()=default
Eigen::VectorXf GetHandJointsDerivative(float t)
GraspTrajectoryPtr getTransformed(const Eigen::Matrix4f &transform)
KeypointPtr & getKeypoint(int i)
void getIndex(float t, int &i1, int &i2, float &f)
KeypointPtr & lastKeypoint()
Length calculateLength() const
std::vector< Eigen::Matrix4f > getAllKeypointPoses()
Eigen::Matrix3f GetOrientation(float t)
void insertKeypoint(size_t index, const Eigen::Matrix4f &tcpTarget, const Eigen::VectorXf &handJointsTarget, float dt)
GraspTrajectoryPtr getTransformedToGraspPose(const Eigen::Matrix4f &target, const Eigen::Vector3f &handForward=Eigen::Vector3f::UnitZ())
static GraspTrajectoryPtr ReadFromReader(const RapidXmlReaderPtr &reader)
Eigen::Vector6f GetTcpDerivative(float t)
static GraspTrajectoryPtr ReadFromFile(const grasping::GraspCandidatePtr &cnd)
void writeToFile(const std::string &filename)
static JsonValuePtr Create(const std::string &value)
static RapidXmlReaderPtr FromFile(const std::string &path)
static RapidXmlReaderPtr FromXmlString(const std::string &xml)
static Reachability CalculateReachability(const std::vector< Eigen::Matrix4f > targets, const Eigen::VectorXf &initialJV, VirtualRobot::RobotNodeSetPtr rns, VirtualRobot::RobotNodePtr tcp=VirtualRobot::RobotNodePtr(), Parameters params=Parameters())
Use this to check a trajectory of waypoints.
double toSecondsDouble() const
Returns the amount of seconds.
#define ARMARX_CHECK(expression)
Shortcut for ARMARX_CHECK_EXPRESSION.
#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_WARNING
The logging level for unexpected behaviour, but not a serious problem.
#define ARMARX_VERBOSE
The logging level for verbose information.
This file offers overloads of toIce() and fromIce() functions for STL container types.
Eigen::VectorXf mapValuesToVector(const armarx::NameValueMap &map)
std::shared_ptr< RapidXmlReader > RapidXmlReaderPtr
std::shared_ptr< JsonObject > JsonObjectPtr
auto transform(const Container< InputT, Alloc > &in, OutputT(*func)(InputT const &)) -> Container< OutputT, typename std::allocator_traits< Alloc >::template rebind_alloc< OutputT > >
Convenience function (with less typing) to transform a container of type InputT into the same contain...
void from_json(const nlohmann::json &j, Vector2f &value)
std::shared_ptr< class GraspTrajectory > GraspTrajectoryPtr
double norm(const Point &a)
double angle(const Point &a, const Point &b, const Point &c)