SimpleDiffIK.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 SecondHands Demo (shdemo at armar6)
20  * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
21  * GNU General Public License
22  */
23 
24 #include "SimpleDiffIK.h"
25 
26 #include <cfloat>
27 
28 #include <VirtualRobot/Nodes/RobotNode.h>
29 #include <VirtualRobot/RobotNodeSet.h>
30 
33 
34 namespace armarx
35 {
36  SimpleDiffIK::Result
38  VirtualRobot::RobotNodeSetPtr rns,
39  VirtualRobot::RobotNodePtr tcp,
40  Parameters params)
41  {
42 
43  tcp = tcp ? tcp : rns->getTCP();
44  CartesianVelocityController velocityController(rns);
45  CartesianPositionController positionController(tcp);
46 
47  if (params.resetRnsValues)
48  {
49  for (VirtualRobot::RobotNodePtr rn : rns->getAllRobotNodes())
50  {
51  if (rn->isLimitless())
52  {
53  rn->setJointValue(0);
54  }
55  else
56  {
57  rn->setJointValue((rn->getJointLimitHi() + rn->getJointLimitLo()) / 2);
58  }
59  }
60  }
61 
62  std::vector<IKStep> ikSteps;
63  Eigen::VectorXf currentJointValues = rns->getJointValuesEigen();
64  for (size_t i = 0; i <= params.stepsInitial + params.stepsFineTune; i++)
65  {
66  Eigen::Vector3f posDiff = positionController.getPositionDiff(targetPose);
67  Eigen::Vector3f oriDiff = positionController.getOrientationDiff(targetPose);
68 
69  //ARMARX_IMPORTANT << VAROUT(posDiff) << VAROUT(oriDiff);
70 
71  Eigen::VectorXf cartesianVel(6);
72  cartesianVel << posDiff(0), posDiff(1), posDiff(2), oriDiff(0), oriDiff(1), oriDiff(2);
73  const Eigen::VectorXf jnv =
74  params.jointLimitAvoidanceKp * velocityController.calculateJointLimitAvoidance();
75  const Eigen::VectorXf jv =
76  velocityController.calculate(cartesianVel, jnv, VirtualRobot::IKSolver::All);
77 
78 
79  float stepLength =
80  i < params.stepsInitial ? params.ikStepLengthInitial : params.ikStepLengthFineTune;
81  Eigen::VectorXf jvClamped = jv * stepLength;
82 
83  float infNorm = jvClamped.lpNorm<Eigen::Infinity>();
84  if (infNorm > params.maxJointAngleStep)
85  {
86  jvClamped = jvClamped / infNorm * params.maxJointAngleStep;
87  }
88 
89  if (params.returnIKSteps)
90  {
91  IKStep s;
92  s.posDiff = posDiff;
93  s.oriDiff = oriDiff;
94  s.cartesianVel = cartesianVel;
95  s.jnv = jnv;
96  s.jv = jv;
97  s.infNorm = infNorm;
98  s.jvClamped = jvClamped;
99  ikSteps.emplace_back(s);
100  }
101 
102 
103  Eigen::VectorXf newJointValues = currentJointValues + jvClamped;
104  rns->setJointValues(newJointValues);
105  currentJointValues = newJointValues;
106  }
107 
108  Result result;
109  result.ikSteps = ikSteps;
110  result.jointValues = rns->getJointValuesEigen();
111  result.posDiff = positionController.getPositionDiff(targetPose);
112  result.oriDiff = positionController.getOrientationDiff(targetPose);
113  result.posError = positionController.getPositionError(targetPose);
114  result.oriError = positionController.getOrientationError(targetPose);
115  result.reached =
116  result.posError < params.maxPosError && result.oriError < params.maxOriError;
117 
118  result.jointLimitMargins = Eigen::VectorXf::Zero(rns->getSize());
119  result.minimumJointLimitMargin = FLT_MAX;
120  for (size_t i = 0; i < rns->getSize(); i++)
121  {
122  VirtualRobot::RobotNodePtr rn = rns->getNode(i);
123  if (rn->isLimitless())
124  {
125  result.jointLimitMargins(i) = M_PI;
126  }
127  else
128  {
129  result.jointLimitMargins(i) = std::min(rn->getJointValue() - rn->getJointLimitLo(),
130  rn->getJointLimitHi() - rn->getJointValue());
131  result.minimumJointLimitMargin =
133  }
134  }
135 
136  return result;
137  }
138 
140  SimpleDiffIK::CalculateReachability(const std::vector<Eigen::Matrix4f> targets,
141  const Eigen::VectorXf& initialJV,
142  VirtualRobot::RobotNodeSetPtr rns,
143  VirtualRobot::RobotNodePtr tcp,
145  {
146  Reachability r;
147  rns->setJointValues(initialJV);
148  for (const Eigen::Matrix4f& target : targets)
149  {
150  Result res = CalculateDiffIK(target, rns, tcp, params);
151  r.aggregate(res);
152  }
153  if (!r.reachable)
154  {
156  }
157  return r;
158  }
159 
160  SimpleDiffIKProvider::SimpleDiffIKProvider(VirtualRobot::RobotNodeSetPtr rns,
161  VirtualRobot::RobotNodePtr tcp,
162  SimpleDiffIK::Parameters params) :
163  rns(rns), tcp(tcp), params(params)
164  {
165  }
166 
169  {
170  params.resetRnsValues = true;
171  SimpleDiffIK::Result result = SimpleDiffIK::CalculateDiffIK(targetPose, rns, tcp, params);
172  DiffIKResult r;
173  r.jointValues = rns->getJointValuesEigen();
174  r.oriError = result.oriError;
175  r.posError = result.posError;
176  r.reachable = result.reached;
177  return r;
178  }
179 
182  const Eigen::VectorXf& startJointValues)
183  {
184  params.resetRnsValues = false;
185  rns->setJointValues(startJointValues);
186  SimpleDiffIK::Result result = SimpleDiffIK::CalculateDiffIK(targetPose, rns, tcp, params);
187  DiffIKResult r;
188  r.jointValues = rns->getJointValuesEigen();
189  r.oriError = result.oriError;
190  r.posError = result.posError;
191  r.reachable = result.reached;
192  return r;
193  }
194 
195  void
197  {
198  ikResults.emplace_back(result);
199  reachable = reachable && result.reached;
201  if (jointLimitMargins.rows() == 0)
202  {
204  }
205  else
206  {
208  }
211  }
212 } // namespace armarx
armarx::SimpleDiffIK::Result::posDiff
Eigen::Vector3f posDiff
Definition: SimpleDiffIK.h:73
armarx::SimpleDiffIK::Parameters::ikStepLengthFineTune
float ikStepLengthFineTune
Definition: SimpleDiffIK.h:47
armarx::SimpleDiffIK::Parameters::stepsInitial
size_t stepsInitial
Definition: SimpleDiffIK.h:48
armarx::CartesianVelocityController::calculate
Eigen::VectorXf calculate(const Eigen::VectorXf &cartesianVel, VirtualRobot::IKSolver::CartesianSelection mode)
Definition: CartesianVelocityController.cpp:80
armarx::SimpleDiffIK::Parameters::returnIKSteps
bool returnIKSteps
Definition: SimpleDiffIK.h:54
armarx::DiffIKResult
Definition: DiffIKProvider.h:34
armarx::SimpleDiffIK::Reachability::aggregate
void aggregate(const Result &result)
Definition: SimpleDiffIK.cpp:196
armarx::SimpleDiffIK::Parameters
Definition: SimpleDiffIK.h:39
armarx::SimpleDiffIK::Reachability::reachable
bool reachable
Definition: SimpleDiffIK.h:86
armarx::SimpleDiffIK::Result::reached
bool reached
Definition: SimpleDiffIK.h:77
armarx::SimpleDiffIK::Reachability::minimumJointLimitMargin
float minimumJointLimitMargin
Definition: SimpleDiffIK.h:87
GfxTL::Matrix4f
MatrixXX< 4, 4, float > Matrix4f
Definition: MatrixXX.h:650
armarx::SimpleDiffIK::CalculateDiffIK
static Result CalculateDiffIK(const Eigen::Matrix4f targetPose, VirtualRobot::RobotNodeSetPtr rns, VirtualRobot::RobotNodePtr tcp=VirtualRobot::RobotNodePtr(), Parameters params=Parameters())
Definition: SimpleDiffIK.cpp:37
armarx::SimpleDiffIK::Reachability
Definition: SimpleDiffIK.h:83
armarx::DiffIKResult::posError
float posError
Definition: DiffIKProvider.h:37
boost::target
Vertex target(const detail::edge_base< Directed, Vertex > &e, const PCG &)
Definition: point_cloud_graph.h:668
armarx::DiffIKResult::jointValues
Eigen::VectorXf jointValues
Definition: DiffIKProvider.h:39
armarx::CartesianVelocityController
Definition: CartesianVelocityController.h:36
armarx::SimpleDiffIK::Result::minimumJointLimitMargin
float minimumJointLimitMargin
Definition: SimpleDiffIK.h:79
armarx::CartesianPositionController::getPositionDiff
Eigen::Vector3f getPositionDiff(const Eigen::Matrix4f &targetPose) const
Definition: CartesianPositionController.cpp:182
armarx::SimpleDiffIK::Result::jointLimitMargins
Eigen::VectorXf jointLimitMargins
Definition: SimpleDiffIK.h:78
armarx::SimpleDiffIK::Result::jointValues
Eigen::VectorXf jointValues
Definition: SimpleDiffIK.h:72
armarx::SimpleDiffIK::Parameters::jointLimitAvoidanceKp
float jointLimitAvoidanceKp
Definition: SimpleDiffIK.h:52
armarx::SimpleDiffIK::Parameters::maxOriError
float maxOriError
Definition: SimpleDiffIK.h:51
armarx::DiffIKResult::oriError
float oriError
Definition: DiffIKProvider.h:38
armarx::CartesianPositionController::getPositionError
float getPositionError(const Eigen::Matrix4f &targetPose) const
Definition: CartesianPositionController.cpp:104
armarx::SimpleDiffIKProvider::SolveRelative
DiffIKResult SolveRelative(const Eigen::Matrix4f &targetPose, const Eigen::VectorXf &startJointValues)
Definition: SimpleDiffIK.cpp:181
armarx::SimpleDiffIK::Result::posError
float posError
Definition: SimpleDiffIK.h:75
M_PI
#define M_PI
Definition: MathTools.h:17
SimpleDiffIK.h
armarx::SimpleDiffIK::Parameters::maxJointAngleStep
float maxJointAngleStep
Definition: SimpleDiffIK.h:53
armarx::SimpleDiffIKProvider::SimpleDiffIKProvider
SimpleDiffIKProvider(VirtualRobot::RobotNodeSetPtr rns, VirtualRobot::RobotNodePtr tcp=VirtualRobot::RobotNodePtr(), SimpleDiffIK::Parameters params=SimpleDiffIK::Parameters())
Definition: SimpleDiffIK.cpp:160
max
T max(T t1, T t2)
Definition: gdiam.h:51
armarx::SimpleDiffIK::Parameters::ikStepLengthInitial
float ikStepLengthInitial
Definition: SimpleDiffIK.h:46
armarx::CartesianVelocityController::calculateJointLimitAvoidance
Eigen::VectorXf calculateJointLimitAvoidance()
Definition: CartesianVelocityController.cpp:171
armarx::SimpleDiffIK::Reachability::jointLimitMargins
Eigen::VectorXf jointLimitMargins
Definition: SimpleDiffIK.h:88
armarx::SimpleDiffIK::Result::oriError
float oriError
Definition: SimpleDiffIK.h:76
CartesianVelocityController.h
CartesianPositionController.h
armarx::SimpleDiffIK::Reachability::maxOriError
float maxOriError
Definition: SimpleDiffIK.h:90
armarx::SimpleDiffIK::Result::ikSteps
std::vector< IKStep > ikSteps
Definition: SimpleDiffIK.h:80
armarx::CartesianPositionController::getOrientationDiff
Eigen::Vector3f getOrientationDiff(const Eigen::Matrix4f &targetPose) const
Definition: CartesianPositionController.cpp:196
armarx::SimpleDiffIK::Result
Definition: SimpleDiffIK.h:70
armarx::SimpleDiffIK::CalculateReachability
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.
Definition: SimpleDiffIK.cpp:140
armarx::SimpleDiffIK::Parameters::maxPosError
float maxPosError
Definition: SimpleDiffIK.h:50
armarx::SimpleDiffIK::Result::oriDiff
Eigen::Vector3f oriDiff
Definition: SimpleDiffIK.h:74
armarx::CartesianPositionController
Definition: CartesianPositionController.h:42
armarx::SimpleDiffIKProvider::SolveAbsolute
DiffIKResult SolveAbsolute(const Eigen::Matrix4f &targetPose)
Definition: SimpleDiffIK.cpp:168
armarx::DiffIKResult::reachable
bool reachable
Definition: DiffIKProvider.h:36
armarx::SimpleDiffIK::IKStep
Definition: SimpleDiffIK.h:58
min
T min(T t1, T t2)
Definition: gdiam.h:44
armarx::SimpleDiffIK::Reachability::ikResults
std::vector< Result > ikResults
Definition: SimpleDiffIK.h:91
armarx::SimpleDiffIK::Parameters::stepsFineTune
size_t stepsFineTune
Definition: SimpleDiffIK.h:49
armarx::ctrlutil::s
double s(double t, double s0, double v0, double a0, double j)
Definition: CtrlUtil.h:33
armarx::CartesianPositionController::getOrientationError
float getOrientationError(const Eigen::Matrix4f &targetPose) const
Definition: CartesianPositionController.cpp:110
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:27
armarx::SimpleDiffIK::Parameters::resetRnsValues
bool resetRnsValues
Definition: SimpleDiffIK.h:55
armarx::SimpleDiffIK::Reachability::maxPosError
float maxPosError
Definition: SimpleDiffIK.h:89