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