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());
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
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
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
00062
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;
00066 lock_.unlock();
00067
00068 tf_filter_->add(C_T_L);
00069
00070
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
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
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_);
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
00110
00111 btMatrix3x3 Cref_R_C;
00112
00113
00114 tf::VectorTFToEigen(L_T_Cref_.inverse()*z,z_Cref);
00115 z_Cref.normalize();
00116
00117
00118
00119 Eigen::Matrix3d P = (Eigen::Matrix3d()).setIdentity()-z_Cref*z_Cref.transpose();
00120
00121
00122
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
00128 tf::Transform Cref_T_C(Cref_R_C.transpose(),tf::Vector3(0,0,0));
00129
00130
00131
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
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
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 }