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