phalange.cpp
Go to the documentation of this file.
00001 #include "../include/phalange.h"
00002 #include <geometry_msgs/PoseStamped.h>
00003 #include <tf_conversions/tf_eigen.h>
00004 #include <Eigen/Core>
00005 
00006 namespace ICR
00007 {
00008 
00009 Phalange::Phalange(tf::Transform const & L_T_Cref,std::string const & phl_name,std::string const & phl_frame_id, std::string const & sensor_topic) : nh_private_("~"),L_T_Cref_(L_T_Cref),C_T_O_(new icr_msgs::StampedContactPose),
00010                                                                                                                                                       phl_name_(phl_name),phl_frame_id_(phl_frame_id),obj_frame_id_("/fixed")
00011 {
00012   std::string searched_param;
00013   nh_private_.searchParam("tf_prefix",searched_param);
00014   nh_private_.getParam(searched_param, tf_prefix_);
00015 
00016   L_T_Cref_.setRotation(L_T_Cref_.getRotation().normalize());//ensure normalized orientation
00017 
00018   contacts_subs_=nh_.subscribe<icr_msgs::ContactState>(sensor_topic, 1, &Phalange::listenContacts, this);
00019   ct_pose_pub_=nh_.advertise<geometry_msgs::PoseStamped>(phl_name_ + "/contact_pose",1);
00020   set_pose_srv_ = nh_.advertiseService(phl_name_ + "/set_ref_contact_pose",&Phalange::setPose,this);
00021 
00022   //Initialize the filter
00023   tf_filter_ = new tf::MessageFilter<icr_msgs::StampedContactPose>(tf_list_, obj_frame_id_, 10);
00024   tf_filter_->registerCallback(boost::bind(&Phalange::transformContactPose, this, _1) );
00025 }
00026 //---------------------------------------------------------------------
00027 Phalange::~Phalange(){delete tf_filter_;}
00028 //---------------------------------------------------------------------
00029 void Phalange::transformContactPose(const boost::shared_ptr<const icr_msgs::StampedContactPose>& C_T_L)
00030 {
00031   geometry_msgs::PoseStamped P_in, P_out;
00032   P_in.header=C_T_L->header;
00033   P_in.pose=C_T_L->contact_pose.pose;
00034 
00035   //Compute the current contact pose w.r.t. the object frame 
00036   tf_list_.transformPose(obj_frame_id_,P_in,P_out); 
00037 
00038   lock_.lock();
00039   C_T_O_->contact_pose.phalange=phl_name_;
00040   C_T_O_->header.stamp=C_T_L->header.stamp;
00041   C_T_O_->header.frame_id=obj_frame_id_;
00042   C_T_O_->contact_pose.pose=P_out.pose;
00043   C_T_O_->contact_pose.touching=C_T_L->contact_pose.touching;
00044   lock_.unlock();
00045 }
00046 //---------------------------------------------------------------------
00047 void Phalange::listenContacts(const icr_msgs::ContactState::ConstPtr& cts_st)
00048 {
00049   icr_msgs::StampedContactPose::Ptr C_T_L(new icr_msgs::StampedContactPose);
00050   C_T_L->header.stamp=cts_st->header.stamp;
00051   C_T_L->header.frame_id=tf_prefix_ + phl_frame_id_;
00052 
00053   lock_.lock();   
00054 
00055   if(!strcmp(cts_st->info.c_str(),"touching"))
00056     {
00057         C_T_L->contact_pose.pose.position.x=cts_st->contact_position.x;
00058         C_T_L->contact_pose.pose.position.y=cts_st->contact_position.y;
00059         C_T_L->contact_pose.pose.position.z=cts_st->contact_position.z;
00060 
00061         //Contact orientation is generated via projecting the pose of the link frame on the nullspace of
00062         //the normal specified in the message
00063         tf::quaternionTFToMsg(projectPose(tf::Vector3(cts_st->contact_normal.x,cts_st->contact_normal.y,cts_st->contact_normal.z)),C_T_L->contact_pose.pose.orientation);
00064 
00065         C_T_L->contact_pose.touching=true;  //Phalange geometry and target object geometry are in contact
00066         lock_.unlock();
00067 
00068         tf_filter_->add(C_T_L);//Push the current pose on the filter queue
00069 
00070         //Publish the contact pose 
00071         geometry_msgs::PoseStamped P;
00072         P.header=C_T_L->header;
00073         P.pose=C_T_L->contact_pose.pose;
00074         ct_pose_pub_.publish(P);
00075 
00076         return;
00077     }
00078 
00079   lock_.unlock();
00080 
00081   //Use the reference contact pose if no contact is made
00082   tf::pointTFToMsg(L_T_Cref_.getOrigin(),C_T_L->contact_pose.pose.position);
00083   tf::quaternionTFToMsg(L_T_Cref_.getRotation(),C_T_L->contact_pose.pose.orientation);
00084 
00085   C_T_L->contact_pose.touching=false;
00086   tf_filter_->add(C_T_L);
00087 
00088   //Publish the contact pose 
00089   geometry_msgs::PoseStamped P;
00090   P.header=C_T_L->header;
00091   P.pose=C_T_L->contact_pose.pose;
00092   ct_pose_pub_.publish(P);
00093 }
00094 //---------------------------------------------------------------------
00095 void Phalange::setTargetObjFrameId(std::string const & obj_frame_id)
00096 {
00097 
00098   lock_.lock();
00099   obj_frame_id_=obj_frame_id;
00100   tf_filter_->setTargetFrame(obj_frame_id_);//Set the filter's target frame to the current target object
00101   lock_.unlock();
00102 }
00103 //---------------------------------------------------------------------
00104 tf::Quaternion Phalange::projectPose(tf::Vector3 const & z)
00105 {
00106   tf::Quaternion ori;
00107   Eigen::Vector3d z_Cref;  
00108 
00109   //The transposed rotation matrix containing the basis of the new contact frame expressed in the
00110   //reference contact frame. It is transposed since btMatrix3x3 only allows row-wise access
00111   btMatrix3x3 Cref_R_C;
00112 
00113   //Express z (given in the link frame) in the contact reference frame
00114   tf::VectorTFToEigen(L_T_Cref_.inverse()*z,z_Cref); 
00115   z_Cref.normalize();//Assert unit normal
00116 
00117   //Generate the matrix I-n*n^T for projecting on the nullspace of the new z-axis. The nullspace
00118   //is perpendicular to z.
00119   Eigen::Matrix3d P = (Eigen::Matrix3d()).setIdentity()-z_Cref*z_Cref.transpose();
00120   
00121   //Project the x & y axis of the contact reference frame - this is unstable if one of these axis is
00122   //(nearly) orthogonal to the nullspace - there should be some check on the norm of the projections ...
00123   tf::VectorEigenToTF((P*Eigen::Vector3d(1,0,0)).normalized(),Cref_R_C[0]);
00124   tf::VectorEigenToTF((P*Eigen::Vector3d(0,1,0)).normalized(),Cref_R_C[1]);
00125   tf::VectorEigenToTF(z_Cref,Cref_R_C[2]);
00126     
00127   //Transformation from the new contact frame to the reference frame
00128   tf::Transform Cref_T_C(Cref_R_C.transpose(),tf::Vector3(0,0,0));
00129 
00130   //Return the orientation (the position is computed in the listenContacts callback by simply
00131   //averaging the positions contained in the gazebo_msgs/ContactsState msg)
00132   return (L_T_Cref_*Cref_T_C.getRotation()).normalize();
00133 }
00134 //---------------------------------------------------------------------
00135 bool Phalange::setPose(icr_msgs::SetPose::Request  &req, icr_msgs::SetPose::Response &res)
00136 {
00137   //Sets the pose of the contact reference w.r.t the phalange link frame
00138   res.success=false;
00139   lock_.lock();
00140 
00141   L_T_Cref_.setOrigin(tf::Vector3(req.origin.x,req.origin.y,req.origin.z));
00142   L_T_Cref_.setRotation(tf::createQuaternionFromRPY(req.rpy.x,req.rpy.y,req.rpy.z));
00143 
00144   lock_.unlock();
00145   res.success=true;
00146   return res.success;
00147 }
00148 //---------------------------------------------------------------------
00149 icr_msgs::StampedContactPose::ConstPtr Phalange::getStampedContactPose()
00150 {
00151   //return a copy for thread safety
00152   lock_.lock();
00153   icr_msgs::StampedContactPose::ConstPtr C_T_O(new icr_msgs::StampedContactPose(*C_T_O_.get()));
00154   lock_.unlock();
00155 
00156   return C_T_O;
00157 }
00158 //---------------------------------------------------------------------
00159 std::string Phalange::getPhalangeName()
00160 {
00161   std::string phl_name;
00162 
00163   lock_.lock();
00164   phl_name=phl_name_;
00165   lock_.unlock();
00166 
00167   return phl_name;
00168 }
00169 //---------------------------------------------------------------------
00170 std::string Phalange::getPhalangeFrameId()
00171 {
00172   std::string phl_frame_id;
00173 
00174   lock_.lock();
00175   phl_frame_id=phl_frame_id_;
00176   lock_.unlock();
00177 
00178   return phl_frame_id;
00179 }
00180 //---------------------------------------------------------------------
00181 }//end namespace


icr
Author(s): Robert Krug
autogenerated on Mon Jan 6 2014 11:36:10