- 3.0.2 rigid body dynamics module.
IKNLPSolverIpopt.h
Go to the documentation of this file.
1 /**********************************************************************************************************************
2 This file is part of the Control Toolbox (https://github.com/ethz-adrl/control-toolbox), copyright by ETH Zurich.
3 Licensed under the BSD-2 license (see LICENSE file in main directory)
4 **********************************************************************************************************************/
5 
6 #pragma once
7 
8 #include <ct/optcon/optcon.h>
9 #include "IKNLP.h"
10 #include "../InverseKinematicsBase.h"
11 
12 namespace ct {
13 namespace rbd {
14 
15 #ifdef BUILD_WITH_IPOPT_SUPPORT // build IPOPT interface
16 
24 template <typename IKNLP, typename VALIDATION_KIN>
25 class IKNLPSolverIpopt final
26  : public ct::rbd::InverseKinematicsBase<IKNLP::Kinematics_t::NJOINTS, typename IKNLP::Scalar_t>,
28 {
29 public:
30  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
31 
32  using KINEMATICS = typename IKNLP::Kinematics_t;
33  using SCALAR = typename IKNLP::Scalar_t;
34 
39 
40  IKNLPSolverIpopt() = delete;
41 
43  IKNLPSolverIpopt(std::shared_ptr<IKNLP> iknlp,
44  ct::optcon::NlpSolverSettings nlpSolverSettings,
45  const size_t eeInd = 0)
46  : ct::optcon::IpoptSolver(std::static_pointer_cast<ct::optcon::tpl::Nlp<SCALAR>>(iknlp), nlpSolverSettings),
47  iknlp_(iknlp),
48  kinematics_(VALIDATION_KIN()),
49  eeInd_(eeInd),
50  noise_(0.5, 0.5) // uniform noise on interval [0, 1]
51  {
52  }
53 
55  IKNLPSolverIpopt(std::shared_ptr<IKNLP> iknlp,
56  ct::optcon::NlpSolverSettings nlpSolverSettings,
57  const ct::rbd::InverseKinematicsSettings& ikSettings,
58  const size_t eeInd = 0)
59  : IKNLPSolverIpopt(iknlp, nlpSolverSettings, eeInd)
60  {
61  this->updateSettings(ikSettings);
62  }
63 
64  void setInitialGuess(const JointPosition_t& q_init)
65  {
66  if (iknlp_)
67  iknlp_->setInitialGuess(q_init);
68  else
69  throw std::runtime_error("IKNLPSolverIpopt needs to be be initialized before setting an initial guess!");
70  }
71 
73  const RigidBodyPoseTpl& ee_W_base,
74  const std::vector<size_t>& freeJoints = std::vector<size_t>()) override
75  {
76  ikSolutions.clear();
77 
78  // get joint limits for proper initialization
79  JointPosition_t jointsLower = iknlp_->getIKConstraintContainer()->getJointLimitConstraints()->getLowerBound();
80  JointPosition_t jointsUpper = iknlp_->getIKConstraintContainer()->getJointLimitConstraints()->getUpperBound();
81 
82  iknlp_->getIKCostEvaluator()->setTargetPose(ee_W_base);
83 
84  size_t count = 0;
85 
86  bool solutionFound = false;
87 
88  while (count < this->getSettings().maxNumTrials_ && !solutionFound)
89  {
90  // set randomized initial guess if applicable
91  if (this->getSettings().randomizeInitialGuess_ && count != 0)
92  {
93  // generate random number between 0 and 1 for each joint
94  JointPosition_t randomJoints = noise_.gen<IKNLP::Kinematics_t::NJOINTS>();
95 
96  // interpolate between lower and upper bound on joints accordingly
97  JointPosition_t newInitGuess =
98  jointsLower + JointPosition_t((jointsUpper - jointsLower).array() * randomJoints.array());
99 
100  setInitialGuess(newInitGuess);
101  }
102 
103  // call underlying NLP solver
104  solve();
105 
106  JointPosition_t sol = iknlp_->getSolution();
107 
108  // check if the solve was actually successful by forward evaluation and comparison
109  RigidBodyPose forwardEval = kinematics_.getEEPoseInBase(eeInd_, sol);
110 
111  // evaluate if solution is near the desired pose and return
112  if (forwardEval.isNear(ee_W_base, this->getSettings().validationTol_))
113  {
114  ikSolutions.push_back(sol);
115  solutionFound = true;
116  }
117 
118  count++;
119  }
120 
121  return solutionFound;
122  }
123 
125  const RigidBodyPoseTpl& eeWorldPose,
126  const RigidBodyPoseTpl& baseWorldPose,
127  const std::vector<size_t>& freeJoints) override
128  {
129  return computeInverseKinematics(ikSolutions, eeWorldPose.inReferenceFrame(baseWorldPose), freeJoints);
130  }
131 
132 private:
133  std::shared_ptr<IKNLP> iknlp_;
134 
135  VALIDATION_KIN kinematics_; // for validation (todo: need different way to include double-based kinematics
136  size_t eeInd_; // for validation
137 
138  ct::core::UniformNoise noise_;
139 };
140 
141 #else // BUILD_WITH_IPOPT_SUPPORT -- not building with IPOPT support, create dummy class
142 
143 template <typename IKNLP, typename VALIDATION_KIN>
144 class IKNLPSolverIpopt : public ct::rbd::InverseKinematicsBase<IKNLP::Kinematics_t::NJOINTS, typename IKNLP::Scalar_t>
145 {
146 public:
147  using KINEMATICS = typename IKNLP::Kinematics_t;
148  using SCALAR = typename IKNLP::Scalar_t;
149 
154 
155  IKNLPSolverIpopt() { throw(std::runtime_error("Error - IPOPT interface not compiled.")); }
157  IKNLPSolverIpopt(std::shared_ptr<IKNLP> iknlp,
158  ct::optcon::NlpSolverSettings nlpSolverSettings,
159  const size_t eeInd = 0)
160  {
161  throw(std::runtime_error("Error - IPOPT interface not compiled."));
162  }
163 
165  IKNLPSolverIpopt(std::shared_ptr<IKNLP> iknlp,
166  ct::optcon::NlpSolverSettings nlpSolverSettings,
167  const ct::rbd::InverseKinematicsSettings& ikSettings,
168  const size_t eeInd = 0)
169  : IKNLPSolverIpopt(iknlp, nlpSolverSettings, eeInd)
170  {
171  throw(std::runtime_error("Error - IPOPT interface not compiled."));
172  }
173 
174  void setInitialGuess(const JointPosition_t& q_init) {}
176  const RigidBodyPoseTpl& ee_W_base,
177  const std::vector<size_t>& freeJoints = std::vector<size_t>()) override
178  {
179  return false;
180  }
181 
183  const RigidBodyPoseTpl& eeWorldPose,
184  const RigidBodyPoseTpl& baseWorldPose,
185  const std::vector<size_t>& freeJoints) override
186  {
187  return false;
188  }
189 };
190 
191 #endif // BUILD_WITH_IPOPT_SUPPORT
192 
193 
194 } // namespace rbd
195 } // namespace ct
tpl::Nlp< double > Nlp
KINEMATICS Kinematics_t
Definition: IKNLP.h:23
tpl::RigidBodyPose< double > RigidBodyPose
Definition: RigidBodyPose.h:426
typename InverseKinematicsBase::JointPositionsVector_t JointPositionsVector_t
Definition: IKNLPSolverIpopt.h:152
const InverseKinematicsSettings & getSettings() const
Definition: InverseKinematicsBase.h:122
IKNLPSolverIpopt(std::shared_ptr< IKNLP > iknlp, ct::optcon::NlpSolverSettings nlpSolverSettings, const size_t eeInd=0)
constructor
Definition: IKNLPSolverIpopt.h:157
CppAD::AD< CppAD::cg::CG< double > > SCALAR
Definition: IKNLPSolverIpopt.h:144
Definition: InverseKinematicsBase.h:25
Definition: InverseKinematicsBase.h:15
typename InverseKinematicsBase::JointPosition_t JointPosition_t
Definition: IKNLPSolverIpopt.h:151
SCALAR Scalar_t
Definition: IKNLP.h:22
void setInitialGuess(const JointPosition_t &q_init)
Definition: IKNLPSolverIpopt.h:174
typename JointState< NJOINTS, SCALAR >::Position JointPosition_t
Definition: InverseKinematicsBase.h:30
typename IKNLP::Scalar_t SCALAR
Definition: IKNLPSolverIpopt.h:148
IKNLPSolverIpopt(std::shared_ptr< IKNLP > iknlp, ct::optcon::NlpSolverSettings nlpSolverSettings, const ct::rbd::InverseKinematicsSettings &ikSettings, const size_t eeInd=0)
constructor with additional inverse kinematics settings
Definition: IKNLPSolverIpopt.h:165
bool computeInverseKinematics(JointPositionsVector_t &ikSolutions, const RigidBodyPoseTpl &ee_W_base, const std::vector< size_t > &freeJoints=std::vector< size_t >()) override
Definition: IKNLPSolverIpopt.h:175
tpl::IpoptSolver< double > IpoptSolver
typename InverseKinematicsBase::RigidBodyPoseTpl RigidBodyPoseTpl
Definition: IKNLPSolverIpopt.h:153
bool computeInverseKinematics(JointPositionsVector_t &ikSolutions, const RigidBodyPoseTpl &eeWorldPose, const RigidBodyPoseTpl &baseWorldPose, const std::vector< size_t > &freeJoints) override
Definition: IKNLPSolverIpopt.h:182
tpl::RigidBodyPose< SCALAR > RigidBodyPoseTpl
Definition: InverseKinematicsBase.h:32
void updateSettings(const InverseKinematicsSettings &settings)
Definition: InverseKinematicsBase.h:123
IKNLPSolverIpopt()
Definition: IKNLPSolverIpopt.h:155
typename IKNLP::Kinematics_t KINEMATICS
Definition: IKNLPSolverIpopt.h:147
std::vector< JointPosition_t, Eigen::aligned_allocator< JointPosition_t > > JointPositionsVector_t
Definition: InverseKinematicsBase.h:31