NaturalIK.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 "NaturalIK.h"
25 
26 #include <SimoxUtility/math/convert/deg_to_rad.h>
27 #include <SimoxUtility/math/convert/rad_to_deg.h>
28 #include <VirtualRobot/Nodes/RobotNode.h>
29 #include <VirtualRobot/RobotNodeSet.h>
30 #include <VirtualRobot/math/Helpers.h>
31 
34 
35 using namespace armarx;
36 
37 NaturalIK::NaturalIK(std::string side, Eigen::Vector3f shoulderPos, float scale) :
38  side(side), shoulderPos(shoulderPos), scale(scale)
39 {
40 }
41 
43 NaturalIK::solveSoechtingIK(const Eigen::Vector3f& targetPos, std::optional<float> minElbowHeight)
44 {
45  Eigen::Vector3f vtgt = targetPos;
46 
49  for (int i = 1; i < soechtingIterations; i++)
50  {
51  Eigen::Vector3f err = targetPos - fwd.wrist;
52  vtgt = vtgt + err;
54  }
55 
56 
57  //ARMARX_IMPORTANT << VAROUT(fwd.elbow.z()) << VAROUT(minElbowHeight.value_or(-999));
58 
59  // this could be solved analytically.
60  if (minElbowHeight.has_value() && minElbowHeight.value() > fwd.elbow.z())
61  {
62  float mEH = minElbowHeight.value();
63  float lo = 0;
64  float hi = side == "Right" ? -M_PI : M_PI;
65  Eigen::Vector3f wri_n = (fwd.wrist - shoulderPos).normalized();
66  Eigen::Vector3f elb = fwd.elbow;
67  for (int i = 0; i < 20; i++)
68  {
69  float a = (lo + hi) / 2;
70  Eigen::AngleAxisf aa(a, wri_n);
71  elb = shoulderPos + aa * (fwd.elbow - shoulderPos);
72  if (elb.z() > mEH)
73  {
74  hi = a;
75  }
76  else
77  {
78  lo = a;
79  }
80  }
81  fwd.elbow = elb;
82  }
83 
84  return fwd;
85 }
86 
89  ArmJoints arm,
90  NaturalIK::Parameters params)
91 {
92  Eigen::Vector3f targetPos = math::Helpers::Position(targetPose);
94  solveSoechtingIK(targetPos, params.minimumElbowHeight);
95  return NaturalDiffIK::CalculateDiffIK(targetPose,
96  fwd.elbow,
97  arm.rns,
98  arm.tcp,
99  arm.elbow,
101  params.diffIKparams);
102 }
103 
105 NaturalIK::calculateIKpos(const Eigen::Vector3f& targetPos,
107  NaturalIK::Parameters params)
108 {
111  solveSoechtingIK(targetPos, params.minimumElbowHeight);
112  return NaturalDiffIK::CalculateDiffIK(targetPose,
113  fwd.elbow,
114  arm.rns,
115  arm.tcp,
116  arm.elbow,
118  params.diffIKparams);
119 }
120 
124  NaturalDiffIK::Mode setOri,
125  NaturalIK::Parameters params)
126 {
127  Eigen::Vector3f targetPos = math::Helpers::Position(targetPose);
129  solveSoechtingIK(targetPos, params.minimumElbowHeight);
130  //VirtualRobot::IKSolver::CartesianSelection mode = setOri ? VirtualRobot::IKSolver::All : VirtualRobot::IKSolver::Position;
132  targetPose, fwd.elbow, arm.rns, arm.tcp, arm.elbow, setOri, params.diffIKparams);
133 }
134 
135 Eigen::Vector3f
137 {
138  return shoulderPos;
139 }
140 
143 {
144  target = target - shoulderPos;
145  if (side == "Right")
146  {
147  target = target / scale;
148  }
149  else if (side == "Left")
150  {
151  target = target / scale;
152  target(0) = -target(0);
153  }
154  else
155  {
156  throw LocalException("Unsupported side: ") << side << ". supported are Left|Right.";
157  }
158 
159  target = target / 10; // Soechting is defined in cm
160  float x = target(0);
161  float y = target(1);
162  float z = target(2);
163 
164  float R = target.norm();
165  float Chi = simox::math::rad_to_deg(std::atan2(x, y));
166  float Psi = simox::math::rad_to_deg(std::atan2(z, std::sqrt(x * x + y * y)));
167 
168  //ARMARX_IMPORTANT << "target: " << target.transpose() << " " << VAROUT(R) << VAROUT(Chi) << VAROUT(Psi);
169 
170  // Angles derived from accurate pointing
171  //SoechtingAngles sa;
172  //sa.SE = -6.7 + 1.09*R + 1.10*Psi;
173  //sa.EE = 47.6 + 0.33*R - 0.95*Psi;
174  //sa.EY = -11.5 + 1.27*Chi - 0.54*Psi;
175  //sa.SY = 67.7 + 1.00*Chi - 0.68*R;
176 
177  // Angles derived from pointing in the dark
178  SoechtingAngles sa;
179  sa.SE = -4.0 + 1.10 * R + 0.90 * Psi;
180  sa.EE = 39.4 + 0.54 * R - 1.06 * Psi;
181  sa.SY = 13.2 + 0.86 * Chi + 0.11 * Psi;
182  sa.EY = -10.0 + 1.08 * Chi - 0.35 * Psi;
183 
184  sa.SE = simox::math::deg_to_rad(sa.SE);
185  sa.SY = simox::math::deg_to_rad(sa.SY);
186  sa.EE = simox::math::deg_to_rad(sa.EE);
187  sa.EY = simox::math::deg_to_rad(sa.EY);
188 
189  if (side == "Left")
190  {
191  sa.SY = -sa.SY;
192  sa.EY = -sa.EY;
193  }
194 
195  return sa;
196 }
197 
200 {
201  Eigen::AngleAxisf aaSE(sa.SE, Eigen::Vector3f::UnitX());
202  Eigen::AngleAxisf aaSY(-sa.SY, Eigen::Vector3f::UnitZ());
203  Eigen::AngleAxisf aaEE(-sa.EE, Eigen::Vector3f::UnitX());
204  Eigen::AngleAxisf aaEY(-sa.EY, Eigen::Vector3f::UnitZ());
205  Eigen::Vector3f elb = -Eigen::Vector3f::UnitZ() * upperArmLength;
206  elb = aaSY * aaSE * elb;
207  Eigen::Vector3f wri = Eigen::Vector3f::UnitZ() * lowerArmLength;
208  wri = aaEY * aaEE * wri;
209  //ARMARX_IMPORTANT << VAROUT(elb.transpose()) << VAROUT(wri.transpose());
210 
212  res.shoulder = shoulderPos;
213  res.elbow = shoulderPos + elb;
214  res.wrist = shoulderPos + elb + wri;
215  res.soechtingAngles = sa;
216 
217  return res;
218 }
219 
220 void
222 {
223  this->scale = scale;
224 }
225 
226 float
228 {
229  return scale;
230 }
231 
232 float
234 {
235  return upperArmLength;
236 }
237 
238 void
240 {
241  upperArmLength = value;
242 }
243 
244 float
246 {
247  return lowerArmLength;
248 }
249 
250 void
252 {
253  lowerArmLength = value;
254 }
255 
257  const NaturalIK::ArmJoints& arm,
258  const NaturalDiffIK::Mode& setOri,
259  const NaturalIK::Parameters& params) :
260  natik(natik), arm(arm), setOri(setOri), params(params)
261 {
262 }
263 
266 {
267  params.diffIKparams.resetRnsValues = true;
268  NaturalDiffIK::Result result = natik.calculateIK(targetPose, arm, setOri, params);
269  DiffIKResult r;
270  r.jointValues = arm.rns->getJointValuesEigen();
271  r.oriError = result.oriError;
272  r.posError = result.posError;
273  r.reachable = result.reached;
274  return r;
275 }
276 
279  const Eigen::VectorXf& startJointValues)
280 {
281  params.diffIKparams.resetRnsValues = false;
282  arm.rns->setJointValues(startJointValues);
283  NaturalDiffIK::Result result = natik.calculateIK(targetPose, arm, setOri, params);
284  DiffIKResult r;
285  r.jointValues = arm.rns->getJointValuesEigen();
286  r.oriError = result.oriError;
287  r.posError = result.posError;
288  r.reachable = result.reached;
289  return r;
290 }
armarx::NaturalDiffIK::Mode::All
@ All
armarx::NaturalIK::Parameters
Definition: NaturalIK.h:55
armarx::NaturalIK::SoechtingAngles
Definition: NaturalIK.h:73
armarx::DiffIKResult
Definition: DiffIKProvider.h:34
armarx::natik
Brief description of class natik.
Definition: natik.h:38
armarx::NaturalDiffIK::Mode::Position
@ Position
armarx::navigation::core::Pose
Eigen::Isometry3f Pose
Definition: basic_types.h:31
armarx::NaturalIK::calculateIK
NaturalDiffIK::Result calculateIK(const Eigen::Matrix4f &targetPose, ArmJoints arm, NaturalIK::Parameters params=NaturalIK::Parameters())
Definition: NaturalIK.cpp:88
armarx::NaturalIK::ArmJoints::tcp
VirtualRobot::RobotNodePtr tcp
Definition: NaturalIK.h:70
armarx::NaturalIK::SoechtingForwardPositions::wrist
Eigen::Vector3f wrist
Definition: NaturalIK.h:98
GfxTL::Matrix4f
MatrixXX< 4, 4, float > Matrix4f
Definition: MatrixXX.h:650
armarx::NaturalDiffIK::Mode
Mode
Definition: NaturalDiffIK.h:34
armarx::DiffIKResult::posError
float posError
Definition: DiffIKProvider.h:37
armarx::NaturalIK::ArmJoints::elbow
VirtualRobot::RobotNodePtr elbow
Definition: NaturalIK.h:68
armarx::NaturalIK::SoechtingAngles::EE
float EE
Definition: NaturalIK.h:77
boost::target
Vertex target(const detail::edge_base< Directed, Vertex > &e, const PCG &)
Definition: point_cloud_graph.h:668
armarx::NaturalDiffIK::Result::reached
bool reached
Definition: NaturalDiffIK.h:85
armarx::NaturalIK::CalculateSoechtingAngles
SoechtingAngles CalculateSoechtingAngles(Eigen::Vector3f target)
NaturalIK::CalculateSoechtingAngles.
Definition: NaturalIK.cpp:142
armarx::DiffIKResult::jointValues
Eigen::VectorXf jointValues
Definition: DiffIKProvider.h:39
lo
#define lo(x)
Definition: AbstractInterface.h:47
armarx::NaturalIK::ArmJoints
Definition: NaturalIK.h:65
armarx::DiffIKResult::oriError
float oriError
Definition: DiffIKProvider.h:38
armarx::NaturalIK::getScale
float getScale()
Definition: NaturalIK.cpp:227
armarx::NaturalIK::SoechtingAngles::SY
float SY
Definition: NaturalIK.h:76
armarx::NaturalIK::setLowerArmLength
void setLowerArmLength(float value)
Definition: NaturalIK.cpp:251
armarx::NaturalDiffIK::Result::oriError
float oriError
Definition: NaturalDiffIK.h:84
armarx::NaturalIK::NaturalIK
NaturalIK(std::string side, Eigen::Vector3f shoulderPos=Eigen::Vector3f::Zero(), float scale=1)
Definition: NaturalIK.cpp:37
armarx::NaturalIK
The NaturalIK class.
Definition: NaturalIK.h:52
GfxTL::Identity
void Identity(MatrixXX< N, N, T > *a)
Definition: MatrixXX.h:570
armarx::ctrlutil::a
double a(double t, double a0, double j)
Definition: CtrlUtil.h:45
cxxopts::value
std::shared_ptr< Value > value()
Definition: cxxopts.hpp:855
armarx::NaturalIK::setUpperArmLength
void setUpperArmLength(float value)
Definition: NaturalIK.cpp:239
armarx::NaturalIKProvider::NaturalIKProvider
NaturalIKProvider(const NaturalIK &natik, const NaturalIK::ArmJoints &arm, const NaturalDiffIK::Mode &setOri, const NaturalIK::Parameters &params=NaturalIK::Parameters())
Definition: NaturalIK.cpp:256
M_PI
#define M_PI
Definition: MathTools.h:17
armarx::NaturalIK::setScale
void setScale(float scale)
Definition: NaturalIK.cpp:221
armarx::NaturalIK::forwardKinematics
SoechtingForwardPositions forwardKinematics(SoechtingAngles sa)
Definition: NaturalIK.cpp:199
armarx::NaturalIK::Parameters::diffIKparams
NaturalDiffIK::Parameters diffIKparams
Definition: NaturalIK.h:61
armarx::NaturalDiffIK::Result::posError
float posError
Definition: NaturalDiffIK.h:82
armarx::NaturalIK::calculateIKpos
NaturalDiffIK::Result calculateIKpos(const Eigen::Vector3f &targetPos, ArmJoints arm, NaturalIK::Parameters params=NaturalIK::Parameters())
Definition: NaturalIK.cpp:105
armarx::NaturalDiffIK::Parameters::resetRnsValues
bool resetRnsValues
Definition: NaturalDiffIK.h:56
armarx::NaturalIK::getLowerArmLength
float getLowerArmLength() const
Definition: NaturalIK.cpp:245
armarx::NaturalIK::ArmJoints::rns
VirtualRobot::RobotNodeSetPtr rns
Definition: NaturalIK.h:67
armarx::NaturalIK::SoechtingForwardPositions::elbow
Eigen::Vector3f elbow
Definition: NaturalIK.h:97
armarx::NaturalIK::getShoulderPos
Eigen::Vector3f getShoulderPos()
Definition: NaturalIK.cpp:136
GfxTL::sqrt
VectorXD< D, T > sqrt(const VectorXD< D, T > &a)
Definition: VectorXD.h:704
armarx::NaturalIK::SoechtingAngles::SE
float SE
Definition: NaturalIK.h:75
armarx::NaturalIK::Parameters::minimumElbowHeight
std::optional< float > minimumElbowHeight
Definition: NaturalIK.h:62
hi
#define hi(x)
Definition: AbstractInterface.h:46
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::NaturalIK::SoechtingForwardPositions
Definition: NaturalIK.h:94
armarx::DiffIKResult::reachable
bool reachable
Definition: DiffIKProvider.h:36
armarx::NaturalDiffIK::Result
Definition: NaturalDiffIK.h:76
armarx::NaturalIKProvider::SolveAbsolute
DiffIKResult SolveAbsolute(const Eigen::Matrix4f &targetPose)
Definition: NaturalIK.cpp:265
Logging.h
armarx::navigation::core::Position
Eigen::Vector3f Position
Definition: basic_types.h:36
armarx::NaturalIKProvider::SolveRelative
DiffIKResult SolveRelative(const Eigen::Matrix4f &targetPose, const Eigen::VectorXf &startJointValues)
Definition: NaturalIK.cpp:278
armarx::NaturalIK::solveSoechtingIK
NaturalIK::SoechtingForwardPositions solveSoechtingIK(const Eigen::Vector3f &targetPos, std::optional< float > minElbowHeight=std::nullopt)
Definition: NaturalIK.cpp:43
armarx::NaturalIK::SoechtingAngles::EY
float EY
Definition: NaturalIK.h:78
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:27
armarx::NaturalIK::SoechtingForwardPositions::soechtingAngles
SoechtingAngles soechtingAngles
Definition: NaturalIK.h:99
Exception.h
NaturalIK.h
armarx::NaturalIK::getUpperArmLength
float getUpperArmLength() const
Definition: NaturalIK.cpp:233
armarx::NaturalIK::SoechtingForwardPositions::shoulder
Eigen::Vector3f shoulder
Definition: NaturalIK.h:96