ows.cpp
Go to the documentation of this file.
00001 #include "../include/ows.h"
00002 #include "../include/debug.h"
00003 #include "../include/config.h"
00004 #include <assert.h>
00005 #include <stdio.h>
00006 #include <math.h>
00007 #include <Eigen/Geometry>
00008 
00009 namespace ICR
00010 {
00011 //--------------------------------------------------------------------
00012 //--------------------------------------------------------------------
00013 OWS::OWS() : initialized_(false), div_by_lambda_(false), lambda_(0),num_wc_(0){wrench_cones_.clear();} 
00014 //--------------------------------------------------------------------
00015 OWS::OWS(OWS const& src) :  wrench_cones_(src.wrench_cones_), parent_obj_name_(src.parent_obj_name_), initialized_(src.initialized_), 
00016                             div_by_lambda_(src.div_by_lambda_), lim_surf_(src.lim_surf_), lambda_(src.lambda_),num_wc_(src.num_wc_) {}
00017 //--------------------------------------------------------------------
00018 OWS& OWS::operator=(OWS const& src)
00019 {
00020   if (this !=&src)
00021     {
00022       wrench_cones_=src.wrench_cones_;
00023       parent_obj_name_=src.parent_obj_name_;
00024       initialized_=src.initialized_;
00025       div_by_lambda_=src.div_by_lambda_;
00026       lim_surf_=src.lim_surf_;
00027       lambda_=src.lambda_;
00028       num_wc_=src.num_wc_;
00029     }
00030   return *this;
00031 }
00032 //--------------------------------------------------------------------
00033 std::ostream& operator<<(std::ostream& stream, OWS const& ows)
00034 {
00035   stream <<'\n'<<"OWS: "<<'\n'
00036          <<"Parent object name: "<<ows.parent_obj_name_<<'\n'
00037          <<"Is initialized: "<<ows.initialized_<<'\n'
00038          <<"Number of wrench cones: "<<ows.num_wc_<<'\n'
00039          <<"Lambda: "<<ows.lambda_<<'\n'
00040          <<"Wrenches divided by lambda: "<<ows.div_by_lambda_<<'\n'<<'\n';
00041 
00042   return stream;
00043 }
00044 //--------------------------------------------------------------------
00045 OWS::~OWS()
00046 {
00047   for(uint i=0; i < num_wc_; i++)
00048     delete wrench_cones_[i];
00049 }
00050 //--------------------------------------------------------------------
00051 void OWS::updateLambda(Eigen::Vector3d const* const cp_vtx)
00052 {  
00053   double norm=(*cp_vtx).norm();
00054   lambda_ = (norm > lambda_) ? norm : lambda_;
00055 }
00056 //--------------------------------------------------------------------
00057 void OWS::addWrenchCone(uint id,Eigen::Vector3d const* const cp_vtx, Eigen::Vector3d const* const cp_vtx_normal)
00058 {
00059 
00060   //Build the transformation matrix for the wrenches according to "Murray, Li & Sastry - A Mathematical Introduction
00061   //to Robotic Manipulation; pp. 218"
00062   Eigen::Vector3d z_ax(0,0,1);
00063   Eigen::Vector3d axis=(z_ax.cross(*cp_vtx_normal));
00064   axis.normalize();
00065   double angle=acos(z_ax.dot(*cp_vtx_normal));
00066   assert(angle==angle); //assure that the angle is not NaN
00067   Eigen::Matrix3d Rot_ci=Eigen::Matrix3d::Zero();
00068 
00069   if (fabs(angle-PI) < EPSILON_WRENCH_CONE_ROTATION) //rotation angle is pi    
00070     {Rot_ci(0,0)=1;  Rot_ci(1,1)=-1; Rot_ci(2,2)=-1;}
00071   else if (fabs(angle) < EPSILON_WRENCH_CONE_ROTATION) // rotation angle is 0
00072     Rot_ci.setIdentity();
00073   else
00074     Rot_ci=Eigen::AngleAxisd(angle,axis);
00075 
00076   Eigen::Matrix<double,6,6> trans_mat=Eigen::Matrix<double,6,6>::Zero();
00077   trans_mat.bottomLeftCorner<3,3>()=skewSymmetricMatrix(*cp_vtx)*Rot_ci;
00078   trans_mat.topLeftCorner<3,3>()=Rot_ci;
00079   trans_mat.bottomRightCorner<3,3>()=Rot_ci;
00080  
00081   //Multiply the local wrench cone with the transformation matrix and create a new Wrench cone associated
00082   //with the current contact point
00083   wrench_cones_.push_back(new WrenchCone(id,trans_mat*(*lim_surf_.getLocalWrenchCone()->getWrenches())));
00084 }
00085 //--------------------------------------------------------------------
00086 void OWS::init(TargetObject const& obj, LimitSurface const& lim_surf)
00087 {
00088   //would need to clean up the wrench_cones_ before recomputing the OWS
00089   assert(!initialized_);
00090 
00091   num_wc_=obj.getNumCp();
00092   wrench_cones_.reserve(num_wc_);
00093   parent_obj_name_=obj.getName();
00094   lim_surf_=lim_surf;
00095     
00096   for(uint id=0; id < num_wc_;id++)
00097     {
00098       addWrenchCone(id,obj.getContactPoint(id)->getVertex(),obj.getContactPoint(id)->getVertexNormal());
00099       updateLambda(obj.getContactPoint(id)->getVertex());
00100     } 
00101 
00102   initialized_=true;
00103 
00104 #ifdef DIVIDE_OWS_BY_LAMBDA
00105     this->divideByLambda();
00106 #endif
00107 
00108 #ifdef DEBUG_OWS // File for writing the wrenches
00109   remove("../debug/wrenches.txt");
00110   FILE* wn=fopen ("../debug/wrenches.txt","a");
00111   if(!wn)
00112     {
00113       std::cout<<"Error in OWS: Couldn't write to file. Exiting..."<<std::endl;
00114       exit(1);
00115     }
00116 
00117   Eigen::Matrix<double,6,Eigen::Dynamic> pw;
00118   for(uint id=0; id < num_wc_;id++)
00119     {
00120       pw=*wrench_cones_[id]->getWrenches();
00121  
00122       for (int i=0; i<pw.cols();i++)
00123         fprintf(wn, "% f % f % f % f % f % f \n", pw.col(i)(0),pw.col(i)(1) ,pw.col(i)(2),pw.col(i)(3),pw.col(i)(4) ,pw.col(i)(5));    
00124     }
00125 
00126 fclose (wn);
00127 #endif
00128 }
00129 //--------------------------------------------------------------------
00130 uint OWS::getNumWrenchCones()const{return num_wc_;}
00131 //--------------------------------------------------------------------
00132 WrenchCone const* OWS::getWrenchCone(uint id)const{return wrench_cones_.at(id);}
00133 //--------------------------------------------------------------------
00134 LimitSurface const* OWS::getLimitSurface()const{return &lim_surf_;}
00135 //--------------------------------------------------------------------
00136 void OWS::scale(double scale)
00137 {
00138   for(uint id=0; id < num_wc_; id++)
00139     wrench_cones_[id]->scaleWrenches(scale);
00140 
00141 }
00142 void OWS::divideByLambda()
00143 {
00144   assert(initialized_);
00145 
00146     if(!div_by_lambda_)
00147       for(uint id=0; id < num_wc_; id++)
00148         wrench_cones_[id]->scaleWrenchTorques(1/lambda_);
00149 
00150   div_by_lambda_=true;
00151 }
00152 //--------------------------------------------------------------------
00153 std::string OWS::getParentObjectName()const{return parent_obj_name_;}
00154 //--------------------------------------------------------------------
00155 //--------------------------------------------------------------------
00156 }//namespace ICR


libicr
Author(s): Robert Krug
autogenerated on Mon Jan 6 2014 11:33:08