GraspTrajectory.cpp
Go to the documentation of this file.
1/*
2 * This file is part of ArmarX.
3 *
4 * Copyright (C) 2012-2016, High Performance Humanoid Technologies (H2T),
5 * Karlsruhe Institute of Technology (KIT), all rights reserved.
6 *
7 * ArmarX is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * ArmarX is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 *
19 * @author Simon Ottenhaus (simon dot ottenhaus at kit dot edu)
20 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
21 * GNU General Public License
22 */
23
24#include "GraspTrajectory.h"
25
26#include <VirtualRobot/math/AbstractFunctionR1R6.h>
27#include <VirtualRobot/math/Helpers.h>
28
30
31using namespace armarx;
32
33GraspTrajectory::Keypoint::Keypoint(const Eigen::Matrix4f& tcpTarget,
34 const Eigen::VectorXf& handJointsTarget) :
37 dt(0),
41{
42}
43
44GraspTrajectory::Keypoint::Keypoint(const Eigen::Matrix4f& tcpTarget,
45 const Eigen::VectorXf& handJointsTarget,
46 float dt,
47 const Eigen::Vector3f& feedForwardPosVelocity,
48 const Eigen::Vector3f& feedForwardOriVelocity,
49 const Eigen::VectorXf& feedForwardHandJointsVelocity) :
52 dt(dt),
56{
57}
58
59Eigen::Vector3f
61{
62 return ::math::Helpers::GetPosition(tcpTarget);
63}
64
65Eigen::Matrix3f
67{
68 return ::math::Helpers::GetOrientation(tcpTarget);
69}
70
71Eigen::Matrix4f
76
77void
79{
80 Eigen::Vector3f pos0 = ::math::Helpers::GetPosition(prev->tcpTarget);
81 Eigen::Matrix3f ori0 = ::math::Helpers::GetOrientation(prev->tcpTarget);
82 Eigen::VectorXf hnd0 = prev->handJointsTarget;
83
84 Eigen::Vector3f pos1 = ::math::Helpers::GetPosition(tcpTarget);
85 Eigen::Matrix3f ori1 = ::math::Helpers::GetOrientation(tcpTarget);
86 Eigen::VectorXf hnd1 = handJointsTarget;
87
88 Eigen::Vector3f dpos = pos1 - pos0;
89 Eigen::Vector3f dori = ::math::Helpers::GetRotationVector(ori0, ori1);
90 Eigen::VectorXf dhnd = hnd1 - hnd0;
91
92 this->dt = dt;
96}
97
98GraspTrajectory::GraspTrajectory(const Eigen::Matrix4f& tcpStart,
99 const Eigen::VectorXf& handJointsStart)
100{
101 KeypointPtr keypoint(new Keypoint(tcpStart, handJointsStart));
102 keypointMap[0] = keypoints.size();
103 keypoints.push_back(keypoint);
104}
105
106void
107GraspTrajectory::addKeypoint(const Eigen::Matrix4f& tcpTarget,
108 const Eigen::VectorXf& handJointsTarget,
109 float dt)
110{
111 ARMARX_CHECK_EQUAL(GetHandJointCount(), handJointsTarget.rows());
112 KeypointPtr prev = lastKeypoint();
113 KeypointPtr keypoint(new Keypoint(tcpTarget, handJointsTarget));
114 keypoint->updateVelocities(prev, dt);
115 float t = getDuration() + dt;
116 keypointMap[t] = keypoints.size();
117 keypoints.push_back(keypoint);
118}
119
120size_t
122{
123 return keypoints.size();
124}
125
126void
128 const Eigen::Matrix4f& tcpTarget,
129 const Eigen::VectorXf& handJointsTarget,
130 float dt)
131{
132 ARMARX_CHECK_EQUAL(GetHandJointCount(), handJointsTarget.rows());
133 if (index <= 0 || index > keypoints.size())
134 {
135 throw LocalException("Index out of range" + std::to_string(index));
136 }
137 KeypointPtr prev = keypoints.at(index - 1);
138 KeypointPtr keypoint(new Keypoint(tcpTarget, handJointsTarget));
139 keypoint->updateVelocities(prev, dt);
140 if (index < keypoints.size())
141 {
142 KeypointPtr next = keypoints.at(index);
143 next->updateVelocities(keypoint, next->dt);
144 }
145 keypoints.insert(keypoints.begin() + index, keypoint);
146 updateKeypointMap();
147}
148
149void
151{
152 if (index <= 0 || index >= keypoints.size())
153 {
154 throw LocalException("Index out of range" + std::to_string(index));
155 }
156 keypoints.erase(keypoints.begin() + index);
157 if (index < keypoints.size())
158 {
159 KeypointPtr prev = keypoints.at(index - 1);
160 KeypointPtr next = keypoints.at(index);
161 next->updateVelocities(prev, next->dt);
162 }
163 updateKeypointMap();
164}
165
166void
168 const Eigen::Matrix4f& tcpTarget,
169 const Eigen::VectorXf& handJointsTarget,
170 float dt)
171{
172 ARMARX_CHECK_EQUAL(GetHandJointCount(), handJointsTarget.rows());
173 if (index <= 0 || index >= keypoints.size())
174 {
175 throw LocalException("Index out of range" + std::to_string(index));
176 }
177 KeypointPtr prev = keypoints.at(index - 1);
178 KeypointPtr keypoint(new Keypoint(tcpTarget, handJointsTarget));
179 keypoint->updateVelocities(prev, dt);
180 keypoints.at(index) = keypoint;
181 updateKeypointMap();
182}
183
184void
186{
187 if (index <= 0 || index >= keypoints.size())
188 {
189 throw LocalException("Index out of range" + std::to_string(index));
190 }
191 KeypointPtr prev = keypoints.at(index - 1);
192 KeypointPtr& keypoint = keypoints.at(index);
193 keypoint->updateVelocities(prev, dt);
194 updateKeypointMap();
195}
196
199{
200 return keypoints.at(keypoints.size() - 1);
201}
202
205{
206 return keypoints.at(i);
207}
208
209Eigen::Matrix4f
211{
212 return getKeypoint(0)->getTargetPose();
213}
214
215void
216GraspTrajectory::getIndex(float t, int& i1, int& i2, float& f)
217{
218 if (t <= 0)
219 {
220 i1 = 0;
221 i2 = 0;
222 f = 0;
223 return;
224 }
225 std::map<float, size_t>::const_iterator it, prev;
226 it = keypointMap.upper_bound(t);
227 if (it == keypointMap.end())
228 {
229 i1 = keypoints.size() - 1;
230 i2 = keypoints.size() - 1;
231 f = 0;
232 return;
233 }
234 prev = std::prev(it);
235 i1 = prev->second;
236 i2 = it->second;
237 f = ::math::Helpers::ILerp(prev->first, it->first, t);
238}
239
240Eigen::Vector3f
242{
243 int i1, i2;
244 float f;
245 getIndex(t, i1, i2, f);
246 return ::math::Helpers::Lerp(
247 getKeypoint(i1)->getTargetPosition(), getKeypoint(i2)->getTargetPosition(), f);
248}
249
250Eigen::Matrix3f
252{
253 int i1, i2;
254 float f;
255 getIndex(t, i1, i2, f);
256 Eigen::Vector3f oriVel = GetOrientationDerivative(t);
257 if (oriVel.squaredNorm() == 0)
258 {
259 return getKeypoint(i1)->getTargetOrientation();
260 }
261 Eigen::AngleAxisf aa(oriVel.norm(), oriVel.normalized());
262 aa.angle() = aa.angle() * f * getKeypoint(i2)->dt;
263 return aa.toRotationMatrix() * getKeypoint(i1)->getTargetOrientation();
264}
265
266Eigen::Matrix4f
268{
269 return ::math::Helpers::CreatePose(GetPosition(t), GetOrientation(t));
270}
271
272std::vector<Eigen::Matrix4f>
274{
275 std::vector<Eigen::Matrix4f> res;
276 for (const KeypointPtr& keypoint : keypoints)
277 {
278 res.emplace_back(keypoint->getTargetPose());
279 }
280 return res;
281}
282
283std::vector<Eigen::Vector3f>
285{
286 std::vector<Eigen::Vector3f> res;
287 for (const KeypointPtr& keypoint : keypoints)
288 {
289 res.emplace_back(keypoint->getTargetPosition());
290 }
291 return res;
292}
293
294std::vector<Eigen::Matrix3f>
296{
297 std::vector<Eigen::Matrix3f> res;
298 for (const KeypointPtr& keypoint : keypoints)
299 {
300 res.emplace_back(keypoint->getTargetOrientation());
301 }
302 return res;
303}
304
305Eigen::VectorXf
307{
308 int i1, i2;
309 float f;
310 getIndex(t, i1, i2, f);
311
312 return getKeypoint(i1)->handJointsTarget * (1 - f) + getKeypoint(i2)->handJointsTarget * f;
313}
314
315Eigen::Vector3f
317{
318 int i1, i2;
319 float f;
320 getIndex(t, i1, i2, f);
321 return getKeypoint(i2)->feedForwardPosVelocity;
322}
323
324Eigen::Vector3f
326{
327 int i1, i2;
328 float f;
329 getIndex(t, i1, i2, f);
330 return getKeypoint(i2)->feedForwardOriVelocity;
331}
332
335{
336 Eigen::Vector6f ffVel;
337 ffVel.block<3, 1>(0, 0) = GetPositionDerivative(t);
338 ffVel.block<3, 1>(3, 0) = GetOrientationDerivative(t);
339 return ffVel;
340}
341
342Eigen::VectorXf
344{
345 int i1, i2;
346 float f;
347 getIndex(t, i1, i2, f);
348 return getKeypoint(i2)->feedForwardHandJointsVelocity;
349}
350
351float
353{
354 return keypointMap.rbegin()->first;
355}
356
359{
360 Length l;
361 for (size_t i = 1; i < keypoints.size(); i++)
362 {
363 KeypointPtr k0 = keypoints.at(i - 1);
364 KeypointPtr k1 = keypoints.at(i);
365
366 Eigen::Vector3f pos0 = ::math::Helpers::GetPosition(k0->tcpTarget);
367 Eigen::Matrix3f ori0 = ::math::Helpers::GetOrientation(k0->tcpTarget);
368
369 Eigen::Vector3f pos1 = ::math::Helpers::GetPosition(k1->tcpTarget);
370 Eigen::Matrix3f ori1 = ::math::Helpers::GetOrientation(k1->tcpTarget);
371
372 l.pos += (pos1 - pos0).norm();
373 l.ori += fabs(::math::Helpers::GetAngleAxisFromTo(ori0, ori1).angle());
374 }
375 return l;
376}
377
378int
380{
381 return keypoints.at(0)->handJointsTarget.rows();
382}
383
385GraspTrajectory::getTranslatedAndRotated(const Eigen::Vector3f& translation,
386 const Eigen::Matrix3f& rotation)
387{
389 new GraspTrajectory(::math::Helpers::TranslateAndRotatePose(
390 getKeypoint(0)->getTargetPose(), translation, rotation),
391 getKeypoint(0)->handJointsTarget));
392 for (size_t i = 1; i < keypoints.size(); i++)
393 {
394 KeypointPtr& kp = keypoints.at(i);
395 traj->addKeypoint(
396 ::math::Helpers::TranslateAndRotatePose(kp->getTargetPose(), translation, rotation),
397 kp->handJointsTarget,
398 kp->dt);
399 }
400 return traj;
401}
402
405{
407 new GraspTrajectory(transform * getStartPose(), getKeypoint(0)->handJointsTarget));
408 for (size_t i = 1; i < keypoints.size(); i++)
409 {
410 KeypointPtr& kp = keypoints.at(i);
411 traj->addKeypoint(transform * kp->getTargetPose(), kp->handJointsTarget, kp->dt);
412 }
413 return traj;
414}
415
418{
419 return getTransformed(Eigen::Matrix4f::Identity());
420}
421
423GraspTrajectory::getTransformedToGraspPose(const Eigen::Matrix4f& target,
424 const Eigen::Vector3f& handForward)
425{
426 Eigen::Matrix4f startPose = getStartPose();
427 Eigen::Vector3f targetHandForward = ::math::Helpers::TransformDirection(target, handForward);
428 Eigen::Vector3f trajHandForward = ::math::Helpers::TransformDirection(startPose, handForward);
429 Eigen::Vector3f up(0, 0, 1);
430
431 float angle = ::math::Helpers::Angle(targetHandForward, trajHandForward, up);
432 Eigen::AngleAxisf aa(angle, up);
433
434 Eigen::Matrix4f transform = ::math::Helpers::CreateTranslationRotationTranslationPose(
435 -::math::Helpers::GetPosition(startPose),
436 aa.toRotationMatrix(),
437 ::math::Helpers::GetPosition(target));
439}
440
442GraspTrajectory::calculateReachability(VirtualRobot::RobotNodeSetPtr rns,
443 VirtualRobot::RobotNodePtr tcp,
445{
447 getAllKeypointPoses(), Eigen::VectorXf::Zero(rns->getSize()), rns, tcp, params);
448}
449
450void
451GraspTrajectory::writeToFile(const std::string& filename)
452{
453 RapidXmlWriter writer;
454 RapidXmlWriterNode root = writer.createRootNode("GraspTrajectory");
455 for (const KeypointPtr& keypoint : keypoints)
456 {
458 e.Add("dt", keypoint->dt);
459 e.AddAsArr("Pose", keypoint->tcpTarget);
460 e.AddAsArr("HandValues", keypoint->handJointsTarget);
461 root.append_string_node("Keypoint", e.obj->toJsonString(0, "", true));
462 }
463 writer.saveToFile(filename, true);
464}
465
467GraspTrajectory::ReadFromFile(const grasping::GraspCandidatePtr& cnd)
468{
469 std::string packageName = "armar6_skills"; // cnd->executionHints->graspTrajectoryPackage;
470 armarx::CMakePackageFinder finder(packageName);
471 std::string dataDir = finder.getDataDir() + "/" + packageName;
472 return GraspTrajectory::ReadFromFile(dataDir + "/motions/grasps/" +
473 cnd->executionHints->graspTrajectoryName + ".xml");
474}
475
478{
479 RapidXmlReaderNode root = reader->getRoot("GraspTrajectory");
481 for (const RapidXmlReaderNode& kpNode : root.nodes("Keypoint"))
482 {
483 StructuralJsonParser p(kpNode.value());
484 p.parse();
486 float dt = nav.selectSingleNode("dt").asFloat();
487
488 Eigen::Matrix4f pose;
489 std::vector<JPathNavigator> rows = nav.select("Pose/*");
490 for (int i = 0; i < 4; i++)
491 {
492 std::vector<JPathNavigator> cells = rows.at(i).select("*");
493 for (int j = 0; j < 4; j++)
494 {
495 pose(i, j) = cells.at(j).asFloat();
496 }
497 }
498
499 Eigen::Vector3f handValues;
500 std::vector<JPathNavigator> cells = nav.select("HandValues/*");
501 for (int j = 0; j < 3; j++)
502 {
503 handValues(j) = cells.at(j).asFloat();
504 }
505
506 if (!traj)
507 {
508 traj = GraspTrajectoryPtr(new GraspTrajectory(pose, handValues));
509 }
510 else
511 {
512 traj->addKeypoint(pose, handValues, dt);
513 }
514 }
515 return traj;
516}
517
519GraspTrajectory::ReadFromFile(const std::string& filename)
520{
522}
523
525GraspTrajectory::ReadFromString(const std::string& xml)
526{
528}
529
530void
531GraspTrajectory::updateKeypointMap()
532{
533 keypointMap.clear();
534 float t = 0;
535 for (size_t i = 0; i < keypoints.size(); i++)
536 {
537 t += getKeypoint(i)->dt;
538 keypointMap[t] = i;
539 }
540}
uint8_t index
constexpr T dt
The CMakePackageFinder class provides an interface to the CMake Package finder capabilities.
Eigen::Matrix3f getTargetOrientation() const
void updateVelocities(const GraspTrajectoryKeypointPtr &prev, float deltat)
Eigen::Vector3f getTargetPosition() const
Eigen::Matrix4f getTargetPose() const
Eigen::VectorXf feedForwardHandJointsVelocity
Eigen::VectorXf GetHandValues(float t)
void removeKeypoint(size_t index)
Eigen::Vector3f GetOrientationDerivative(float t)
Eigen::Matrix4f getStartPose()
Eigen::Matrix4f GetPose(float t)
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)
GraspTrajectoryPtr getClone()
GraspTrajectoryPtr getTranslatedAndRotated(const Eigen::Vector3f &translation, const Eigen::Matrix3f &rotation)
static GraspTrajectoryPtr ReadFromString(const std::string &xml)
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)
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)
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)
std::vector< RapidXmlReaderNode > nodes(const char *name=nullptr) const
static RapidXmlReaderPtr FromFile(const std::string &path)
static RapidXmlReaderPtr FromXmlString(const std::string &xml)
RapidXmlWriterNode & append_string_node(const std::string &name, const std::string &value)
void saveToFile(const std::string &path, bool indent)
RapidXmlWriterNode createRootNode(const std::string &name)
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.
void Add(const std::string &key, const std::string &value)
void AddAsArr(const std::string &key, const Eigen::Vector3f &vec)
#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...
Matrix< float, 6, 1 > Vector6f
This file offers overloads of toIce() and fromIce() functions for STL container types.
std::shared_ptr< RapidXmlReader > RapidXmlReaderPtr
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...
Definition algorithm.h:351
std::shared_ptr< class GraspTrajectory > GraspTrajectoryPtr
double norm(const Point &a)
Definition point.hpp:102
double angle(const Point &a, const Point &b, const Point &c)
Definition point.hpp:109