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
00026
00027
00028
00029
00030
00031
00032
00033
00034
00038 #include <LinearMath/btMatrix3x3.h>
00039 #include <LinearMath/btVector3.h>
00040 #include <tf_conversions/tf_eigen.h>
00041 #include "motion_adaption/motion_adaption.h"
00042
00043
00044 bool MotionAdaption::adaptTransforms()
00045 {
00046 if(adaptTorso())
00047 {
00048 if(adaptHead())
00049 {
00050 if(scaleUserHandsAndElbows())
00051 {
00052 if(adaptShoulders())
00053 {
00054 if(adaptElbows())
00055 {
00056 if(!adaptHands())
00057 return false;
00058 }
00059 else
00060 return false;
00061 }
00062 else
00063 return false;
00064 }
00065 else
00066 return false;
00067 }
00068 else
00069 return false;
00070 }
00071 else
00072 return false;
00073
00074 return true;
00075 }
00076
00077
00078 bool MotionAdaption::adaptTorso()
00079 {
00080
00081
00082 tf_torso_goal_.setIdentity();
00083
00084 internal_tf.setTransform(tf::StampedTransform(tf_torso_goal_, calc_time, "/ref_frame", "/torso_adapted"));
00085
00086 return true;
00087 }
00088
00089
00090 bool MotionAdaption::adaptHead()
00091 {
00092 try
00093 {
00094 tf_listener_.waitForTransform("/fixed_ref_frame", robot_head_str_, ros::Time(0), ros::Duration(wait_for_tf_));
00095 tf_listener_.lookupTransform("/fixed_ref_frame", robot_head_str_, ros::Time(0), tf_robot_torso_head_);
00096 }
00097 catch (tf::TransformException const &ex)
00098 {
00099 ROS_DEBUG("%s",ex.what());
00100 ROS_WARN("(Step 3.1) Couldn't get the transformation from the fixed_ref_frame to head_goal_frame.");
00101 ROS_WARN("No further processing will be done!");
00102 return false;
00103 }
00104 tf_head_goal_.setIdentity();
00105 tf_head_goal_.setOrigin(tf_robot_torso_head_.getOrigin());
00106
00107 quat_ = tf_usr_head_.getRotation();
00108
00109
00110 tf_head_goal_.setRotation(quat_);
00111
00112
00113 internal_tf.setTransform(tf::StampedTransform(tf_head_goal_, calc_time,"/ref_frame", "/head_adapted"));
00114
00115 return true;
00116 }
00117
00118
00119 bool MotionAdaption::scaleUserHandsAndElbows()
00120 {
00121 user_shoulder_width_ = tf_usr_r_shoulder_.getOrigin().x() + (- tf_usr_l_shoulder_.getOrigin().x());
00122 user_shoulder_height_ = (tf_usr_r_shoulder_.getOrigin().y() + tf_usr_l_shoulder_.getOrigin().y()) / 2.0;
00123 user_upper_arm_length_ = tf_usr_r_shoulder_elbow_.getOrigin().x();
00124 user_arm_length_ = tf_usr_r_shoulder_elbow_.getOrigin().x() + tf_usr_r_elbow_hand_.getOrigin().x();
00125
00126 if (user_shoulder_width_ > 0.0 && user_shoulder_height_ > 0.0 && user_arm_length_ > 0.0)
00127 {
00128 x_norm_ = tf_usr_r_hand_.getOrigin().x() / (user_arm_length_ + 0.5 * user_shoulder_width_);
00129 y_norm_ = tf_usr_r_hand_.getOrigin().y() / (user_arm_length_ + user_shoulder_height_);
00130 z_norm_ = tf_usr_r_hand_.getOrigin().z() / user_arm_length_;
00131 x_adapt_ = x_norm_ * ( robot_arm_length_ + 0.5 * robot_shoulder_width_);
00132 y_adapt_ = y_norm_ * ( robot_arm_length_ + robot_shoulder_heigth_);
00133 z_adapt_ = z_norm_ * robot_arm_length_;
00134 tf_r_hand_scaled_.setOrigin(tf::Vector3(x_adapt_, y_adapt_, z_adapt_));
00135
00136 x_norm_ = tf_usr_l_hand_.getOrigin().x() / (user_arm_length_ + 0.5 * user_shoulder_width_);
00137 y_norm_ = tf_usr_l_hand_.getOrigin().y() / (user_arm_length_ + user_shoulder_height_);
00138 z_norm_ = tf_usr_l_hand_.getOrigin().z() / user_arm_length_;
00139 x_adapt_ = x_norm_ * ( robot_arm_length_ + 0.5 * robot_shoulder_width_);
00140 y_adapt_ = y_norm_ * ( robot_arm_length_ + robot_shoulder_heigth_);
00141 z_adapt_ = z_norm_ * robot_arm_length_;
00142 tf_l_hand_scaled_.setOrigin(tf::Vector3(x_adapt_, y_adapt_, z_adapt_));
00143
00144 x_norm_ = tf_usr_r_elbow_.getOrigin().x() / (user_upper_arm_length_ + 0.5 * user_shoulder_width_);
00145 y_norm_ = tf_usr_r_elbow_.getOrigin().y() / (user_upper_arm_length_ + user_shoulder_height_);
00146 z_norm_ = tf_usr_r_elbow_.getOrigin().z() / user_upper_arm_length_;
00147 x_adapt_ = x_norm_ * ( robot_upper_arm_length_ + 0.5 * robot_shoulder_width_);
00148 y_adapt_ = y_norm_ * ( robot_upper_arm_length_ + robot_shoulder_heigth_);
00149 z_adapt_ = z_norm_ * robot_upper_arm_length_;
00150 tf_r_elbow_scaled_.setOrigin(tf::Vector3(x_adapt_, y_adapt_, z_adapt_));
00151
00152 x_norm_ = tf_usr_l_elbow_.getOrigin().x() / (user_upper_arm_length_ + 0.5 * user_shoulder_width_);
00153 y_norm_ = tf_usr_l_elbow_.getOrigin().y() / (user_upper_arm_length_ + user_shoulder_height_);
00154 z_norm_ = tf_usr_l_elbow_.getOrigin().z() / user_upper_arm_length_;
00155 x_adapt_ = x_norm_ * ( robot_upper_arm_length_ + 0.5 * robot_shoulder_width_);
00156 y_adapt_ = y_norm_ * ( robot_upper_arm_length_ + robot_shoulder_heigth_);
00157 z_adapt_ = z_norm_ * robot_upper_arm_length_;
00158 tf_l_elbow_scaled_.setOrigin(tf::Vector3(x_adapt_, y_adapt_, z_adapt_));
00159
00160
00161 internal_tf.setTransform(tf::StampedTransform(tf_r_elbow_scaled_, calc_time, "/ref_frame", "/r_elbow_scaled"));
00162
00163 internal_tf.setTransform(tf::StampedTransform(tf_r_hand_scaled_, calc_time, "/ref_frame", "/r_hand_scaled"));
00164
00165 internal_tf.setTransform(tf::StampedTransform(tf_l_elbow_scaled_, calc_time, "/ref_frame", "/l_elbow_scaled"));
00166
00167 internal_tf.setTransform(tf::StampedTransform(tf_l_hand_scaled_, calc_time, "/ref_frame", "/l_hand_scaled"));
00168 }
00169 else
00170 {
00171 ROS_WARN("(Step 3.3) User's body proportions are not valid.");
00172 ROS_WARN("No further processing will be done!");
00173 return false;
00174 }
00175 return true;
00176 }
00177
00178
00179 bool MotionAdaption::adaptShoulders()
00180 {
00181
00182 try
00183 {
00184 tf_listener_.waitForTransform("/fixed_ref_frame", robot_r_shoulder_str_, ros::Time(0),
00185 ros::Duration(wait_for_tf_));
00186 tf_listener_.lookupTransform("/fixed_ref_frame", robot_r_shoulder_str_, ros::Time(0),
00187 tf_robot_torso_r_shoulder_);
00188 tf_listener_.waitForTransform("/fixed_ref_frame", robot_l_shoulder_str_, ros::Time(0),
00189 ros::Duration(wait_for_tf_));
00190 tf_listener_.lookupTransform("/fixed_ref_frame", robot_l_shoulder_str_, ros::Time(0),
00191 tf_robot_torso_l_shoulder_);
00192 tf_listener_.waitForTransform(robot_r_shoulder_str_, robot_l_shoulder_str_, ros::Time(0),
00193 ros::Duration(wait_for_tf_));
00194 tf_listener_.lookupTransform(robot_r_shoulder_str_, robot_l_shoulder_str_, ros::Time(0),
00195 tf_robot_r_shoulder_l_shoulder_);
00196 tf_listener_.waitForTransform(robot_r_shoulder_str_, robot_r_elbow_str_, ros::Time(0), ros::Duration(wait_for_tf_));
00197 tf_listener_.lookupTransform(robot_r_shoulder_str_, robot_r_elbow_str_, ros::Time(0), tf_robot_r_shoulder_r_elbow_);
00198 tf_listener_.waitForTransform(robot_r_elbow_str_, robot_r_hand_str_, ros::Time(0), ros::Duration(wait_for_tf_));
00199 tf_listener_.lookupTransform(robot_r_elbow_str_, robot_r_hand_str_, ros::Time(0), tf_robot_r_elbow_r_hand_);
00200 }
00201 catch (tf::TransformException const &ex)
00202 {
00203 ROS_DEBUG("%s",ex.what());
00204 ROS_WARN("(Step 3.4.1) Couldn't get one or more transformations of the robot to calculate body measurements.");
00205 ROS_WARN("No further processing will be done!");
00206 return false;
00207 }
00208 robot_shoulder_heigth_ = sqrt(pow(tf_robot_torso_r_shoulder_.getOrigin()[
00209 tf_robot_torso_r_shoulder_.getOrigin().absolute().maxAxis()], 2));
00210 robot_shoulder_width_ = sqrt(pow(tf_robot_r_shoulder_l_shoulder_.getOrigin()[
00211 tf_robot_r_shoulder_l_shoulder_.getOrigin().absolute().maxAxis()], 2));
00212 robot_upper_arm_length_ = sqrt(tf_robot_r_shoulder_r_elbow_.getOrigin().length2());
00213 robot_lower_arm_length_ = sqrt(tf_robot_r_elbow_r_hand_.getOrigin().length2());
00214 robot_arm_length_ = robot_upper_arm_length_ + robot_lower_arm_length_;
00215 ROS_DEBUG_THROTTLE(1.0, "robot_shoulder_heigth = %f, robot_shoulder_width = %f, robot_arm_length = %f",
00216 robot_shoulder_heigth_, robot_shoulder_width_, robot_arm_length_);
00217
00218 tf_r_shoulder_scaled_.setOrigin(tf_robot_torso_r_shoulder_.getOrigin());
00219 tf_l_shoulder_scaled_.setOrigin(tf_robot_torso_l_shoulder_.getOrigin());
00220
00221 internal_tf.setTransform(tf::StampedTransform(tf_r_shoulder_scaled_, calc_time,"/ref_frame", "/r_robot_shoulder"));
00222
00223 internal_tf.setTransform(tf::StampedTransform(tf_l_shoulder_scaled_, calc_time,"/ref_frame", "/l_robot_shoulder"));
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236 try
00237 {
00238
00239 internal_tf.lookupTransform("/r_robot_shoulder", "/r_elbow_scaled", ros::Time(0), tf_r_shoulder_elbow_);
00240
00241 internal_tf.lookupTransform("/r_robot_shoulder", "/r_hand_scaled", ros::Time(0), tf_r_shoulder_hand_);
00242
00243 internal_tf.lookupTransform("/l_robot_shoulder", "/l_elbow_scaled", ros::Time(0), tf_l_shoulder_elbow_);
00244
00245 internal_tf.lookupTransform("/l_robot_shoulder", "/l_hand_scaled", ros::Time(0), tf_l_shoulder_hand_);
00246 }
00247 catch (tf::TransformException const &ex)
00248 {
00249 ROS_DEBUG("%s",ex.what());
00250 ROS_WARN("(Step 3.4.2) Couldn't get one or more transformations from the shoulders to the hands and elbows.");
00251 ROS_WARN("No further processing will be done!");
00252 return false;
00253 }
00254
00255
00256 vec_shoulder_elbow_ = tf_r_shoulder_elbow_.getOrigin();
00257 vec_shoulder_hand_ = tf_r_shoulder_hand_.getOrigin();
00258 if(vec_shoulder_hand_.angle(vec_shoulder_elbow_) < 0.15708 && !vec_r_elbow_hand_valid_.isZero())
00259 {
00260 ROS_DEBUG_THROTTLE(0.1, "valid right hand vector is used (angle between vectors: %f).",
00261 vec_shoulder_hand_.angle(vec_shoulder_elbow_));
00262 vec_shoulder_hand_ = vec_shoulder_elbow_ + vec_r_elbow_hand_valid_;
00263 r_elbow_extended_ = true;
00264 }
00265 else
00266 {
00267 vec_r_elbow_hand_valid_ = vec_shoulder_hand_ - vec_shoulder_elbow_;
00268 r_elbow_extended_ = false;
00269 }
00270 vec_normal_ = vec_shoulder_hand_.cross(vec_shoulder_elbow_);
00271 vec_helper_ = vec_normal_.cross(vec_shoulder_hand_);
00272 vec_shoulder_hand_.normalize();
00273 vec_helper_.normalize();
00274 vec_normal_.normalize();
00275 mat_orientation_.setValue(vec_shoulder_hand_.x(), vec_helper_.x(), vec_normal_.x(),
00276 vec_shoulder_hand_.y(), vec_helper_.y(), vec_normal_.y(),
00277 vec_shoulder_hand_.z(), vec_helper_.z(), vec_normal_.z());
00278 tf_r_shoulder_goal_.setBasis(mat_orientation_);
00279
00280 internal_tf.setTransform(tf::StampedTransform(tf_r_shoulder_goal_, calc_time, "/r_robot_shoulder", "/r_shoulder_adapted"));
00281
00282
00283 vec_shoulder_elbow_ = tf_l_shoulder_elbow_.getOrigin();
00284 vec_shoulder_hand_ = tf_l_shoulder_hand_.getOrigin();
00285 if(vec_shoulder_hand_.angle(vec_shoulder_elbow_) < 0.15708 && !vec_l_elbow_hand_valid_.isZero())
00286 {
00287 ROS_DEBUG_THROTTLE(0.1, "valid right hand vector is used (angle between vectors: %f).",
00288 vec_shoulder_hand_.angle(vec_shoulder_elbow_));
00289 vec_shoulder_hand_ = vec_shoulder_elbow_ + vec_l_elbow_hand_valid_;
00290 l_elbow_extended_ = true;
00291 }
00292 else
00293 {
00294 vec_l_elbow_hand_valid_ = vec_shoulder_hand_ - vec_shoulder_elbow_;
00295 l_elbow_extended_ = false;
00296 }
00297 vec_normal_ = vec_shoulder_hand_.cross(vec_shoulder_elbow_);
00298 vec_helper_ = vec_normal_.cross(vec_shoulder_hand_);
00299 vec_shoulder_hand_.normalize();
00300 vec_helper_.normalize();
00301 vec_normal_.normalize();
00302 mat_orientation_.setValue(vec_shoulder_hand_.x(), vec_helper_.x(), vec_normal_.x(),
00303 vec_shoulder_hand_.y(), vec_helper_.y(), vec_normal_.y(),
00304 vec_shoulder_hand_.z(), vec_helper_.z(), vec_normal_.z());
00305 tf_l_shoulder_goal_.setBasis(mat_orientation_);
00306
00307 internal_tf.setTransform(tf::StampedTransform(tf_l_shoulder_goal_, calc_time, "/l_robot_shoulder", "/l_shoulder_adapted"));
00308 return true;
00309 }
00310
00311
00312 bool MotionAdaption::adaptElbows()
00313 {
00314
00315 limb_length_ = tf_r_shoulder_hand_.getOrigin().length();
00316 if (limb_length_ >= robot_arm_length_|| r_elbow_extended_)
00317 {
00318 elbow_x_ = robot_upper_arm_length_;
00319 elbow_y_ = 0.0;
00320 }
00321 else if (limb_length_ < 1e-6)
00322 {
00323 elbow_x_ = 0.0;
00324 elbow_y_ = robot_upper_arm_length_;
00325 }
00326 else
00327 {
00328 elbow_x_ = (pow(limb_length_, 2) - pow(robot_lower_arm_length_, 2) + pow(robot_upper_arm_length_, 2)) /
00329 ( 2 * limb_length_);
00330 elbow_y_ = sqrt(pow(robot_upper_arm_length_, 2) - pow(elbow_x_, 2));
00331 }
00332 tf_r_elbow_pos_.setOrigin(tf::Vector3(elbow_x_, elbow_y_, 0.0));
00333
00334 internal_tf.setTransform(tf::StampedTransform(tf_r_elbow_pos_, calc_time, "/r_shoulder_adapted", "/r_elbow_pos"));
00335
00336 limb_length_ = tf_l_shoulder_hand_.getOrigin().length();
00337 if (limb_length_ >= robot_arm_length_ || l_elbow_extended_)
00338 {
00339 elbow_x_ = robot_upper_arm_length_;
00340 elbow_y_ = 0.0;
00341 }
00342 else if (limb_length_ < 1e-6)
00343 {
00344 elbow_x_ = 0.0;
00345 elbow_y_ = robot_upper_arm_length_;
00346 }
00347 else
00348 {
00349 elbow_x_ = (pow(limb_length_, 2) - pow(robot_lower_arm_length_, 2) + pow(robot_upper_arm_length_, 2)) /
00350 ( 2 * limb_length_);
00351 elbow_y_ = sqrt(pow(robot_upper_arm_length_, 2) - pow(elbow_x_, 2));
00352 }
00353 tf_l_elbow_pos_.setOrigin(tf::Vector3(elbow_x_, elbow_y_, 0.0));
00354
00355 internal_tf.setTransform(tf::StampedTransform(tf_l_elbow_pos_, calc_time, "/l_shoulder_adapted", "/l_elbow_pos"));
00356
00357
00358 try
00359 {
00360
00361 internal_tf.lookupTransform("/r_elbow_pos", "/r_hand_scaled", ros::Time(0), tf_r_elbow_hand_);
00362
00363 internal_tf.lookupTransform("/l_elbow_pos", "/l_hand_scaled", ros::Time(0), tf_l_elbow_hand_);
00364 }
00365 catch (tf::TransformException ex)
00366 {
00367 ROS_DEBUG("%s",ex.what());
00368 ROS_WARN("(Step 3.5) Couldn't get one or more transformations from the elbow to the hands.");
00369 ROS_WARN("No further processing will be done!");
00370 return false;
00371 }
00372
00373 if(l_elbow_extended_ == true)
00374 tf_l_elbow_hand_.setOrigin(btVector3(robot_lower_arm_length_, 0.0, 0.0));
00375
00376 vec_elbow_hand_ = tf_r_elbow_hand_.getOrigin();
00377 vec_normal_ = btVector3(0.0, 0.0, 1.0);
00378 vec_helper_ = vec_normal_.cross(vec_elbow_hand_);
00379 vec_elbow_hand_.normalize();
00380 vec_normal_.normalize();
00381 vec_helper_.normalize();
00382 mat_orientation_.setValue(vec_elbow_hand_.x(), vec_helper_.x(), vec_normal_.x(),
00383 vec_elbow_hand_.y(), vec_helper_.y(), vec_normal_.y(),
00384 vec_elbow_hand_.z(), vec_helper_.z(), vec_normal_.z());
00385 tf_r_elbow_goal_.setOrigin(tf_r_elbow_pos_.getOrigin());
00386 tf_r_elbow_goal_.setBasis(mat_orientation_);
00387
00388
00389 internal_tf.setTransform(tf::StampedTransform(tf_r_elbow_goal_, calc_time, "/r_shoulder_adapted", "/r_elbow_adapted"));
00390 vec_elbow_hand_ = tf_l_elbow_hand_.getOrigin();
00391 vec_normal_ = btVector3(0.0, 0.0, 1.0);
00392 vec_helper_ = vec_normal_.cross(vec_elbow_hand_);
00393 vec_elbow_hand_.normalize();
00394 vec_normal_.normalize();
00395 vec_helper_.normalize();
00396 mat_orientation_.setValue(vec_elbow_hand_.x(), vec_helper_.x(), vec_normal_.x(),
00397 vec_elbow_hand_.y(), vec_helper_.y(), vec_normal_.y(),
00398 vec_elbow_hand_.z(), vec_helper_.z(), vec_normal_.z());
00399 tf_l_elbow_goal_.setOrigin(tf_l_elbow_pos_.getOrigin());
00400 tf_l_elbow_goal_.setBasis(mat_orientation_);
00401
00402 internal_tf.setTransform(tf::StampedTransform(tf_l_elbow_goal_, calc_time, "/l_shoulder_adapted", "/l_elbow_adapted"));
00403 return true;
00404 }
00405
00406
00407 bool MotionAdaption::adaptHands()
00408 {
00409 try
00410 {
00411
00412 internal_tf.lookupTransform("/ref_frame", "/r_elbow_adapted", ros::Time(0), tf_r_elbow_orient_);
00413
00414 internal_tf.lookupTransform("/ref_frame", "/l_elbow_adapted", ros::Time(0), tf_l_elbow_orient_);
00415 }
00416 catch (tf::TransformException const &ex)
00417 {
00418 ROS_DEBUG("%s",ex.what());
00419 ROS_WARN("(Step 3.6) Couldn't get one or more transformations from the ref frame to the elbows.");
00420 ROS_WARN("No further processing will be done!");
00421 return false;
00422 }
00423 tf_r_hand_adjusted_.setIdentity();
00424 tf_r_hand_adjusted_.setOrigin(btVector3(robot_lower_arm_length_, 0.0, 0.0));
00425
00426 internal_tf.setTransform(tf::StampedTransform(tf_r_hand_adjusted_, calc_time, "/r_elbow_adapted", "/r_hand_adapted"));
00427 tf_l_hand_goal_.setIdentity();
00428 tf_l_hand_goal_.setOrigin(btVector3(robot_lower_arm_length_, 0.0, 0.0));
00429
00430 internal_tf.setTransform(tf::StampedTransform(tf_l_hand_goal_, calc_time, "/l_elbow_adapted", "/l_hand_adapted"));
00431 return true;
00432 }
00433