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
00061
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);
00067 Eigen::Matrix3d Rot_ci=Eigen::Matrix3d::Zero();
00068
00069 if (fabs(angle-PI) < EPSILON_WRENCH_CONE_ROTATION)
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)
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
00082
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
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 }