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
34namespace armarx
35{
37 SimpleDiffIK::CalculateDiffIK(const Eigen::Matrix4f targetPose,
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());
132 std::min(result.minimumJointLimitMargin, result.jointLimitMargins(i));
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,
163 rns(rns), tcp(tcp), params(params)
164 {
165 }
166
168 SimpleDiffIKProvider::SolveAbsolute(const Eigen::Matrix4f& targetPose)
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
181 SimpleDiffIKProvider::SolveRelative(const Eigen::Matrix4f& targetPose,
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 }
209 maxPosError = std::max(maxPosError, result.posError);
210 maxOriError = std::max(maxOriError, result.oriError);
211 }
212} // namespace armarx
#define M_PI
Definition MathTools.h:17
float getPositionError(const Eigen::Matrix4f &targetPose) const
float getOrientationError(const Eigen::Matrix4f &targetPose) const
Eigen::Vector3f getOrientationDiff(const Eigen::Matrix4f &targetPose) const
Eigen::Vector3f getPositionDiff(const Eigen::Matrix4f &targetPose) const
Eigen::VectorXf calculate(const Eigen::VectorXf &cartesianVel, VirtualRobot::IKSolver::CartesianSelection mode)
DiffIKResult SolveAbsolute(const Eigen::Matrix4f &targetPose)
SimpleDiffIKProvider(VirtualRobot::RobotNodeSetPtr rns, VirtualRobot::RobotNodePtr tcp=VirtualRobot::RobotNodePtr(), SimpleDiffIK::Parameters params=SimpleDiffIK::Parameters())
DiffIKResult SolveRelative(const Eigen::Matrix4f &targetPose, const Eigen::VectorXf &startJointValues)
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.
static Result CalculateDiffIK(const Eigen::Matrix4f targetPose, VirtualRobot::RobotNodeSetPtr rns, VirtualRobot::RobotNodePtr tcp=VirtualRobot::RobotNodePtr(), Parameters params=Parameters())
Brief description of class targets.
Definition targets.h:39
This file offers overloads of toIce() and fromIce() functions for STL container types.
Eigen::VectorXf jointValues
std::vector< Result > ikResults
void aggregate(const Result &result)
Eigen::VectorXf jointLimitMargins
std::vector< IKStep > ikSteps