SimpleFullbodyInverseKinematicsSolver.h
Go to the documentation of this file.
1 #ifndef SimpleFullbodyInverseKinematicsSolver_H
2 #define SimpleFullbodyInverseKinematicsSolver_H
3 
4 #include <hrpModel/Body.h>
5 #include "../ImpedanceController/JointPathEx.h"
6 #include "../ImpedanceController/RatsMatrix.h"
7 
8 // Class for Simple Fullbody Inverse Kinematics
9 // Input : target root pos and rot, target COG, target joint angles, target EE coords
10 // Output : joint angles
11 // Algorithm : Limb IK + move base
13 {
14 private:
15  // Robot model for IK
17  // Org (current) joint angles before IK
19  // IK fail checking
21  std::string print_str;
23 public:
24  // IK parameter for each limb
25  struct IKparam {
26  // IK target EE coords
29  // EE offset, EE link
33  // IK solver and parameter
36  // IK fail checking
38  // Solve ik or not
40  // Name of parent link in limb
41  std::string parent_name;
42  // Limb length
45  : avoid_gain(0.001), reference_gain(0.01),
46  pos_ik_error_count(0), rot_ik_error_count(0),
47  limb_length_margin(0.02)
48  {
49  };
50  };
51  std::map<std::string, IKparam> ikp;
52  // Used for ref joint angles overwrite before IK
53  std::vector<int> overwrite_ref_ja_index_vec;
54  // IK targets and current?
60  // IK params
62  // For IK fail checking
64  // For limb stretch avoidance
67 
68  SimpleFullbodyInverseKinematicsSolver (hrp::BodyPtr& _robot, const std::string& _print_str, const double _dt)
69  : m_robot(_robot),
70  ik_error_debug_print_freq(static_cast<int>(0.2/_dt)), // once per 0.2 [s]
71  has_ik_failed(false),
72  overwrite_ref_ja_index_vec(), ikp(),
73  move_base_gain(0.8), ratio_for_vel(1.0),
74  pos_ik_thre(0.5*1e-3), // [m]
75  rot_ik_thre((1e-2)*M_PI/180.0), // [rad]
76  print_str(_print_str), m_dt(_dt),
77  use_limb_stretch_avoidance(false), limb_stretch_avoidance_time_const(1.5)
78  {
79  qorg.resize(m_robot->numJoints());
80  qrefv.resize(m_robot->numJoints());
81  limb_stretch_avoidance_vlimit[0] = -1000 * 1e-3 * _dt; // lower limit
82  limb_stretch_avoidance_vlimit[1] = 50 * 1e-3 * _dt; // upper limit
83  };
85 
86  void initializeInterlockingJoints (std::vector<std::pair<hrp::Link*, hrp::Link*> > & interlocking_joints)
87  {
88  for ( std::map<std::string, IKparam>::iterator it = ikp.begin(); it != ikp.end(); it++ ) {
89  std::cerr << "[" << print_str << "] Interlocking Joints for [" << it->first << "]" << std::endl;
90  it->second.manip->setInterlockingJointPairIndices(interlocking_joints, print_str);
91  }
92  };
94  {
95  current_root_p = m_robot->rootLink()->p;
96  current_root_R = m_robot->rootLink()->R;
97  for ( unsigned int i = 0; i < m_robot->numJoints(); i++ ){
98  qorg[i] = m_robot->joint(i)->q;
99  }
100  };
102  {
103  for ( std::map<std::string, IKparam>::iterator it = ikp.begin(); it != ikp.end(); it++ ) {
104  if (it->second.is_ik_enable) {
105  for ( unsigned int j = 0; j < it->second.manip->numJoints(); j++ ){
106  int i = it->second.manip->joint(j)->jointId;
107  m_robot->joint(i)->q = qorg[i];
108  }
109  }
110  }
111  m_robot->rootLink()->p = current_root_p;
112  m_robot->rootLink()->R = current_root_R;
113  m_robot->calcForwardKinematics();
114  };
116  {
117  for ( unsigned int i = 0; i < m_robot->numJoints(); i++ ){
118  qrefv[i] = m_robot->joint(i)->q;
119  }
120  };
121  // Solve fullbody IK using limb IK
122  void solveFullbodyIK (const hrp::Vector3& _dif_cog, const bool is_transition)
123  {
124  hrp::Vector3 dif_cog(ratio_for_vel*_dif_cog);
125  dif_cog(2) = m_robot->rootLink()->p(2) - target_root_p(2);
126  m_robot->rootLink()->p = m_robot->rootLink()->p + -1 * move_base_gain * dif_cog;
127  m_robot->rootLink()->R = target_root_R;
128  // Avoid limb stretch
129  {
130  std::vector<hrp::Vector3> tmp_p;
131  std::vector<std::string> tmp_name;
132  for ( std::map<std::string, IKparam>::iterator it = ikp.begin(); it != ikp.end(); it++ ) {
133  if (it->first.find("leg") != std::string::npos) {
134  tmp_p.push_back(it->second.target_p0);
135  tmp_name.push_back(it->first);
136  }
137  }
138  limbStretchAvoidanceControl(tmp_p, tmp_name);
139  }
140  // Overwrite by ref joint angle
141  for (size_t i = 0; i < overwrite_ref_ja_index_vec.size(); i++) {
142  m_robot->joint(overwrite_ref_ja_index_vec[i])->q = qrefv[overwrite_ref_ja_index_vec[i]];
143  }
144  m_robot->calcForwardKinematics();
145  for ( std::map<std::string, IKparam>::iterator it = ikp.begin(); it != ikp.end(); it++ ) {
146  if (it->second.is_ik_enable) solveLimbIK (it->second, it->first, ratio_for_vel, is_transition);
147  }
148  };
149  // Solve limb IK
150  bool solveLimbIK (IKparam& param, const std::string& limb_name, const double ratio_for_vel, const bool is_transition)
151  {
152  param.manip->calcInverseKinematics2Loop(param.target_p0, param.target_r0, 1.0, param.avoid_gain, param.reference_gain, &qrefv, ratio_for_vel,
153  param.localPos, param.localR);
154  checkIKTracking(param, limb_name, is_transition);
155  return true;
156  }
157  // IK fail check
158  void checkIKTracking (IKparam& param, const std::string& limb_name, const bool is_transition)
159  {
160  hrp::Vector3 vel_p, vel_r;
161  vel_p = param.target_p0 - (param.target_link->p + param.target_link->R * param.localPos);
162  rats::difference_rotation(vel_r, (param.target_link->R * param.localR), param.target_r0);
163  if (vel_p.norm() > pos_ik_thre && is_transition) {
164  if (param.pos_ik_error_count % ik_error_debug_print_freq == 0) {
165  std::cerr << "[" << print_str << "] Too large IK error in " << limb_name << " (vel_p) = [" << vel_p(0) << " " << vel_p(1) << " " << vel_p(2) << "][m], count = " << param.pos_ik_error_count << std::endl;
166  }
167  param.pos_ik_error_count++;
168  has_ik_failed = true;
169  } else {
170  param.pos_ik_error_count = 0;
171  }
172  if (vel_r.norm() > rot_ik_thre && is_transition) {
173  if (param.rot_ik_error_count % ik_error_debug_print_freq == 0) {
174  std::cerr << "[" << print_str << "] Too large IK error in " << limb_name << " (vel_r) = [" << vel_r(0) << " " << vel_r(1) << " " << vel_r(2) << "][rad], count = " << param.rot_ik_error_count << std::endl;
175  }
176  param.rot_ik_error_count++;
177  has_ik_failed = true;
178  } else {
179  param.rot_ik_error_count = 0;
180  }
181  };
182  // Reset IK fail params
184  has_ik_failed = false;
185  for ( std::map<std::string, IKparam>::iterator it = ikp.begin(); it != ikp.end(); it++ ) {
186  it->second.pos_ik_error_count = it->second.rot_ik_error_count = 0;
187  }
188  }
189  // Get IKparam
190  void getIKParam (std::vector<std::string>& ee_vec, _CORBA_Unbounded_Sequence<OpenHRP::AutoBalancerService::IKLimbParameters>& ik_limb_parameters)
191  {
192  ik_limb_parameters.length(ee_vec.size());
193  for (size_t i = 0; i < ee_vec.size(); i++) {
194  IKparam& param = ikp[ee_vec[i]];
195  OpenHRP::AutoBalancerService::IKLimbParameters& ilp = ik_limb_parameters[i];
196  ilp.ik_optional_weight_vector.length(param.manip->numJoints());
197  std::vector<double> ov;
198  ov.resize(param.manip->numJoints());
199  param.manip->getOptionalWeightVector(ov);
200  for (size_t j = 0; j < param.manip->numJoints(); j++) {
201  ilp.ik_optional_weight_vector[j] = ov[j];
202  }
203  ilp.sr_gain = param.manip->getSRGain();
204  ilp.avoid_gain = param.avoid_gain;
205  ilp.reference_gain = param.reference_gain;
206  ilp.manipulability_limit = param.manip->getManipulabilityLimit();
207  }
208  };
209  // Set IKparam
210  void setIKParam (std::vector<std::string>& ee_vec, const _CORBA_Unbounded_Sequence<OpenHRP::AutoBalancerService::IKLimbParameters>& ik_limb_parameters)
211  {
212  std::cerr << "[" << print_str << "] IK limb parameters" << std::endl;
213  bool is_ik_limb_parameter_valid_length = true;
214  if (ik_limb_parameters.length() != ee_vec.size()) {
215  is_ik_limb_parameter_valid_length = false;
216  std::cerr << "[" << print_str << "] ik_limb_parameters invalid length! Cannot be set. (input = " << ik_limb_parameters.length() << ", desired = " << ee_vec.size() << ")" << std::endl;
217  } else {
218  for (size_t i = 0; i < ee_vec.size(); i++) {
219  if (ikp[ee_vec[i]].manip->numJoints() != ik_limb_parameters[i].ik_optional_weight_vector.length())
220  is_ik_limb_parameter_valid_length = false;
221  }
222  if (is_ik_limb_parameter_valid_length) {
223  for (size_t i = 0; i < ee_vec.size(); i++) {
224  IKparam& param = ikp[ee_vec[i]];
225  const OpenHRP::AutoBalancerService::IKLimbParameters& ilp = ik_limb_parameters[i];
226  std::vector<double> ov;
227  ov.resize(param.manip->numJoints());
228  for (size_t j = 0; j < param.manip->numJoints(); j++) {
229  ov[j] = ilp.ik_optional_weight_vector[j];
230  }
231  param.manip->setOptionalWeightVector(ov);
232  param.manip->setSRGain(ilp.sr_gain);
233  param.avoid_gain = ilp.avoid_gain;
234  param.reference_gain = ilp.reference_gain;
235  param.manip->setManipulabilityLimit(ilp.manipulability_limit);
236  }
237  } else {
238  std::cerr << "[" << print_str << "] ik_optional_weight_vector invalid length! Cannot be set. (input = [";
239  for (size_t i = 0; i < ee_vec.size(); i++) {
240  std::cerr << ik_limb_parameters[i].ik_optional_weight_vector.length() << ", ";
241  }
242  std::cerr << "], desired = [";
243  for (size_t i = 0; i < ee_vec.size(); i++) {
244  std::cerr << ikp[ee_vec[i]].manip->numJoints() << ", ";
245  }
246  std::cerr << "])" << std::endl;
247  }
248  }
249  if (is_ik_limb_parameter_valid_length) {
250  printIKparam(ee_vec);
251  }
252  };
253  // Avoid limb stretch
254  void limbStretchAvoidanceControl (const std::vector<hrp::Vector3>& target_p, const std::vector<std::string>& target_name)
255  {
256  m_robot->calcForwardKinematics();
257  double tmp_d_root_height = 0.0, prev_d_root_height = d_root_height;
258  if (use_limb_stretch_avoidance) {
259  for (size_t i = 0; i < target_p.size(); i++) {
260  // Check whether inside limb length limitation
261  hrp::Link* parent_link = m_robot->link(ikp[target_name[i]].parent_name);
262  hrp::Vector3 rel_target_p = target_p[i] - parent_link->p; // position from parent to target link (world frame)
263  double limb_length_limitation = ikp[target_name[i]].max_limb_length - ikp[target_name[i]].limb_length_margin;
264  double tmp = limb_length_limitation * limb_length_limitation - rel_target_p(0) * rel_target_p(0) - rel_target_p(1) * rel_target_p(1);
265  if (rel_target_p.norm() > limb_length_limitation && tmp >= 0) {
266  tmp_d_root_height = std::min(tmp_d_root_height, rel_target_p(2) + std::sqrt(tmp));
267  }
268  }
269  // Change root link height depending on limb length
270  d_root_height = tmp_d_root_height == 0.0 ? (- 1/limb_stretch_avoidance_time_const * d_root_height * m_dt + d_root_height) : tmp_d_root_height;
271  } else {
272  d_root_height = - 1/limb_stretch_avoidance_time_const * d_root_height * m_dt + d_root_height;
273  }
274  d_root_height = vlimit(d_root_height, prev_d_root_height + limb_stretch_avoidance_vlimit[0], prev_d_root_height + limb_stretch_avoidance_vlimit[1]);
275  m_robot->rootLink()->p(2) += d_root_height;
276  };
277  double vlimit(const double value, const double llimit_value, const double ulimit_value)
278  {
279  if (value > ulimit_value) {
280  return ulimit_value;
281  } else if (value < llimit_value) {
282  return llimit_value;
283  }
284  return value;
285  };
286  // Set parameter
287  void printParam () const
288  {
289  std::cerr << "[" << print_str << "] move_base_gain = " << move_base_gain << std::endl;
290  std::cerr << "[" << print_str << "] pos_ik_thre = " << pos_ik_thre << "[m], rot_ik_thre = " << rot_ik_thre << "[rad]" << std::endl;
291  };
292  // Set IKparam
293  void printIKparam (std::vector<std::string>& ee_vec)
294  {
295  std::cerr << "[" << print_str << "] ik_optional_weight_vectors = ";
296  for (size_t i = 0; i < ee_vec.size(); i++) {
297  IKparam& param = ikp[ee_vec[i]];
298  std::vector<double> ov;
299  ov.resize(param.manip->numJoints());
300  param.manip->getOptionalWeightVector(ov);
301  std::cerr << "[";
302  for (size_t j = 0; j < param.manip->numJoints(); j++) {
303  std::cerr << ov[j] << " ";
304  }
305  std::cerr << "]";
306  }
307  std::cerr << std::endl;
308  std::cerr << "[" << print_str << "] sr_gains = [";
309  for (size_t i = 0; i < ee_vec.size(); i++) {
310  std::cerr << ikp[ee_vec[i]].manip->getSRGain() << ", ";
311  }
312  std::cerr << "]" << std::endl;
313  std::cerr << "[" << print_str << "] avoid_gains = [";
314  for (size_t i = 0; i < ee_vec.size(); i++) {
315  std::cerr << ikp[ee_vec[i]].avoid_gain << ", ";
316  }
317  std::cerr << "]" << std::endl;
318  std::cerr << "[" << print_str << "] reference_gains = [";
319  for (size_t i = 0; i < ee_vec.size(); i++) {
320  std::cerr << ikp[ee_vec[i]].reference_gain << ", ";
321  }
322  std::cerr << "]" << std::endl;
323  std::cerr << "[" << print_str << "] manipulability_limits = [";
324  for (size_t i = 0; i < ee_vec.size(); i++) {
325  std::cerr << ikp[ee_vec[i]].manip->getManipulabilityLimit() << ", ";
326  }
327  std::cerr << "]" << std::endl;
328  };
329  hrp::Vector3 getEndEffectorPos(const std::string& limb_name){
330  return ikp[limb_name].target_link->p + ikp[limb_name].target_link->R * ikp[limb_name].localPos;
331  }
332  hrp::Matrix33 getEndEffectorRot(const std::string& limb_name){
333  return ikp[limb_name].target_link->R * ikp[limb_name].localR;
334  }
335 };
336 
337 #endif // SimpleFullbodyInverseKinematicsSolver_H
hrp::Vector3 getEndEffectorPos(const std::string &limb_name)
void getIKParam(std::vector< std::string > &ee_vec, _CORBA_Unbounded_Sequence< OpenHRP::AutoBalancerService::IKLimbParameters > &ik_limb_parameters)
void difference_rotation(hrp::Vector3 &ret_dif_rot, const hrp::Matrix33 &self_rot, const hrp::Matrix33 &target_rot)
Definition: RatsMatrix.cpp:40
double vlimit(const double value, const double llimit_value, const double ulimit_value)
bool solveLimbIK(IKparam &param, const std::string &limb_name, const double ratio_for_vel, const bool is_transition)
png_uint_32 i
Eigen::VectorXd dvector
Eigen::Vector3d Vector3
Eigen::Matrix3d Matrix33
#define min(a, b)
void limbStretchAvoidanceControl(const std::vector< hrp::Vector3 > &target_p, const std::vector< std::string > &target_name)
hrp::Matrix33 getEndEffectorRot(const std::string &limb_name)
def j(str, encoding="cp932")
void solveFullbodyIK(const hrp::Vector3 &_dif_cog, const bool is_transition)
SimpleFullbodyInverseKinematicsSolver(hrp::BodyPtr &_robot, const std::string &_print_str, const double _dt)
#define M_PI
void checkIKTracking(IKparam &param, const std::string &limb_name, const bool is_transition)
typedef int
void initializeInterlockingJoints(std::vector< std::pair< hrp::Link *, hrp::Link * > > &interlocking_joints)
void setIKParam(std::vector< std::string > &ee_vec, const _CORBA_Unbounded_Sequence< OpenHRP::AutoBalancerService::IKLimbParameters > &ik_limb_parameters)
void printIKparam(std::vector< std::string > &ee_vec)


hrpsys
Author(s): AIST, Fumio Kanehiro
autogenerated on Thu May 6 2021 02:41:51