NaturalDiffIK.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 
25 #include "NaturalDiffIK.h"
26 
27 #include <cfloat>
28 
29 #include <VirtualRobot/IK/DifferentialIK.h>
30 #include <VirtualRobot/Nodes/RobotNode.h>
31 #include <VirtualRobot/RobotNodeSet.h>
32 
35 
36 namespace armarx
37 {
38  Eigen::VectorXf
39  NaturalDiffIK::LimitInfNormTo(Eigen::VectorXf vec, float maxValue)
40  {
41  float infNorm = vec.lpNorm<Eigen::Infinity>();
42  if (infNorm > maxValue)
43  {
44  vec = vec / infNorm * maxValue;
45  }
46  return vec;
47  }
48 
51  const Eigen::Vector3f& elbowTarget,
52  VirtualRobot::RobotNodeSetPtr rns,
53  VirtualRobot::RobotNodePtr tcp,
54  VirtualRobot::RobotNodePtr elbow,
55  Mode setOri,
56  Parameters params)
57  {
59 
60  CartesianVelocityController vcTcp(rns);
61  CartesianPositionController pcTcp(tcp);
62  CartesianVelocityController vcElb(rns, elbow);
63  CartesianPositionController pcElb(elbow);
64 
65  if (params.resetRnsValues)
66  {
67  for (VirtualRobot::RobotNodePtr rn : rns->getAllRobotNodes())
68  {
69  if (rn->isLimitless())
70  {
71  rn->setJointValue(0);
72  }
73  else
74  {
75  rn->setJointValue((rn->getJointLimitHi() + rn->getJointLimitLo()) / 2);
76  }
77  }
78  }
79 
80 
81  //std::stringstream ss;
82 
83  //ARMARX_IMPORTANT << "start";
84 
85  int posMet = 0;
86  int oriMet = 0;
87 
88  std::vector<IKStep> ikSteps;
89  Eigen::VectorXf currentJointValues = rns->getJointValuesEigen();
90  for (size_t i = 0; i <= params.stepsInitial + params.stepsFineTune; i++)
91  {
92  //ss << pdTcp.norm() << " ## " << odTcp.norm() << " ## " << pdElb.norm() << std::endl;
93 
94  int posLen = mode & VirtualRobot::IKSolver::Position ? 3 : 0;
95  int oriLen = mode & VirtualRobot::IKSolver::Orientation ? 3 : 0;
96  Eigen::Vector3f pdTcp =
97  posLen ? pcTcp.getPositionDiff(targetPose) : Eigen::Vector3f::Zero();
98  Eigen::Vector3f odTcp =
99  oriLen ? pcTcp.getOrientationDiff(targetPose) : Eigen::Vector3f::Zero();
100  Eigen::VectorXf cartesianVel(posLen + oriLen);
101  if (posLen)
102  {
103  cartesianVel.block<3, 1>(0, 0) = pdTcp;
104  }
105  if (oriLen)
106  {
107  cartesianVel.block<3, 1>(posLen, 0) = odTcp;
108  }
109 
110  Eigen::Vector3f pdElb = pcElb.getPositionDiffVec3(elbowTarget);
111  Eigen::VectorXf cartesianVelElb(3);
112  cartesianVelElb.block<3, 1>(0, 0) = pdElb;
113  Eigen::VectorXf jvElb =
114  params.elbowKp * vcElb.calculate(cartesianVelElb, VirtualRobot::IKSolver::Position);
115  Eigen::VectorXf jvLA =
117  Eigen::VectorXf jv = vcTcp.calculate(cartesianVel, jvElb + jvLA, mode);
118 
119 
120  float stepLength =
121  i < params.stepsInitial ? params.ikStepLengthInitial : params.ikStepLengthFineTune;
122  Eigen::VectorXf jvClamped = jv * stepLength;
123  jvClamped = LimitInfNormTo(jvClamped, params.maxJointAngleStep);
124 
125  if (params.returnIKSteps)
126  {
127  IKStep s;
128  s.pdTcp = pdTcp;
129  s.odTcp = odTcp;
130  s.pdElb = pdElb;
131  s.tcpPose = tcp->getPoseInRootFrame();
132  s.elbPose = elbow->getPoseInRootFrame();
133  s.cartesianVel = cartesianVel;
134  s.cartesianVelElb = cartesianVelElb;
135  s.jvElb = jvElb;
136  s.jvLA = jvLA;
137  s.jv = jv;
138  s.jvClamped = jvClamped;
139  ikSteps.emplace_back(s);
140  }
141 
142 
143  Eigen::VectorXf newJointValues = currentJointValues + jvClamped;
144  rns->setJointValues(newJointValues);
145  currentJointValues = newJointValues;
146 
147  if (pdTcp.norm() > params.maxPosError)
148  {
149  posMet = 0;
150  }
151  else
152  {
153  posMet++;
154  }
155  if (odTcp.norm() > params.maxOriError)
156  {
157  oriMet = 0;
158  }
159  else
160  {
161  oriMet++;
162  }
163 
164  // terminate early, if reached for at least 3 iterations
165  if (posMet > 2 && oriMet > 2)
166  {
167  break;
168  }
169  }
170 
171  //ARMARX_IMPORTANT << ss.str();
172 
173  Result result;
174  result.ikSteps = ikSteps;
175  result.jointValues = rns->getJointValuesEigen();
176  result.posDiff = pcTcp.getPositionDiff(targetPose);
177  result.oriDiff = pcTcp.getOrientationDiff(targetPose);
178  result.posError = pcTcp.getPositionError(targetPose);
179  result.oriError = pcTcp.getOrientationError(targetPose);
180  result.reached = result.posError < params.maxPosError &&
181  (setOri == Mode::Position || result.oriError < params.maxOriError);
182  result.posDiffElbow = pcElb.getPositionDiffVec3(elbowTarget);
183  result.posErrorElbow = result.posDiffElbow.norm();
184 
185  result.jointLimitMargins = Eigen::VectorXf::Zero(rns->getSize());
186  result.minimumJointLimitMargin = FLT_MAX;
187  for (size_t i = 0; i < rns->getSize(); i++)
188  {
189  VirtualRobot::RobotNodePtr rn = rns->getNode(i);
190  if (rn->isLimitless())
191  {
192  result.jointLimitMargins(i) = M_PI;
193  }
194  else
195  {
196  result.jointLimitMargins(i) = std::min(rn->getJointValue() - rn->getJointLimitLo(),
197  rn->getJointLimitHi() - rn->getJointValue());
198  result.minimumJointLimitMargin =
200  }
201  }
202 
203  return result;
204  }
205 
208  {
209  return mode == Mode::All ? VirtualRobot::IKSolver::All : VirtualRobot::IKSolver::Position;
210  }
211 
212 
213 } // namespace armarx
armarx::NaturalDiffIK::Parameters::stepsInitial
size_t stepsInitial
Definition: NaturalDiffIK.h:49
NaturalDiffIK.h
armarx::NaturalDiffIK::Parameters::maxJointAngleStep
float maxJointAngleStep
Definition: NaturalDiffIK.h:55
armarx::CartesianVelocityController::calculate
Eigen::VectorXf calculate(const Eigen::VectorXf &cartesianVel, VirtualRobot::IKSolver::CartesianSelection mode)
Definition: CartesianVelocityController.cpp:80
armarx::NaturalDiffIK::Mode::All
@ All
GfxTL::Orientation
ScalarT Orientation(const VectorXD< 2, ScalarT > &p1, const VectorXD< 2, ScalarT > &p2, const VectorXD< 2, ScalarT > &c)
Definition: Orientation.h:10
armarx::NaturalDiffIK::Mode::Position
@ Position
armarx::NaturalDiffIK::LimitInfNormTo
static Eigen::VectorXf LimitInfNormTo(Eigen::VectorXf vec, float maxValue)
Definition: NaturalDiffIK.cpp:39
GfxTL::Matrix4f
MatrixXX< 4, 4, float > Matrix4f
Definition: MatrixXX.h:650
armarx::NaturalDiffIK::Mode
Mode
Definition: NaturalDiffIK.h:34
armarx::NaturalDiffIK::Result::reached
bool reached
Definition: NaturalDiffIK.h:85
armarx::CartesianVelocityController
Definition: CartesianVelocityController.h:36
armarx::CartesianPositionController::getPositionDiff
Eigen::Vector3f getPositionDiff(const Eigen::Matrix4f &targetPose) const
Definition: CartesianPositionController.cpp:182
armarx::CartesianPositionController::getPositionError
float getPositionError(const Eigen::Matrix4f &targetPose) const
Definition: CartesianPositionController.cpp:104
armarx::NaturalDiffIK::Result::posDiffElbow
Eigen::Vector3f posDiffElbow
Definition: NaturalDiffIK.h:80
armarx::NaturalDiffIK::Result::oriError
float oriError
Definition: NaturalDiffIK.h:84
armarx::CartesianPositionController::getPositionDiffVec3
Eigen::Vector3f getPositionDiffVec3(const Eigen::Vector3f &targetPosition) const
Definition: CartesianPositionController.cpp:190
M_PI
#define M_PI
Definition: MathTools.h:17
armarx::NaturalDiffIK::Parameters::maxOriError
float maxOriError
Definition: NaturalDiffIK.h:52
armarx::NaturalDiffIK::Parameters::maxPosError
float maxPosError
Definition: NaturalDiffIK.h:51
armarx::NaturalDiffIK::Result::posError
float posError
Definition: NaturalDiffIK.h:82
armarx::NaturalDiffIK::Result::posErrorElbow
float posErrorElbow
Definition: NaturalDiffIK.h:83
armarx::NaturalDiffIK::Result::oriDiff
Eigen::Vector3f oriDiff
Definition: NaturalDiffIK.h:81
armarx::NJointTaskSpaceDMPControllerMode::CartesianSelection
CartesianSelection
Definition: ControllerInterface.ice:34
armarx::NaturalDiffIK::Result::posDiff
Eigen::Vector3f posDiff
Definition: NaturalDiffIK.h:79
armarx::NaturalDiffIK::Result::jointValues
Eigen::VectorXf jointValues
Definition: NaturalDiffIK.h:78
armarx::NaturalDiffIK::Parameters::resetRnsValues
bool resetRnsValues
Definition: NaturalDiffIK.h:56
armarx::NaturalDiffIK::Parameters::ikStepLengthFineTune
float ikStepLengthFineTune
Definition: NaturalDiffIK.h:48
armarx::CartesianVelocityController::calculateJointLimitAvoidance
Eigen::VectorXf calculateJointLimitAvoidance()
Definition: CartesianVelocityController.cpp:171
CartesianVelocityController.h
CartesianPositionController.h
armarx::NaturalDiffIK::Parameters::stepsFineTune
size_t stepsFineTune
Definition: NaturalDiffIK.h:50
armarx::CartesianPositionController::getOrientationDiff
Eigen::Vector3f getOrientationDiff(const Eigen::Matrix4f &targetPose) const
Definition: CartesianPositionController.cpp:196
armarx::NaturalDiffIK::ModeToCartesianSelection
static VirtualRobot::IKSolver::CartesianSelection ModeToCartesianSelection(Mode mode)
Definition: NaturalDiffIK.cpp:207
armarx::NaturalDiffIK::Parameters::jointLimitAvoidanceKp
float jointLimitAvoidanceKp
Definition: NaturalDiffIK.h:53
armarx::NaturalDiffIK::CalculateDiffIK
static Result CalculateDiffIK(const Eigen::Matrix4f &targetPose, const Eigen::Vector3f &elbowTarget, VirtualRobot::RobotNodeSetPtr rns, VirtualRobot::RobotNodePtr tcp, VirtualRobot::RobotNodePtr elbow, Mode setOri, Parameters params=Parameters())
Definition: NaturalDiffIK.cpp:50
armarx::CartesianPositionController
Definition: CartesianPositionController.h:42
armarx::NaturalDiffIK::Parameters
Definition: NaturalDiffIK.h:40
armarx::NaturalDiffIK::Result
Definition: NaturalDiffIK.h:76
armarx::navigation::core::Position
Eigen::Vector3f Position
Definition: basic_types.h:36
min
T min(T t1, T t2)
Definition: gdiam.h:44
armarx::NaturalDiffIK::Parameters::returnIKSteps
bool returnIKSteps
Definition: NaturalDiffIK.h:57
armarx::NaturalDiffIK::IKStep
Definition: NaturalDiffIK.h:60
armarx::NaturalDiffIK::Parameters::ikStepLengthInitial
float ikStepLengthInitial
Definition: NaturalDiffIK.h:47
armarx::NaturalDiffIK::Result::ikSteps
std::vector< IKStep > ikSteps
Definition: NaturalDiffIK.h:89
armarx::NaturalDiffIK::Parameters::elbowKp
float elbowKp
Definition: NaturalDiffIK.h:54
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::NaturalDiffIK::Result::minimumJointLimitMargin
float minimumJointLimitMargin
Definition: NaturalDiffIK.h:87
armarx::NaturalDiffIK::Result::jointLimitMargins
Eigen::VectorXf jointLimitMargins
Definition: NaturalDiffIK.h:86