00001
00002
00003
00004
00005
00006
00007 #include <boost/format.hpp>
00008 #include "articulation_models/models/generic_model.h"
00009
00010 #include "articulation_models/utils.h"
00011 #include "articulation_models/models/factory.h"
00012 #include <gsl/gsl_multimin.h>
00013 #include <gsl/gsl_blas.h>
00014
00015 using namespace std;
00016 using namespace boost;
00017
00018 using namespace Eigen;
00019
00020 using namespace articulation_msgs;
00021
00022 #include <iomanip>
00023 #define VEC(a) setprecision(5)<<fixed<<a.x()<<" "<<a.y()<<" "<<a.z()<<" "<<a.w()<<" l="<<a.length()
00024 #define VEC2(a) "t=["<<VEC(a.getOrigin())<<"] r=[]"<<VEC(a.getRotation())<<"]"
00025 #define PRINT(a) cout << #a <<"=" << VEC(a)<<endl;
00026 #define PRINT2(a) cout << #a <<"=" << VEC2(a)<<endl;
00027
00028 namespace articulation_models {
00029
00030 GenericModel::GenericModel() {
00031 setId(-1);
00032 sigma_position = 0.005;
00033 sigma_orientation = 360 * M_PI/180.0;
00034
00035 avg_error_position = 0;
00036 avg_error_orientation = 0;
00037 bic = 0;
00038
00039 last_error_jacobian = 0;
00040 evaluated = false;
00041 supress_similar = true;
00042 outlier_ratio = 0.5;
00043 sac_iterations = 100;
00044 optimizer_iterations = 10;
00045
00046
00047 prior_outlier_ratio = log(0.01) / (- 0.05);
00048
00049 complexity = 0;
00050 jacobian = Eigen::MatrixXd();
00051 hessian = Eigen::MatrixXd();
00052 }
00053
00054 void GenericModel::setModel(const ModelMsg& model) {
00055 this->model = model;
00056 readParamsFromModel();
00057 prepareChannels();
00058 }
00059
00060 ModelMsg GenericModel::getModel() {
00061 writeParamsToModel();
00062 model.name = getModelName();
00063 model.header = model.track.header;
00064 model.track.pose_flags.resize(model.track.pose.size(),TrackMsg::POSE_VISIBLE );
00065 if(model.track.pose.size())
00066 model.track.pose_flags[model.track.pose.size()-1] |= TrackMsg::POSE_END_OF_SEGMENT;
00067 return model;
00068 }
00069
00070 void GenericModel::setTrack(const TrackMsg& track) {
00071 this->model.track = track;
00072 prepareChannels();
00073 }
00074
00075 TrackMsg GenericModel::getTrack() {
00076 return model.track;
00077 }
00078
00079 void GenericModel::setId(int id) {
00080 model.id = id;
00081 }
00082
00083 int GenericModel::getId() {
00084 return(model.id);
00085 }
00086
00087
00088 std::string GenericModel::getModelName() {
00089 return MultiModelFactory::instance.getLongName(this);
00090 }
00091
00092 size_t GenericModel::getDOFs() {
00093 return 0;
00094 }
00095
00096 size_t GenericModel::getSamples() {
00097 return model.track.pose.size();
00098 }
00099
00100
00101 void GenericModel::readParamsFromModel() {
00102 getParam("sigma_position",sigma_position);
00103 getParam("sigma_orientation",sigma_orientation);
00104 getParam("supress_similar",supress_similar);
00105 getParam("avg_error_position",avg_error_position);
00106 getParam("avg_error_orientation",avg_error_orientation);
00107 getParam("bic",bic);
00108 getParam("last_error_jacobian",last_error_jacobian);
00109 getParam("evaluated",evaluated);
00110
00111 getParam("jacobian",jacobian);
00112 getParam("hessian",hessian);
00113 getParam("loglikelihood",loglikelihood);
00114 getParam("outlier_ratio",outlier_ratio);
00115 getParam("sac_iterations",sac_iterations);
00116 getParam("prior_outlier_ratio",prior_outlier_ratio);
00117 }
00118
00119 void GenericModel::writeParamsToModel() {
00120 setParam("sigma_position",sigma_position,ParamMsg::PRIOR);
00121 setParam("sigma_orientation",sigma_orientation,ParamMsg::PRIOR);
00122 setParam("supress_similar",supress_similar,ParamMsg::PRIOR);
00123 setParam("avg_error_position",avg_error_position,ParamMsg::EVAL);
00124 setParam("avg_error_orientation",avg_error_orientation,ParamMsg::EVAL);
00125 setParam("loglikelihood",loglikelihood,ParamMsg::EVAL);
00126 setParam("bic",bic,ParamMsg::EVAL);
00127 setParam("last_error_jacobian",last_error_jacobian,ParamMsg::EVAL);
00128 setParam("evaluated",evaluated,ParamMsg::EVAL);
00129 setParam("complexity",complexity,ParamMsg::PRIOR);
00130 setParam("jacobian",jacobian,ParamMsg::EVAL);
00131 setParam("hessian",hessian,ParamMsg::EVAL);
00132 setParam("dofs",getDOFs(),ParamMsg::EVAL);
00133 setParam("samples",getSamples(),ParamMsg::EVAL);
00134 setParam("outlier_ratio",outlier_ratio,ParamMsg::EVAL);
00135 setParam("sac_iterations",sac_iterations,ParamMsg::PRIOR);
00136 setParam("prior_outlier_ratio",prior_outlier_ratio,ParamMsg::PRIOR);
00137 }
00138
00139 void GenericModel::prepareChannels() {
00140 channelOutlier = openChannel("outlier");
00141 channelLogLikelihood = openChannel("loglikelihood");
00142 channelInlierLogLikelihood = openChannel("loglikelihood_if_inlier");
00143 channelConfiguration.resize(getDOFs(),0);
00144 for(size_t i=0;i<getDOFs();i++) {
00145 channelConfiguration[i] = openChannel(str(format("q%d")%i));
00146 }
00147
00148 }
00149
00150 double GenericModel::getParam(std::string name) {
00151 for(size_t i=0;i<model.params.size();i++) {
00152 if(model.params[i].name == name) {
00153 return(model.params[i].value);
00154 }
00155 }
00156
00157 return 0.00;
00158 }
00159
00160 void GenericModel::getParam(std::string name,double& value) {
00161 if(hasParam(name))
00162 value = getParam(name);
00163 }
00164
00165 void GenericModel::getParam(std::string name,Eigen::VectorXd &vec) {
00166 for(int i=0;i<vec.rows();i++)
00167 vec(i) = getParam( str(boost::format( name+"[%1%]") %i ) );
00168 }
00169
00170 void GenericModel::getParam(std::string name,tf::Vector3 &vec) {
00171 vec.setX( getParam( name+".x" ) );
00172 vec.setY( getParam( name+".y" ) );
00173 vec.setZ( getParam( name+".z" ) );
00174 }
00175
00176 void GenericModel::getParam(std::string name,tf::Quaternion &quat) {
00177 quat.setX( getParam( name+".x" ) );
00178 quat.setY( getParam( name+".y" ) );
00179 quat.setZ( getParam( name+".z" ) );
00180 quat.setW( getParam( name+".w" ) );
00181 }
00182
00183 void GenericModel::getParam(std::string name,tf::Transform &t) {
00184 tf::Quaternion q;
00185 tf::Vector3 v;
00186 getParam(name+".orientation",q);
00187 getParam(name+".position",v);
00188 t = tf::Transform(q,v);
00189 }
00190
00191 void GenericModel::getParam(std::string name,Eigen::MatrixXd &mat) {
00192 for(int r=0;r<mat.rows();r++)
00193 for(int c=0;c<mat.cols();c++)
00194 mat(r,c) = getParam( str(boost::format( name+"[%1%][%2%]") %r % c) );
00195 }
00196
00197 void GenericModel::setParam(std::string name,double value,int type) {
00198 for(size_t i=0;i<model.params.size();i++) {
00199 if(model.params[i].name == name) {
00200 model.params[i].value = value;
00201 return;
00202 }
00203 }
00204 ParamMsg data;
00205 data.name = name;
00206 data.value = value;
00207 data.type = type;
00208 model.params.push_back(data);
00209 }
00210
00211 void GenericModel::setParam(std::string name,const Eigen::VectorXd &vec,int type) {
00212 for(int i=0;i<vec.rows();i++)
00213 setParam( boost::str(boost::format( name+"[%1%]") %i ),vec(i),type );
00214 }
00215
00216 void GenericModel::setParam(std::string name,const tf::Vector3 &vec,int type) {
00217 setParam( name+".x",vec.x(),type );
00218 setParam( name+".y",vec.y(),type );
00219 setParam( name+".z",vec.z(),type );
00220 }
00221
00222 void GenericModel::setParam(std::string name,const tf::Quaternion &quat,int type) {
00223 setParam( name+".x",quat.x(),type );
00224 setParam( name+".y",quat.y(),type );
00225 setParam( name+".z",quat.z(),type );
00226 setParam( name+".w",quat.w(),type );
00227 }
00228
00229 void GenericModel::setParam(std::string name,const tf::Transform &t,int type) {
00230 setParam(name+".position",t.getOrigin(),type);
00231 setParam(name+".orientation",t.getRotation(),type);
00232 }
00233
00234 void GenericModel::setParam(std::string name,const Eigen::MatrixXd &mat,int type) {
00235 for(int r=0;r<mat.rows();r++)
00236 for(int c=0;c<mat.cols();c++)
00237 setParam( str(boost::format( name+"[%1%][%2%]") %r%c ),mat(r,c),type );
00238 }
00239
00240 bool GenericModel::hasParam(std::string name) {
00241 for(size_t i=0;i<model.params.size();i++) {
00242 if(model.params[i].name == name)
00243 return(true);
00244 }
00245 return false;
00246 }
00247
00248
00249 int GenericModel::openChannel(std::string name,bool autocreate) {
00250 return(articulation_models::openChannel(model.track,name,autocreate));
00251 }
00252
00253
00254 bool GenericModel::fitModel() {
00255 if(!sampleConsensus()) {
00256
00257 return false;
00258 }
00259 if(!optimizeParameters()) {
00260
00261 return false;
00262 }
00263 if(!normalizeParameters()) {
00264 return false;
00265 }
00266 return true;
00267 }
00268
00269 bool GenericModel::fitMinMaxConfigurations() {
00270 setParam("q_min",getMinConfigurationObserved(),ParamMsg::PARAM);
00271 setParam("q_max",getMaxConfigurationObserved(),ParamMsg::PARAM);
00272 return true;
00273 }
00274
00275
00276
00277 bool GenericModel::evaluateModel() {
00278
00279 if(model.track.pose.size() == 0)
00280 return false;
00281
00282
00283 loglikelihood = getLogLikelihood(false);
00284
00285
00286
00287 size_t n = model.track.pose.size();
00288
00289
00290 double sum_position2 = 0;
00291 double sum_orientation2 = 0;
00292
00293 double sum_position = 0;
00294 double sum_orientation = 0;
00295
00296
00297 for(size_t i=0;i<n;i++) {
00298 tf::Transform p1 = poseToTransform(model.track.pose[i]);
00299 tf::Transform p2 = poseToTransform(model.track.pose_projected[i]);
00300 tf::Transform diff = p1.inverseTimes(p2);
00301 double err_position2 = diff.getOrigin().length2();
00302 double err_orientation2 = SQR(diff.getRotation().getAngle());
00303
00304
00305 sum_position2 += err_position2;
00306 sum_orientation2 += err_orientation2;
00307 sum_position += sqrt(err_position2);
00308 sum_orientation += sqrt(err_orientation2);
00309 }
00310
00311
00312 avg_error_position = sum_position/n;
00313 avg_error_orientation = sum_orientation/n;
00314 loglikelihood += - ((double)n)*getDOFs()*log(n);
00315
00316 bic =
00317 -2*(loglikelihood )
00318 +complexity
00319 * log( n );
00320
00321 last_error_jacobian = evalLatestJacobian();
00322
00323 evaluated = true;
00324
00325 if(model.track.pose.size()>=2) {
00326 VectorXd q1 = predictConfiguration( model.track.pose.front() );
00327 VectorXd q2 = predictConfiguration( model.track.pose.back() );
00328
00329 jacobian = predictJacobian( q2 );
00330 hessian = predictHessian( q2 );
00331 if(getDOFs()>=1 ) {
00332 VectorXd p(3);
00333 for(size_t i=0;i<model.track.pose.size();i++) {
00334 p += pointToEigen(model.track.pose[i].position) - pointToEigen(model.track.pose.front().position);
00335 }
00336 if(p.dot(jacobian.col(0))<0)
00337 jacobian *= -1;
00338 hessian *= -1;
00339 }
00340 }
00341 writeParamsToModel();
00342 return true;
00343 }
00344
00345 double GenericModel::evalLatestJacobian() {
00346 if(model.track.pose.size()<2)
00347 return 0.00;
00348
00349
00350 VectorXd p1 = pointToEigen( model.track.pose[model.track.pose.size()-1].position );
00351 VectorXd p2 = pointToEigen( model.track.pose[model.track.pose.size()-2].position );
00352 VectorXd pD_obs = p1-p2;
00353 if(pD_obs.norm() == 0)
00354 return 0.00;
00355 pD_obs.normalize();
00356
00357
00358
00359
00360 if(getDOFs()==0)
00361 return 2*M_PI;
00362
00363
00364 VectorXd q1 = predictConfiguration( model.track.pose[model.track.pose.size()-1] );
00365 VectorXd q2 = predictConfiguration( model.track.pose[model.track.pose.size()-2] );
00366
00367
00368 MatrixXd J2 = predictJacobian( q2 );
00369
00370 VectorXd qD = (q1 - q2);
00371
00372 VectorXd pD_pred = J2 * qD;
00373
00374 if(pD_pred.norm() == 0)
00375 return 0.00;
00376 pD_pred.normalize();
00377
00378
00379
00380
00381
00382 return acos( pD_obs.dot( pD_pred ) );
00383 }
00384
00385 double GenericModel::getPositionError() {
00386 return avg_error_position;
00387 }
00388
00389 double GenericModel::getOrientationError() {
00390 return avg_error_orientation;
00391 }
00392
00393 double GenericModel::getBIC() {
00394 return bic;
00395 }
00396
00397
00398 geometry_msgs::Pose GenericModel::predictPose(V_Configuration q) {
00399 geometry_msgs::Pose p;
00400 p.orientation.w = 1;
00401 return p;
00402 }
00403
00404 M_CartesianJacobian GenericModel::predictJacobian(V_Configuration vq,double delta) {
00405 M_CartesianJacobian J;
00406 J.resize(3,getDOFs());
00407 VectorXd p = pointToEigen(predictPose(vq).position);
00408 for(size_t i=0;i<getDOFs();i++) {
00409 V_Configuration q = vq;
00410 q(i) += delta;
00411 J.col(i) = (pointToEigen( predictPose(q).position ) - p)/delta;
00412 }
00413 return J;
00414 }
00415
00416 M_CartesianJacobian GenericModel::predictHessian(V_Configuration q,double delta) {
00417 M_CartesianJacobian H;
00418 H.resize(3*getDOFs(),getDOFs());
00419
00420 for(size_t i=0;i<getDOFs();i++) {
00421 V_Configuration qd = q;
00422 q(i) += delta;
00423 M_CartesianJacobian H_part;
00424
00425 M_CartesianJacobian J = predictJacobian(q);
00426 M_CartesianJacobian Jd = predictJacobian(qd);
00427
00428
00429
00430
00431 H_part = (Jd - J)/delta;
00432
00433 for(size_t r=0;r<3;r++) {
00434 for(size_t c=0;c<getDOFs();c++) {
00435 H(r+3*i,c) = H_part(r,c);
00436 }
00437 }
00438 }
00439 return H;
00440 }
00441
00442
00443 void GenericModel::setConfiguration(size_t index,V_Configuration q) {
00444 std::map<int,int> channel;
00445
00446 for(size_t ch=0;ch<getDOFs();ch++) {
00447 std::stringstream s;
00448 s << "q" << ch;
00449 channel[ch] = openChannel( s.str() );
00450 }
00451
00452 for(int j=0;j<q.rows();j++) {
00453 model.track.channels[ channel[j] ].values[index] = q[j];
00454 }
00455 }
00456
00457
00458 void GenericModel::setJacobian(size_t index,M_CartesianJacobian J) {
00459 std::map<int,std::map<int,int> > channel;
00460
00461 for(int r=0;r<J.rows();r++)
00462 for(int c=0;c<J.cols();c++)
00463 channel[r][c] = openChannel( boost::str(boost::format( "J[%1%][%2%]") %r%c ) );
00464
00465 for(int r=0;r<J.rows();r++)
00466 for(int c=0;c<J.cols();c++)
00467 model.track.channels[ channel[r][c] ].values[index] = J(r,c);
00468 }
00469
00470 V_Configuration GenericModel::getConfiguration(size_t index) {
00471 std::map<int,int> channel;
00472
00473 for(size_t ch=0;ch<getDOFs();ch++) {
00474 std::stringstream s;
00475 s << "q" << ch;
00476 channel[ch] = openChannel( s.str() );
00477 }
00478
00479 V_Configuration q;
00480 if (getDOFs()) q.resize(getDOFs());
00481 for(int j=0;j<q.rows();j++) {
00482 q[j] = model.track.channels[ channel[j] ].values[index];
00483 }
00484 return(q);
00485 }
00486
00487 V_Configuration GenericModel::predictConfiguration(geometry_msgs::Pose pose) {
00488 V_Configuration q;
00489 if(getDOFs()>0) q.resize(getDOFs());
00490 return q;
00491 }
00492
00493
00494
00495 V_Configuration GenericModel::getMinConfigurationObserved() {
00496 if(getDOFs()==0) return V_Configuration();
00497 V_Configuration q_min(getDOFs());
00498 for(size_t j=0;j<getDOFs();j++) {
00499 q_min[j] = FLT_MAX;
00500 }
00501
00502 for(size_t i=0;i<model.track.pose.size();i++) {
00503 V_Configuration q = getConfiguration(i);
00504 for(size_t j=0;j<getDOFs();j++) {
00505 q_min[j] = MIN( q_min[j], q[j] );
00506 }
00507 }
00508
00509 return q_min;
00510 }
00511
00512 V_Configuration GenericModel::getMaxConfigurationObserved() {
00513 if(getDOFs()==0) return V_Configuration();
00514 V_Configuration q_max(getDOFs());
00515 for(size_t j=0;j<getDOFs();j++) {
00516 q_max[j] = -FLT_MAX;
00517 }
00518
00519 for(size_t i=0;i<model.track.pose.size();i++) {
00520 V_Configuration q = getConfiguration(i);
00521 for(size_t j=0;j<getDOFs();j++) {
00522 q_max[j] = MAX( q_max[j], q[j] );
00523 }
00524 }
00525
00526 return q_max;
00527 }
00528
00529
00530 void GenericModel::projectPoseToConfiguration() {
00531
00532 for(size_t i=0;i<model.track.pose.size();i++) {
00533 V_Configuration q;
00534 q = predictConfiguration( model.track.pose[i] );
00535 setConfiguration(i,q);
00536 }
00537 }
00538
00539 void GenericModel::projectConfigurationToPose() {
00540
00541 model.track.pose_projected.resize(model.track.pose.size());
00542 for(size_t i=0;i<model.track.pose.size();i++) {
00543 V_Configuration q = getConfiguration(i);
00544 model.track.pose_projected[i] = predictPose( q );
00545 }
00546 }
00547
00548 void GenericModel::projectConfigurationToJacobian() {
00549
00550 model.track.pose_projected.resize(model.track.pose.size());
00551 for(size_t i=0;i<model.track.pose.size();i++) {
00552 V_Configuration q = getConfiguration(i);
00553 setJacobian(i, predictJacobian( q ));
00554 }
00555 }
00556
00557 void GenericModel::sampleConfigurationSpace(double resolution) {
00558
00559
00560 model.track.pose_resampled.clear();
00561
00562 if(getDOFs() == 0) {
00563 model.track.pose_resampled.push_back( predictPose(V_Configuration() ) );
00564 return;
00565 }
00566
00567 V_Configuration q_min(getDOFs());
00568 V_Configuration q_max(getDOFs());
00569 getParam("q_min",q_min);
00570 getParam("q_max",q_max);
00571
00572 geometry_msgs::Pose p_min = predictPose( q_min );
00573 geometry_msgs::Pose p_max = predictPose( q_max );
00574 double dist =
00575 (positionToVector(p_min.position) - positionToVector(p_max.position)).length();
00576 if(isnan(dist) || isinf(dist)) return;
00577
00578
00579 for(size_t j=0;j<getDOFs();j++) {
00580 size_t num = MAX(2,1 + (int)( dist /resolution ));
00581 num = MIN(1000,MAX(num,fabs((double)(q_min[0]-q_max[0])/resolution)));
00582 double new_res = (q_max[j] - q_min[j]) / (num-1);
00583
00584 for(size_t i=0;i<num;i++) {
00585 V_Configuration q(getDOFs());
00586 q[j] = q_min[j] + i*new_res;
00587
00588 geometry_msgs::Pose pose = predictPose( q );
00589 model.track.pose_resampled.push_back(pose);
00590 }
00591 }
00592 }
00593
00594 void GenericModel::keepLatestPoseOnly() {
00595 if(model.track.pose.size()<=1) return;
00596 model.track.pose.erase( model.track.pose.begin(), model.track.pose.begin() + (model.track.pose.size() -1) );
00597 for(size_t i = 0; i < model.track.channels.size(); i++) {
00598 model.track.channels[i].values.erase(
00599 model.track.channels[i].values.begin(),
00600 model.track.channels[i].values.begin() + (model.track.channels[i].values.size() -1)
00601 );
00602 }
00603 }
00604
00605 double GenericModel::getInlierLogLikelihood( size_t index ) {
00606 geometry_msgs::Pose &pose_obs = model.track.pose[index];
00607 V_Configuration q_estimated = predictConfiguration(pose_obs);
00608 for(size_t i=0;i<(size_t)q_estimated.rows();i++) {
00609 model.track.channels[channelConfiguration[i]].values[index] = q_estimated[i];
00610 }
00611
00612 geometry_msgs::Pose pose_estimated = predictPose(q_estimated);
00613 model.track.pose_projected[index] = pose_estimated;
00614
00615 tf::Transform diff = poseToTransform(pose_obs).inverseTimes( poseToTransform(pose_estimated) );
00616 double err_position = diff.getOrigin().length();
00617 double err_orientation = fabs(diff.getRotation().getAngle());
00618
00619 double loglikelihood =
00620 - log(2*M_PI * sigma_position*sigma_orientation)
00621 - 0.5*(
00622 ( SQR(err_position) / (SQR(sigma_position)) ) +
00623 ( SQR(err_orientation) / SQR(sigma_orientation)) );
00624 return loglikelihood;
00625 }
00626
00627 double GenericModel::getOutlierLogLikelihood() {
00628
00629 double chi2inv = 1.96;
00630
00631
00632 double err_position = chi2inv * sigma_position;
00633 double err_orientation = chi2inv * sigma_orientation;
00634
00635 double loglikelihood =
00636 - log(2*M_PI * sigma_position*sigma_orientation)
00637 - 0.5*(
00638 ( SQR(err_position) / (SQR(sigma_position)) ) +
00639 ( SQR(err_orientation) / SQR(sigma_orientation)) );
00640
00641 return( loglikelihood );
00642 }
00643
00644 double GenericModel::getLogLikelihoodForPoseIndex(size_t index) {
00645
00646
00647 double inlierLikelihood = getInlierLogLikelihood(index);
00648 double outlierLikelihood = getOutlierLogLikelihood();
00649
00650
00651 model.track.channels[channelInlierLogLikelihood].values[index] = inlierLikelihood;
00652 double pi = (1-outlier_ratio) * exp( inlierLikelihood );
00653 double po = outlier_ratio * exp( outlierLikelihood );
00654 model.track.channels[channelOutlier].values[index] = po / (pi+po);
00655 double p = (log(exp(inlierLikelihood) + exp(outlierLikelihood)));
00656 model.track.channels[channelLogLikelihood].values[index] = p;
00657 return p;
00658
00659
00660
00661
00662
00663
00664
00665
00666 }
00667
00668 double GenericModel::getLogLikelihood(bool estimate_outlier_ratio) {
00669 model.track.pose_projected.resize(model.track.pose.size());
00670
00671 model.track.channels[channelInlierLogLikelihood].values.resize(model.track.pose.size());
00672 model.track.channels[channelOutlier].values.resize(model.track.pose.size());
00673 model.track.channels[channelLogLikelihood].values.resize(model.track.pose.size());
00674 for(size_t i=0;i<(size_t)getDOFs();i++) {
00675 model.track.channels[channelConfiguration[i]].values.resize(model.track.pose.size());
00676 }
00677
00678 double sum_likelihood = 0;
00679 size_t n = getSamples();
00680 if(estimate_outlier_ratio) {
00681 outlier_ratio =0.5;
00682 for(size_t i=0;i<n;i++) {
00683 model.track.channels[channelOutlier].values[i] = 0.5;
00684 }
00685
00686 int iter = 0;
00687 double diff = 0;
00688 do{
00689 sum_likelihood = 0;
00690 for(size_t i=0;i<n;i++) {
00691 sum_likelihood += getLogLikelihoodForPoseIndex(i);
00692 }
00693
00694 double outlier_ratio_new = 0;
00695 for(size_t i=0;i<n;i++) {
00696 outlier_ratio_new += model.track.channels[channelOutlier].values[i]/n;
00697 }
00698 diff = fabs(outlier_ratio - outlier_ratio_new);
00699 iter++;
00700 outlier_ratio = outlier_ratio_new;
00701
00702 } while( diff>0.01 && iter<10 );
00703 } else {
00704 for(size_t i=0;i<n;i++) {
00705 sum_likelihood += getLogLikelihoodForPoseIndex(i);
00706 }
00707 }
00708 sum_likelihood += - prior_outlier_ratio * outlier_ratio * n;
00709 return sum_likelihood;
00710 }
00711
00712 bool GenericModel::guessParameters() {
00713
00714 return false;
00715 }
00716
00717 bool GenericModel::sampleConsensus() {
00718
00719 writeParamsToModel();
00720 vector<articulation_msgs::ParamMsg> bestParams = model.params;
00721 double bestLikelihood = -DBL_MAX;
00722 bool goodGuess = false;
00723 for(size_t it=0;it<sac_iterations;it++) {
00724 if(!guessParameters()) continue;
00725 goodGuess = true;
00726 double likelihood = getLogLikelihood(true);
00727
00728 if(bestLikelihood < likelihood) {
00729 writeParamsToModel();
00730 bestParams = model.params;
00731 bestLikelihood = likelihood;
00732 }
00733 }
00734
00735 model.params = bestParams;
00736 readParamsFromModel();
00737
00738 return goodGuess;
00739 }
00740
00741 double
00742 my_f (const gsl_vector *v, void *params)
00743 {
00744 GenericModel *p = (GenericModel *)params;
00745
00746 vector<double> delta( v->size );
00747 for(size_t i=0;i<v->size;i++) {
00748 delta[i] = gsl_vector_get (v, i);
00749
00750 }
00751
00752 p->model.params = p->params_initial;
00753 p->readParamsFromModel();
00754 p->updateParameters(delta);
00755 p->writeParamsToModel();
00756 double likelihood = p->getLogLikelihood(true);
00757
00758 return -likelihood;
00759 }
00760
00761
00762 void
00763 my_df (const gsl_vector *v, void *params,
00764 gsl_vector *df)
00765 {
00766 double likelihood = my_f(v,params);
00767
00768 gsl_vector * v_delta =gsl_vector_alloc (v->size);
00769
00770 double DELTA = 1e-3;
00771 for(size_t i=0;i<v->size;i++) {
00772 v_delta = gsl_vector_alloc (v->size);
00773 gsl_vector_memcpy(v_delta,v);
00774 gsl_vector_set(v_delta, i,gsl_vector_get(v, i)+DELTA);
00775
00776 double likelihood_delta = my_f(v_delta,params);
00777 gsl_vector_set(df, i,(likelihood_delta-likelihood)/DELTA);
00778 }
00779 gsl_vector_free (v_delta);
00780 }
00781
00782
00783 void
00784 my_fdf (const gsl_vector *x, void *params,
00785 double *f, gsl_vector *df)
00786 {
00787 *f = my_f(x, params);
00788 my_df(x, params, df);
00789 }
00790
00791 bool GenericModel::optimizeParameters() {
00792
00793
00794
00795 writeParamsToModel();
00796 params_initial = model.params;
00797
00798
00799 size_t iter = 0;
00800 int status;
00801
00802 const gsl_multimin_fdfminimizer_type *T;
00803 gsl_multimin_fdfminimizer *s;
00804
00805 gsl_vector *x;
00806 gsl_multimin_function_fdf my_func;
00807
00808 my_func.n = (int)complexity;
00809 my_func.f = my_f;
00810 my_func.df = my_df;
00811 my_func.fdf = my_fdf;
00812 my_func.params = this;
00813
00814 x = gsl_vector_alloc ((int)complexity);
00815 gsl_vector_set_zero (x);
00816
00817
00818 T = gsl_multimin_fdfminimizer_vector_bfgs2;
00819 s = gsl_multimin_fdfminimizer_alloc (T, (int)complexity);
00820
00821 gsl_multimin_fdfminimizer_set (s, &my_func, x, 0.01, 0.1);
00822
00823
00824
00825
00826
00827
00828
00829
00830 if(optimizer_iterations>0) do
00831 {
00832 iter++;
00833
00834 status = gsl_multimin_fdfminimizer_iterate (s);
00835
00836 if (status)
00837 break;
00838
00839 status = gsl_multimin_test_gradient (s->gradient, 1e-1);
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849 }
00850 while (status == GSL_CONTINUE && iter < optimizer_iterations);
00851
00852
00853
00854
00855
00856
00857
00858 gsl_multimin_fdfminimizer_free (s);
00859 gsl_vector_free (x);
00860
00861 if(!fitMinMaxConfigurations())
00862 return false;
00863
00864
00865
00866
00867
00868
00869
00870 return true;
00871 }
00872
00873
00874 void GenericModel::updateParameters(std::vector<double> delta) {
00875 }
00876
00877 bool GenericModel::normalizeParameters() {
00878 return true;
00879 }
00880
00881 }