pca_gp_model.cpp
Go to the documentation of this file.
00001 /*
00002  * pca_gp_model.cpp
00003  *
00004  *  Created on: Feb 10, 2010
00005  *      Author: sturm
00006  */
00007 
00008 #include "articulation_models/models/pca_gp_model.h"
00009 #include "articulation_models/utils.h"
00010 
00011 using namespace std;
00012 using namespace articulation_msgs;
00013 
00014 #include "Eigen/Core"
00015 #include <Eigen/SVD>
00016 
00017 using namespace Eigen;
00018 
00019 #include <iomanip>
00020 #define VEC(a) setprecision(5)<<fixed<<a.x()<<" "<<a.y()<<" "<<a.z()<<" "<<a.w()<<" l="<<a.length()
00021 #define VEC2(a) "t=["<<VEC(a.getOrigin())<<"] r=[]"<<VEC(a.getRotation())<<"]"
00022 #define PRINT(a) cout << #a <<"=" << VEC(a)<<endl;
00023 #define PRINT2(a) cout << #a <<"=" << VEC2(a)<<endl;
00024 
00025 #include <boost/format.hpp>
00026 using namespace boost;
00027 
00028 namespace articulation_models {
00029 
00030 PCAGPModel::PCAGPModel() {
00031         complexity = 0;
00032 
00033         downsample = 20;
00034 
00035         //todo:add parameters here
00036         CovFuncND initialCovFunc;
00037         double initialSigmaNoise;
00038         vector<double> params = vector<double>(2);      // DOF + 1
00039         params[0] = -0.5;       // length scale, dof 1
00040         params[1] = 0.0;        // sigma
00041         initialCovFunc.setHyperparameter(params);
00042         initialSigmaNoise = -5;
00043 
00044         for(size_t i=0;i<7;i++) {
00045                 gp.push_back( new gaussian_process::SingleGP(initialCovFunc,initialSigmaNoise) );
00046         }
00047 
00048         initialized = false;
00049         outlier_ratio = 0.0;
00050 
00051 }
00052 
00053 PCAGPModel::~PCAGPModel() {
00054         for(size_t i=0;i<gp.size();i++) {
00055                 delete gp[i];
00056         }
00057         gp.clear();
00058 }
00059 
00060 
00061 void PCAGPModel::readParamsFromModel() {
00062         GenericModel::readParamsFromModel();
00063         getParam("downsample",downsample);
00064         getParam("rigid_position",rigid_position);
00065         getParam("prismatic_dir",prismatic_dir);
00066         double training_samples_float=0.00;
00067         getParam("training_samples",training_samples_float);
00068         training_samples = (int)training_samples_float;
00069         complexity = 3 + 6*training_samples;
00070 
00071         checkInitialized();//gp needs to build covariance matrix
00072 }
00073 
00074 void PCAGPModel::writeParamsToModel() {
00075         GenericModel::writeParamsToModel();
00076         setParam("downsample",downsample,ParamMsg::PARAM);
00077         setParam("rigid_position",rigid_position,ParamMsg::PARAM);
00078         setParam("prismatic_dir",prismatic_dir,ParamMsg::PARAM);
00079         setParam("training_samples",training_samples,ParamMsg::PARAM);
00080 }
00081 
00082 tf::Transform PCAGPModel::pose(size_t index) {
00083         tf::Transform pose;
00084         getParam(str(format("pose[%d]")%index),pose);
00085         return pose;
00086 }
00087 
00088 void PCAGPModel::storeData(bool inliersOnly) {
00089         // copy data into params
00090         bool resample = false;
00091         size_t n = model.track.pose.size();
00092 
00093         vector<double> inliers_cum(n,0);
00094         double sum = 0;
00095         for(size_t i=0;i<n;i++) {
00096                 if(inliersOnly)
00097                         sum += 1 - model.track.channels[channelOutlier].values[i];
00098                 else
00099                         sum += 1;
00100                 inliers_cum[i] = sum;
00101         }
00102 //      cout <<"inlier sum is "<<sum<<endl;
00103 
00104         training_samples = (int)sum;
00105         if(downsample>0 && n>downsample) {
00106                 training_samples  = downsample;
00107                 resample = true;
00108         }
00109         complexity = 1 + getDOFs() + 6*training_samples;
00110 
00111         for(size_t i=0;i<training_samples;i++) {
00112                 double choice = i / (double)training_samples;
00113                 size_t j=0;
00114                 for(j=0;j<n;j++) {
00115                         if(inliers_cum[j]/sum>choice) break;
00116                 }
00117 //              cout <<"choosing j="<<j<<endl;
00118                 setParam(str(format("pose[%d]")%i),poseToTransform(model.track.pose[j]),ParamMsg::PARAM);
00119         }
00120 
00121 }
00122 
00123 bool PCAGPModel::fitModel() {
00124         if(getSamples()<3) return true;
00125 
00126 
00127 
00128 
00129         // outlier experimental
00130         storeData(false);       // use all points
00131         outlier_ratio = 0.0;
00132         buildGPs();
00133         getLogLikelihood(true);
00144 //
00145 //      cout << "outlier ratio="<<this->outlier_ratio<<endl;
00146 
00147         return true;
00148 }
00149 
00150 void PCAGPModel::buildGPs() {
00151         if(training_samples<3) return;
00152         // fit PCA
00153         // compute center
00154         tf::Vector3 sum_p(0,0,0);
00155         for (size_t j = 0; j < training_samples; j++) {
00156                 sum_p = sum_p + pose(j).getOrigin();
00157         }
00158         rigid_position = sum_p / training_samples;
00159 
00160         // find line direction
00161         MatrixXf X_trans(training_samples, 3);
00162         for (size_t j = 0; j < training_samples; j++) {
00163                 tf::Vector3 diff = pose(j).getOrigin() - rigid_position;
00164                 X_trans(j, 0) = diff.x();
00165                 X_trans(j, 1) = diff.y();
00166                 X_trans(j, 2) = diff.z();
00167         }
00168 
00169         VectorXf b(training_samples);
00170         VectorXf x(3);
00171         b = VectorXf::Zero(training_samples);
00172         JacobiSVD<MatrixXf> svdOfA(X_trans);
00173 
00174         const Eigen::MatrixXf U = svdOfA.matrixU();
00175         const Eigen::MatrixXf V = svdOfA.matrixV();
00176         const Eigen::VectorXf S = svdOfA.singularValues();
00177 
00178 //      Eigen::MatrixXf Y_trans = U * S.asDiagonal();
00179 //      cout << endl;
00180 //      cout <<"X=["<<endl;
00181 //      for(int i=0;i<X_trans.rows();i++) {
00182 //              for(int j=0;j<X_trans.cols();j++) {
00183 //                      if(j!=0)
00184 //                              cout <<", ";
00185 //                      cout <<X_trans(i,j);
00186 //              }
00187 //              cout <<";"<<endl;
00188 //      }
00189 //      cout << "]"<<endl;
00190 //      cout << X_trans<<endl;
00191 //      cout << endl;
00192 //      cout << Y_trans<<endl;
00193 //      cout << endl;
00194 //      cout << V;
00195 //      cout << endl;
00196         double v0=V(0,0),v1=V(1,0),v2=V(2,0);
00197         prismatic_dir= tf::Vector3(v0,v1,v2);
00198 //      PRINT(prismatic_dir);
00199 
00200         if(!check_values(rigid_position)) {
00201                 cerr <<"rigid_position has NaNs"<<endl;
00202                 return ;
00203         }
00204         if(!check_values(prismatic_dir))  {
00205                 cerr <<"prismatic_dir has NaNs"<<endl;
00206                 return ;
00207         }
00208 //      cout << X_trans << endl;
00209 //      PRINT(rigid_position);
00210 //      PRINT(prismatic_dir);
00211 //      writeParamsToModel();
00212 //      prismatic_dir = tf::Vector3(1,-1,0);
00213 //      prismatic_dir = tf::Vector3(0.48308,-0.87558,0.00000);
00214 //      prismatic_dir = tf::Vector3(0.88215,0.46638,-0.06560);
00215 //      prismatic_dir = tf::Vector3(prismatic_dir.x(),prismatic_dir.y(),prismatic_dir.z());
00216 //      prismatic_dir.normalize();
00217 //      cout <<"fitting:";
00218 //      PRINT(prismatic_dir);
00219 
00220 
00221         TVector<TDoubleVector> input(training_samples);
00222         TVector<double> output[7];
00223         for(size_t j=0;j<7;j++) {
00224                 output[j] = TDoubleVector(training_samples);
00225         }
00226 
00227         for(size_t i=0;i<training_samples;i++) {
00228                 input[i] = TDoubleVector(1);
00229 
00230                 geometry_msgs::Pose p = transformToPose(pose(i));
00231                 input[i][0] = predictConfiguration( p )[0];
00232                 output[0][i] = p.position.x;
00233                 output[1][i] = p.position.y;
00234                 output[2][i] = p.position.z;
00235                 output[3][i] = p.orientation.w;
00236                 output[4][i] = p.orientation.x;
00237                 output[5][i] = p.orientation.y;
00238                 output[6][i] = p.orientation.z;
00239         }
00240 
00241         for(size_t j=0;j<7;j++) {
00242 //              cout << "setting data, j="<<j<<" n="<<input.size()<<endl;
00243                 gp[j]->SetData(input,output[j]);
00244 //              gp[j]->OptimizeGP();
00245         }
00246 
00247 
00248  //     cout << "fitting model, end.."<<endl;
00249 }
00250 
00251 V_Configuration PCAGPModel::predictConfiguration(geometry_msgs::Pose pose) {
00252         tf::Vector3 diff = (positionToVector(pose.position) - rigid_position);
00253 //      PRINT(diff);
00254 //      PRINT(prismatic_dir);
00255 
00256         V_Configuration q( 1 );
00257         q(0) = diff.dot(prismatic_dir);
00258 
00259         return q;
00260 }
00261 
00262 geometry_msgs::Pose PCAGPModel::predictPose(V_Configuration q) {
00263         geometry_msgs::Pose result;
00264         double mean_x=0,var_x=0;
00265         double mean_y=0,var_y=0;
00266         double mean_z=0,var_z=0;
00267         double mean_rw=0,var_rw=0;
00268         double mean_rx=0,var_rx=0;
00269         double mean_ry=0,var_ry=0;
00270         double mean_rz=0,var_rz=0;
00271         TDoubleVector inp(1);
00272         inp(0) = q[0];
00273         gp[0]->Evaluate( inp, mean_x, var_x );
00274         gp[1]->Evaluate( inp, mean_y, var_y );
00275         gp[2]->Evaluate( inp, mean_z, var_z );
00276         gp[3]->Evaluate( inp, mean_rw, var_rw );
00277         gp[4]->Evaluate( inp, mean_rx, var_rx );
00278         gp[5]->Evaluate( inp, mean_ry, var_ry );
00279         gp[6]->Evaluate( inp, mean_rz, var_rz );
00280 
00281         tf::Quaternion pred_rot(mean_rx,mean_ry,mean_rz,mean_rw);
00282         tf::Vector3 pred_pos(mean_x,mean_y,mean_z);
00283         pred_rot.normalize();
00284         tf::Transform pred_pose(pred_rot,pred_pos);
00285         result = transformToPose(pred_pose);
00286 
00287 //      tf::Transform t( rigid_orientation, rigid_position + prismatic_dir*q[0]);
00288 //      result = transformToPose(t);
00289 
00290         return result;
00291 }
00292 
00293 void PCAGPModel::checkInitialized() {
00294         if(!initialized) {
00295                 buildGPs();
00296                 initialized = true;
00297         }
00298 }
00299 
00300 void PCAGPModel::projectPoseToConfiguration() {
00301         checkInitialized();
00302         GenericModel::projectPoseToConfiguration();
00303 }
00304 
00305 void PCAGPModel::projectConfigurationToPose() {
00306         checkInitialized();
00307         GenericModel::projectConfigurationToPose();
00308 }
00309 
00310 void PCAGPModel::projectConfigurationToJacobian() {
00311         checkInitialized();
00312         GenericModel::projectConfigurationToJacobian();
00313 }
00314 
00315 bool PCAGPModel::evaluateModel() {
00316         checkInitialized();
00317         return GenericModel::evaluateModel();
00318 }
00319 
00320 bool PCAGPModel::normalizeParameters() {
00321         if(model.track.pose.size()>2) {
00322                 rigid_position = rigid_position + predictConfiguration(model.track.pose.front())[0] * prismatic_dir;
00323                 if(predictConfiguration(model.track.pose.back())[0]<0)
00324                         prismatic_dir *= -1;
00325         }
00326         return true;
00327 }
00328 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Properties Friends Defines


articulation_models
Author(s): Juergen Sturm
autogenerated on Wed Dec 26 2012 15:35:18