- 3.0.2 rigid body dynamics module.
TermTaskspacePose.hpp
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 #ifdef CPPADCG
9 
12 
15 #include <ct/rbd/state/RBDState.h>
16 
17 
18 namespace ct {
19 namespace rbd {
20 
21 
33 template <class KINEMATICS, bool FB, size_t STATE_DIM, size_t CONTROL_DIM>
34 class TermTaskspacePose : public optcon::TermBase<STATE_DIM, CONTROL_DIM, double, ct::core::ADCGScalar>
35 {
36 public:
37  using SCALAR = ct::core::ADCGScalar;
38  using BASE = optcon::TermBase<STATE_DIM, CONTROL_DIM, double, ct::core::ADCGScalar>;
39 
41 
42  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
43 
45  TermTaskspacePose() {}
47  TermTaskspacePose(size_t eeInd,
48  const Eigen::Matrix<double, 3, 3>& Qpos,
49  const double& Qrot,
50  const ct::rbd::RigidBodyPose& rbdPose,
51  const std::string& name = "TermTaskSpace")
52  // delegate constructor
53  : TermTaskspacePose(eeInd,
54  Qpos,
55  Qrot,
56  rbdPose.position().toImplementation(),
57  rbdPose.getRotationQuaternion().toImplementation(),
58  name)
59  {
60  }
62  TermTaskspacePose(size_t eeInd,
63  const Eigen::Matrix<double, 3, 3>& Qpos,
64  const double& Qrot,
65  const core::StateVector<3, double>& w_pos_des,
66  const Eigen::Quaternion<double>& w_q_des,
67  const std::string& name = "TermTaskSpace")
68  : BASE(name),
69  eeInd_(eeInd),
70  Q_pos_(Qpos),
71  Q_rot_(Qrot),
72  w_p_ref_(w_pos_des),
73  w_R_ref_(w_q_des.normalized().toRotationMatrix())
74  {
75  }
76 
78  TermTaskspacePose(size_t eeInd,
79  const Eigen::Matrix<double, 3, 3>& Qpos,
80  const double& Qrot,
81  const core::StateVector<3, double>& w_pos_des,
82  const Eigen::Matrix<double, 3, 1>& eulerXyz,
83  const std::string& name = "TermTaskSpace")
84  // delegate constructor
85  : TermTaskspacePose(eeInd,
86  Qpos,
87  Qrot,
88  w_pos_des,
89  Eigen::Quaternion<double>(Eigen::AngleAxisd(eulerXyz(0), Eigen::Vector3d::UnitX()) *
90  Eigen::AngleAxisd(eulerXyz(1), Eigen::Vector3d::UnitY()) *
91  Eigen::AngleAxisd(eulerXyz(2), Eigen::Vector3d::UnitZ())),
92  name)
93  {
94  }
95 
96 
98  TermTaskspacePose(std::string& configFile, const std::string& termName, bool verbose = false)
99  {
100  loadConfigFile(configFile, termName, verbose);
101  }
102 
104  TermTaskspacePose(const TermTaskspacePose& arg)
105  : BASE(arg),
106  eeInd_(arg.eeInd_),
107  kinematics_(KINEMATICS()),
108  Q_pos_(arg.Q_pos_),
109  Q_rot_(arg.Q_rot_),
110  w_p_ref_(arg.w_p_ref_),
111  w_R_ref_(arg.w_R_ref_)
112  {
113  }
114 
116  virtual ~TermTaskspacePose() {}
118  virtual TermTaskspacePose<KINEMATICS, FB, STATE_DIM, CONTROL_DIM>* clone() const override
119  {
120  return new TermTaskspacePose(*this);
121  }
122 
124  virtual SCALAR evaluate(const Eigen::Matrix<SCALAR, STATE_DIM, 1>& x,
125  const Eigen::Matrix<SCALAR, CONTROL_DIM, 1>& u,
126  const SCALAR& t) override
127  {
128  return evalLocal<SCALAR>(x, u, t);
129  }
130 
132  virtual ct::core::ADCGScalar evaluateCppadCg(const core::StateVector<STATE_DIM, ct::core::ADCGScalar>& x,
133  const core::ControlVector<CONTROL_DIM, ct::core::ADCGScalar>& u,
134  ct::core::ADCGScalar t) override
135  {
136  return evalLocal<ct::core::ADCGScalar>(x, u, t);
137  }
138 
140  void loadConfigFile(const std::string& filename, const std::string& termName, bool verbose = false) override
141  {
142  if (verbose)
143  std::cout << "Loading TermTaskspacePose from file " << filename << std::endl;
144 
145  ct::optcon::loadScalarCF(filename, "eeId", eeInd_, termName);
146  ct::optcon::loadScalarCF(filename, "Q_rot", Q_rot_, termName);
147 
148  ct::optcon::loadMatrixCF(filename, "Q_pos", Q_pos_, termName);
149  ct::optcon::loadMatrixCF(filename, "x_des", w_p_ref_, termName);
150 
151  // try loading euler angles
152  if (verbose)
153  std::cout << "trying to load euler angles" << std::endl;
154  try
155  {
156  Eigen::Vector3d eulerXyz;
157  ct::optcon::loadMatrixCF(filename, "eulerXyz_des", eulerXyz, termName);
158  Eigen::Quaternion<double> quat_des(Eigen::AngleAxisd(eulerXyz(0), Eigen::Vector3d::UnitX()) *
159  Eigen::AngleAxisd(eulerXyz(1), Eigen::Vector3d::UnitY()) *
160  Eigen::AngleAxisd(eulerXyz(2), Eigen::Vector3d::UnitZ()));
161  w_R_ref_ = quat_des.toRotationMatrix();
162  if (verbose)
163  std::cout << "Read desired Euler Angles Xyz as = \n" << eulerXyz.transpose() << std::endl;
164  } catch (const std::exception& e)
165  {
166  throw std::runtime_error(
167  "Failed to load TermTaskspacePose, could not find a desired end effector orientation in file.");
168  }
169 
170  if (verbose)
171  {
172  std::cout << "Read eeId as eeId = \n" << eeInd_ << std::endl;
173  std::cout << "Read Q_pos as Q_pos = \n" << Q_pos_ << std::endl;
174  std::cout << "Read Q_rot as Q_rot = \n" << Q_rot_ << std::endl;
175  std::cout << "Read x_des as x_des = \n" << w_p_ref_.transpose() << std::endl;
176  }
177  }
178 
179 
181  const Eigen::Matrix<double, 3, 1>& getReferencePosition() const { return w_p_ref_; }
183  const Eigen::Quaterniond getReferenceOrientation() const { return Eigen::Quaterniond(w_R_ref_); }
185  void setReferencePosition(const Eigen::Matrix<double, 3, 1>& w_p_ref) { w_p_ref_ = w_p_ref; }
187  void setReferenceOrientation(const Eigen::Matrix<double, 3, 3> w_R_ref) { w_R_ref_ = w_R_ref; }
189  const ct::rbd::RigidBodyPose getReferencePose() const
190  {
191  return ct::rbd::RigidBodyPose(getReferenceOrientation(), getReferencePosition());
192  }
193 
194 
195 protected:
202  virtual RBDStateTpl setStateFromVector(const Eigen::Matrix<SCALAR, STATE_DIM, 1>& x)
203  {
204  return setStateFromVector_specialized<FB>(x);
205  }
206 
207 private:
209  template <bool T>
210  RBDStateTpl setStateFromVector_specialized(const Eigen::Matrix<SCALAR, -1, 1>& x,
211  typename std::enable_if<T, bool>::type = true)
212  {
213  RBDStateTpl rbdState;
214  rbdState.fromStateVectorEulerXyz(x);
215 
216  return rbdState;
217  }
218 
220  template <bool T>
221  RBDStateTpl setStateFromVector_specialized(const Eigen::Matrix<SCALAR, -1, 1>& x,
222  typename std::enable_if<!T, bool>::type = true)
223  {
224  RBDStateTpl rbdState;
225  rbdState.joints().toImplementation() = x.head(STATE_DIM);
226  return rbdState;
227  }
228 
230  template <typename SC>
231  SC evalLocal(const Eigen::Matrix<SC, STATE_DIM, 1>& x, const Eigen::Matrix<SC, CONTROL_DIM, 1>& u, const SC& t)
232  {
233  using Matrix3Tpl = Eigen::Matrix<SC, 3, 3>;
234 
235  // transform the robot state vector into a CT RBDState
236  RBDState<KINEMATICS::NJOINTS, SC> rbdState = setStateFromVector(x);
237 
238  // position difference in world frame
239  Eigen::Matrix<SC, 3, 1> xDiff =
240  kinematics_.getEEPositionInWorld(eeInd_, rbdState.basePose(), rbdState.jointPositions())
241  .toImplementation() -
242  w_p_ref_.template cast<SC>();
243 
244  // compute the cost based on the position error
245  SC pos_cost = (xDiff.transpose() * Q_pos_.template cast<SC>() * xDiff)(0, 0);
246 
247 
248  // get current end-effector rotation in world frame
249  Matrix3Tpl ee_rot = kinematics_.getEERotInWorld(eeInd_, rbdState.basePose(), rbdState.jointPositions());
250 
251  // compute a measure for the difference between current rotation and desired rotation and compute cost based on the orientation error
252  // for the intuition behind, consider the following posts:
253  // https://math.stackexchange.com/a/87698
254  // https://math.stackexchange.com/a/773635
255  Matrix3Tpl ee_rot_diff = w_R_ref_.template cast<SC>().transpose() * ee_rot;
256 
257  SC rot_cost =
258  (SC)Q_rot_ * (ee_rot_diff - Matrix3Tpl::Identity()).squaredNorm(); // the frobenius norm of (R_diff-I)
259 
260  return pos_cost + rot_cost;
261  }
262 
264  size_t eeInd_;
265 
267  KINEMATICS kinematics_;
268 
270  Eigen::Matrix<double, 3, 3> Q_pos_;
271 
273  double Q_rot_;
274 
276  Eigen::Matrix<double, 3, 1> w_p_ref_;
277 
279  Eigen::Matrix<double, 3, 3> w_R_ref_;
280 };
281 
282 
283 } // namespace rbd
284 } // namespace ct
285 
286 #endif
Cored::Vector3 Vector3d
Definition: rbd.h:137
tpl::RigidBodyPose< double > RigidBodyPose
Definition: RigidBodyPose.h:426
Definition: eigen_traits.h:23
joint states and base states
Definition: RBDState.h:27
CppAD::AD< CppAD::cg::CG< double > > SCALAR
bool verbose
Definition: rbdJITtests.h:15
void loadScalarCF(const std::string &filename, const std::string &scalarName, SCALAR &scalar, const std::string &termName="")
double Qrot
Definition: rbdJITtests.h:28
const Eigen::Matrix< double, 3, 3 > Qpos
Definition: rbdJITtests.h:27
void loadMatrixCF(const std::string &filename, const std::string &matrixName, Eigen::Matrix< SCALAR, ROW, COL > &matrix, const std::string &termName="")