00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "tree_kinematics/treeiksolverpos_online.hpp"
00026 #include <algorithm>
00027
00028 namespace KDL {
00029
00030 TreeIkSolverPos_Online::TreeIkSolverPos_Online(const double& nr_of_jnts,
00031 const std::vector<std::string>& endpoints,
00032 TreeFkSolverPos& fksolver,
00033 TreeIkSolverVel& iksolver,
00034 const JntArray& q_min,
00035 const JntArray& q_max,
00036 const JntArray& q_dot_min,
00037 const JntArray& q_dot_max,
00038 const double x_dot_trans_max,
00039 const double x_dot_rot_max,
00040 const double x_dot_trans_min,
00041 const double x_dot_rot_min,
00042 const double low_pass_factor,
00043 const unsigned int maxiter,
00044 const double eps) :
00045 fksolver_(fksolver),
00046 iksolver_(iksolver),
00047 q_min_(nr_of_jnts),
00048 q_max_(nr_of_jnts),
00049 q_dot_min_(nr_of_jnts),
00050 q_dot_max_(nr_of_jnts),
00051 maxiter_(maxiter),
00052 eps_(eps),
00053 q_dot_(nr_of_jnts),
00054 q_dot_old_(nr_of_jnts),
00055 q_dot_new_(nr_of_jnts),
00056 q_out_old_(nr_of_jnts)
00057 {
00058 assert(q_min.rows() == nr_of_jnts);
00059 assert(q_max.rows() == nr_of_jnts);
00060 assert(q_dot_max.rows() == nr_of_jnts);
00061 assert(q_out_old_.rows() == nr_of_jnts);
00062
00063 SetToZero(q_out_old_);
00064 q_min_ = q_min;
00065 q_max_ = q_max;
00066 q_dot_min_ = q_dot_min;
00067 q_dot_max_ = q_dot_max;
00068 x_dot_trans_max_ = x_dot_trans_max;
00069 x_dot_rot_max_ = x_dot_rot_max;
00070 x_dot_trans_min_ = x_dot_trans_min;
00071 x_dot_rot_min_ = x_dot_rot_min;
00072 low_pass_factor_ = low_pass_factor;
00073 low_pass_adj_factor_ = 0.0;
00074 nr_of_still_endeffectors_ = 0;
00075 small_task_space_movement_ = false;
00076
00077 for (size_t i = 0; i < endpoints.size(); i++)
00078 {
00079
00080 frames_.insert(Frames::value_type(endpoints[i], Frame::Identity()));
00081 delta_twists_.insert(Twists::value_type(endpoints[i], Twist::Zero()));
00082 old_twists_.insert(Twists::value_type(endpoints[i], Twist::Zero()));
00083
00084 frames_pos_lim_.insert(Frames::value_type(endpoints[i], Frame::Identity()));
00085 frames_vel_lim_.insert(Frames::value_type(endpoints[i], Frame::Identity()));
00086 p_in_old_.insert(Frames::value_type(endpoints[i], Frame::Identity()));
00087
00088 }
00089
00090 }
00091
00092
00093 TreeIkSolverPos_Online::~TreeIkSolverPos_Online()
00094 {}
00095
00096
00097 double TreeIkSolverPos_Online::CartToJnt(const JntArray& q_in, const Frames& p_in, JntArray& q_out)
00098 {
00099 assert(q_out.rows() == q_in.rows());
00100 assert(q_dot_.rows() == q_out.rows());
00101
00102 q_out = q_in;
00103
00104
00105 for(Frames::const_iterator f_des_it=p_in.begin();f_des_it!=p_in.end();++f_des_it)
00106 if(frames_.find(f_des_it->first)==frames_.end())
00107 return -2;
00108
00109 for (Frames::const_iterator f_des_it=p_in.begin();f_des_it!=p_in.end();++f_des_it)
00110 {
00111
00112 Frames::iterator f_it = frames_.find(f_des_it->first);
00113 Twists::iterator delta_twists_it = delta_twists_.find(f_des_it->first);
00114
00115 fksolver_.JntToCart(q_out, f_it->second, f_it->first);
00116 twist_ = diff(f_it->second, f_des_it->second);
00117
00118
00119
00120 enforceCartVelLimits();
00121
00122 delta_twists_it->second = twist_;
00123 }
00124
00125 double res = iksolver_.CartToJnt(q_out, delta_twists_, q_dot_);
00126
00127
00128 enforceJointVelLimits();
00129
00130
00131 Add(q_out, q_dot_, q_out);
00132
00133
00134 for (unsigned int j = 0; j < q_min_.rows(); j++)
00135 {
00136 if (q_out(j) < q_min_(j))
00137 q_out(j) = q_min_(j);
00138 else if (q_out(j) > q_max_(j))
00139 q_out(j) = q_max_(j);
00140 }
00141
00142 return res;
00143 }
00144
00145
00146 double TreeIkSolverPos_Online::CartToJnt_it(const JntArray& q_in, const Frames& p_in, JntArray& q_out)
00147 {
00148 assert(q_out.rows() == q_in.rows());
00149 assert(q_out_old_.rows() == q_in.rows());
00150 assert(q_dot_.rows() == q_in.rows());
00151 assert(q_dot_old_.rows() == q_in.rows());
00152 assert(q_dot_new_.rows() == q_in.rows());
00153
00154
00155
00156 q_out = q_in;
00157 SetToZero(q_dot_);
00158 SetToZero(q_dot_old_);
00159 SetToZero(q_dot_new_);
00160 twist_ = Twist::Zero();
00161
00162
00163 unsigned int nr_of_endeffectors = 0;
00164 nr_of_still_endeffectors_ = 0;
00165 low_pass_adj_factor_ = 0.0;
00166
00167 for(Frames::const_iterator f_des_it=p_in.begin();f_des_it!=p_in.end();++f_des_it)
00168 {
00169 if(frames_.find(f_des_it->first)==frames_.end())
00170 return -2;
00171 else
00172 {
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183 Frames::iterator f_old_it = p_in_old_.find(f_des_it->first);
00184 Frames::iterator f_des_pos_l_it = frames_pos_lim_.find(f_des_it->first);
00185 twist_ = diff(f_old_it->second, f_des_it->second);
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203 f_des_pos_l_it->second.p = f_des_it->second.p;
00204 f_des_pos_l_it->second.M = f_des_it->second.M;
00205
00206 Frames::iterator f_des_vel_l_it = frames_vel_lim_.find(f_des_it->first);
00207 fksolver_.JntToCart(q_in, f_des_vel_l_it->second, f_des_it->first);
00208 twist_ = diff(f_des_vel_l_it->second, f_des_pos_l_it->second);
00209
00210
00211
00212 f_des_vel_l_it->second = addDelta(f_des_vel_l_it->second, twist_);
00213 nr_of_endeffectors++;
00214 }
00215 }
00216 if(nr_of_still_endeffectors_ == nr_of_endeffectors)
00217 {
00218 small_task_space_movement_ = true;
00219
00220 }
00221 else
00222 small_task_space_movement_ = false;
00223
00224 unsigned int k=0;
00225 double res = 0.0;
00226 while(++k <= maxiter_)
00227 {
00228
00229 for (Frames::const_iterator f_des_it=frames_vel_lim_.begin(); f_des_it!=frames_vel_lim_.end(); ++f_des_it)
00230 {
00231
00232 Frames::iterator f_it = frames_.find(f_des_it->first);
00233 Twists::iterator delta_twists_it = delta_twists_.find(f_des_it->first);
00234 Twists::iterator old_twists_it = old_twists_.find(f_des_it->first);
00235 Frames::iterator f_0_it = frames_vel_lim_.find(f_des_it->first);
00236
00237 fksolver_.JntToCart(q_out, f_it->second, f_it->first);
00238
00239
00240
00241 delta_twists_it->second = diff(f_it->second, f_des_it->second);
00242
00243
00244 old_twists_it->second = diff(f_0_it->second, f_it->second);
00245
00246 enforceCartVelLimits_it(old_twists_it->second, delta_twists_it->second);
00247
00248
00249 }
00250
00251 res = iksolver_.CartToJnt(q_out, delta_twists_, q_dot_);
00252
00253 if (res < eps_)
00254 {
00255 break;
00256
00257 }
00258
00259
00260
00261
00262
00263 Subtract(q_out, q_in, q_dot_old_);
00264
00265 Add(q_dot_old_, q_dot_, q_dot_);
00266
00267 enforceJointVelLimits();
00268
00269 Subtract(q_dot_, q_dot_old_, q_dot_);
00270
00271
00272 Add(q_out, q_dot_, q_out);
00273
00274
00275 for (unsigned int j = 0; j < q_min_.rows(); ++j)
00276 {
00277 if (q_out(j) < q_min_(j))
00278 q_out(j) = q_min_(j);
00279 else if (q_out(j) > q_max_(j))
00280 q_out(j) = q_max_(j);
00281 }
00282 }
00283
00284 Subtract(q_out, q_in, q_dot_);
00285
00286
00287 Add(q_in, q_dot_, q_out);
00288 filter(q_dot_, q_out, q_out_old_);
00289
00290
00291
00292 q_out_old_ = q_out;
00293 p_in_old_ = p_in;
00294
00295
00296 if (k <= maxiter_)
00297 return res;
00298 else
00299 return -3;
00300 }
00301
00302
00303 bool TreeIkSolverPos_Online::enforceCartVelLimits()
00304 {
00305
00306 double rel_os_trans = 0.0;
00307 double rel_os_rot = 0.0;
00308
00309 double rel_os_max = 0.0;
00310 bool max_exceeded = false;
00311 double x_dot_trans, x_dot_rot;
00312 x_dot_trans = sqrt( pow(twist_.vel.x(), 2) + pow(twist_.vel.y(), 2) + pow(twist_.vel.z(), 2));
00313 x_dot_rot = sqrt( pow(twist_.rot.x(), 2) + pow(twist_.rot.y(), 2) + pow(twist_.rot.z(), 2));
00314
00315 if (x_dot_trans <= x_dot_trans_min_ && x_dot_rot <= x_dot_rot_min_ && x_dot_trans_min_ != 0.0 && x_dot_rot_min_ != 0.0)
00316 {
00317 double trans_low_pass_factor = 0.1 + 0.9 * (x_dot_trans / x_dot_trans_min_);
00318 double rot_low_pass_factor = 0.1 + 0.9 * (x_dot_rot / x_dot_rot_min_);
00319
00320 if(low_pass_adj_factor_ < max(trans_low_pass_factor, rot_low_pass_factor))
00321 low_pass_adj_factor_ = max(trans_low_pass_factor, rot_low_pass_factor);
00322
00323
00324 nr_of_still_endeffectors_++;
00325 }
00326
00327 if ( x_dot_trans > x_dot_trans_max_ || x_dot_rot > x_dot_rot_max_ )
00328 {
00329 rel_os_trans = (x_dot_trans - x_dot_trans_max_) / x_dot_trans_max_;
00330 rel_os_rot = (x_dot_rot - x_dot_rot_max_) / x_dot_rot_max_;
00331
00332 if ( rel_os_trans >= rel_os_rot )
00333 {
00334 max_exceeded = true;
00335 rel_os_max = rel_os_trans;
00336 }
00337 else if ( rel_os_trans < rel_os_rot )
00338 {
00339 max_exceeded = true;
00340 rel_os_max = rel_os_rot;
00341 }
00342 }
00343
00344 if ( max_exceeded == true )
00345 {
00346 twist_.vel = twist_.vel * ( 1.0 / ( 1.0 + rel_os_max ) );
00347 twist_.rot = twist_.rot * ( 1.0 / ( 1.0 + rel_os_max ) );
00348 return true;
00349 }
00350 else
00351 return false;
00352 }
00353
00354
00355 bool TreeIkSolverPos_Online::enforceJointVelLimits()
00356 {
00357
00358
00359
00360
00361
00362 double rel_os = 0.0;
00363
00364 double rel_os_max = 0.0;
00365 bool max_exceeded = false;
00366
00367 for (unsigned int i = 0; i < q_dot_.rows(); ++i)
00368 {
00369 if ( q_dot_(i) > q_dot_max_(i) && q_dot_max_(i) != 0.0)
00370 {
00371 max_exceeded = true;
00372 rel_os = (q_dot_(i) - q_dot_max_(i)) / q_dot_max_(i);
00373 if ( rel_os > rel_os_max )
00374 {
00375 rel_os_max = rel_os;
00376 }
00377 }
00378 else if ( q_dot_(i) < -q_dot_max_(i) && q_dot_max_(i) != 0.0)
00379 {
00380 max_exceeded = true;
00381 rel_os = (-q_dot_(i) - q_dot_max_(i)) / q_dot_max_(i);
00382 if ( rel_os > rel_os_max)
00383 {
00384 rel_os_max = rel_os;
00385 }
00386 }
00387 else if (q_dot_max_(i) == 0.0)
00388 q_dot_(i) = 0.0;
00389 }
00390
00391
00392 if ( max_exceeded == true )
00393 {
00394 Multiply(q_dot_, ( 1.0 / ( 1.0 + rel_os_max ) ), q_dot_);
00395 return true;
00396 }
00397 else
00398 return false;
00399 }
00400
00401
00402 void TreeIkSolverPos_Online::enforceCartVelLimits_it(Twist& old_twist, Twist& current_twist)
00403 {
00404 bool max_exceeded = false;
00405 double x_dot_trans, x_dot_rot;
00406
00407 twist_ = old_twist + current_twist;
00408
00409 x_dot_trans = sqrt( pow(twist_.vel.x(), 2) + pow(twist_.vel.y(), 2) + pow(twist_.vel.z(), 2));
00410 x_dot_rot = sqrt( pow(twist_.rot.x(), 2) + pow(twist_.rot.y(), 2) + pow(twist_.rot.z(), 2));
00411
00412 if ( x_dot_trans > x_dot_trans_max_ || x_dot_rot > x_dot_rot_max_ )
00413 {
00414 if ( x_dot_trans > x_dot_rot )
00415 {
00416 twist_.vel = twist_.vel * ( x_dot_trans_max_ / x_dot_trans );
00417 twist_.rot = twist_.rot * ( x_dot_trans_max_ / x_dot_trans );
00418 max_exceeded = true;
00419 }
00420 else if ( x_dot_rot > x_dot_trans )
00421 {
00422 twist_.vel = twist_.vel * ( x_dot_rot_max_ / x_dot_rot );
00423 twist_.rot = twist_.rot * ( x_dot_rot_max_ / x_dot_rot );
00424 max_exceeded = true;
00425 }
00426 }
00427
00428 if ( max_exceeded == true )
00429 current_twist = twist_ - old_twist;
00430
00431
00432 }
00433
00434
00435 void TreeIkSolverPos_Online::enforceJointVelLimits_it(JntArray& q_dot_old, JntArray& q_dot_current)
00436 {
00437
00438
00439
00440 double rel_os = 0.0;
00441 double rel_os_max = 0.0;
00442 bool max_exceeded = false;
00443
00444
00445 Add(q_dot_old, q_dot_current, q_dot_new_);
00446
00447 for (unsigned int i = 0; i < q_dot_new_.rows(); ++i)
00448 {
00449 if ( q_dot_new_(i) > q_dot_max_(i) )
00450 {
00451 max_exceeded = true;
00452 rel_os = (q_dot_new_(i) - q_dot_max_(i)) / q_dot_max_(i);
00453 if ( rel_os > rel_os_max )
00454 {
00455 rel_os_max = rel_os;
00456 }
00457 }
00458 else if ( q_dot_new_(i) < -q_dot_max_(i) )
00459 {
00460 max_exceeded = true;
00461 rel_os = (-q_dot_new_(i) - q_dot_max_(i)) / q_dot_max_(i);
00462 if ( rel_os > rel_os_max)
00463 {
00464 rel_os_max = rel_os;
00465 }
00466 }
00467 }
00468
00469
00470 if ( max_exceeded == true )
00471 {
00472 Multiply(q_dot_new_, ( 1.0 / ( 1.0 + rel_os_max ) ), q_dot_new_);
00473
00474 Subtract(q_dot_new_, q_dot_old, q_dot_current);
00475 }
00476 }
00477
00478
00479 void TreeIkSolverPos_Online::filter(JntArray& q_dot, JntArray& q_out, JntArray& q_out_old)
00480 {
00481
00482
00483
00484 double low_pass_factor = 1.0;
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507 if(small_task_space_movement_)
00508 {
00509 low_pass_factor = low_pass_adj_factor_ * low_pass_factor_;
00510 small_task_space_movement_ = false;
00511 }
00512 else
00513 low_pass_factor = low_pass_factor_;
00514
00515 for (unsigned int i = 0; i < q_dot.rows(); ++i)
00516 {
00517 q_out(i) = low_pass_factor * q_out(i) + (1.0 - low_pass_factor) * q_out_old(i);
00518 }
00519 }
00520
00521 }
00522