structure_learner_base.cpp
Go to the documentation of this file.
00001 /*
00002  * structure_learner_base.cpp
00003  *
00004  *  Created on: Jul 25, 2010
00005  *      Author: sturm
00006  */
00007 
00008 #include "structure_learner_base.h"
00009 #include "utils.h"
00010 
00011 
00012 KinematicStructureLearner::KinematicStructureLearner():
00013 nh(),nh_local("~") {
00014         KinematicParams::LoadParams(nh_local);
00015 
00016         model_pub = nh.advertise<ModelMsg> ("model", 0);
00017         marker_pub = nh.advertise<visualization_msgs::Marker> ("structure", 0);
00018 
00019 //      ros::Subscriber pose_sub = nh.subscribe("markers", 100, poseCallback);
00020         pose_sub1 = nh.subscribe("/marker/1", 5, &KinematicStructureLearner::poseCallback1,this);
00021         pose_sub2 = nh.subscribe("/marker/2", 5, &KinematicStructureLearner::poseCallback2,this);
00022         pose_sub3 = nh.subscribe("/marker/3", 5, &KinematicStructureLearner::poseCallback3,this);
00023         pose_sub4 = nh.subscribe("/marker/4", 5, &KinematicStructureLearner::poseCallback4,this);
00024 }
00025 
00026 
00027 KinematicGraph KinematicStructureLearner::getSpanningTree(bool increasing) {
00028         //http://en.wikipedia.org/wiki/Prim%27s_algorithm
00029         map< int, map<int,GenericModelPtr> > E = models;
00030         vector<int> V;
00031         for(map< int, map<int,GenericModelPtr> >::iterator i=E.begin();
00032                         i != E.end();i++) {
00033                 if(!i->second.begin()->second) continue;
00034                 V.push_back(i->first);
00035         }
00036         vector<int> V_new;
00037         KinematicGraph E_new;
00038 
00039         if(V.size()==0) {
00040                 ROS_INFO_STREAM("V.size()==0: empty graph");
00041                 return KinematicGraph();
00042         }
00043 
00044         V_new.push_back( V[0] );
00045         while(V_new.size() != V.size()) {
00046                 map<double, pair< pair<int,int>,GenericModelPtr> > E_weighted;
00047 
00048                 // find all possible edges
00049                 for(map< int, map<int,GenericModelPtr> >::iterator i=E.begin();
00050                                 i != E.end();i++) {
00051                         // i has to be in V_new
00052                         vector< int >::iterator result = find( V_new.begin(), V_new.end(), i->first );
00053                         if (result == V_new.end()) {
00054                                 continue;
00055                         }
00056                         for(map<int,GenericModelPtr>::iterator j=i->second.begin();
00057                                 j != i->second.end();j++) {
00058 
00059                                 if(increasing && i->first >= j->first) continue;
00060 
00061                                 if(!j->second) continue;
00062 
00063                                 // j not yet in V_new
00064                                 vector< int >::iterator result = find( V_new.begin(), V_new.end(), j->first );
00065                                 if (result == V_new.end()) {
00066                                         E_weighted[ j->second->getBIC() ] =
00067                                                         pair< pair<int,int>,GenericModelPtr>(
00068                                                                         pair<int,int>(i->first,j->first),j->second );
00069                                 }
00070                         }
00071                 }
00072 
00073                 if(E_weighted.size()==0) {
00074                         break; // done
00075                 }
00076 
00077                 V_new.push_back( E_weighted.begin()->second.first.second);
00078                 E_new.push_back( E_weighted.begin()->second );
00079         }
00080 
00081         if(V_new.size() != V.size()) {
00082                 ROS_INFO_STREAM("V.size()!=V_new.size(): disconnected subset exists");
00083                 return KinematicGraph();
00084         }
00085         E_new.DOF = E_new.getNominalDOFs();
00086         E_new.evaluate(intersectionOfStamps(),*this,*this);
00087         return(E_new);
00088 }
00089 
00090 void KinematicStructureLearner::sendModels(KinematicGraph E_new) {
00091         stringstream s;
00092         size_t id =0;
00093         for(KinematicGraphType::iterator
00094                         it = E_new.begin(); it != E_new.end();it++) {
00095                 s <<" ["<<it->first.first<<","<<it->first.second<<":"<<
00096                                 it->second->getModelName()<<"/"<<it->second->getSamples()<<"]";
00097 
00098                 it->second->projectConfigurationToPose();
00099                 it->second->sampleConfigurationSpace( 0.1 );
00100                 ModelMsg msg = it->second->getModel();
00101                 msg.track.id = id;
00102                 msg.id = id;
00103                 msg.header.frame_id = boost::str(boost::format( "/pred/%1%") % it->first.first );
00104                 model_pub.publish(msg);
00105                 id++;
00106 //              it->second->model.track.pose_projected.back()
00107         }
00108         static size_t old_ids = 0;
00109         size_t new_ids = id;
00110         while(id<old_ids) {
00111                 ModelMsg msg;
00112                 msg.track.id = id;
00113                 msg.id = id;
00114                 msg.header.frame_id = "/pred/1";
00115                 model_pub.publish(msg);
00116                 id++;
00117         }
00118         old_ids = new_ids;
00119 
00120         ROS_INFO_STREAM("tree: "<<s.str());
00121 }
00122 
00123 void KinematicStructureLearner::sendTreeTransforms(KinematicGraph graph) {
00124         if (graph.size() == 0)
00125                 return;
00126 
00127         double latestTimestamp = stampedMarker.rbegin()->first;
00128         PoseMap observation = getObservation(latestTimestamp);
00129         PoseMap predictionEmpty = getObservation(intersectionOfStamps().back());
00130         PoseMap prediction = graph.getPrediction(intersectionOfStamps().back(),observation,predictionEmpty,*this,*this);
00131 
00132         // send transform for root node
00133         static tf::TransformBroadcaster br;
00134         const PoseStamped &latestPose =
00135                         stampedMarker[latestTimestamp].begin()->second->pose;
00136         for (PoseMap::iterator it = prediction.begin(); it != prediction.end(); it++) {
00137                 br.sendTransform(tf::StampedTransform(poseToTransform(it->second),
00138                                 latestPose.header.stamp, "/camera", boost::str(boost::format(
00139                                                 "/pred/%1%") % it->first)));
00140         }
00141 }
00142 
00143 void KinematicStructureLearner::saveGraphEval() {
00144         ofstream in_file;
00145         string pid = boost::str(boost::format( "%1%") % getpid() );
00146         in_file.open ((string("")+"graph_eval"+pid+".gnuplot").c_str());
00147         in_file.precision(10);
00148         in_file<<"set xlabel \"number of samples\""<<endl;
00149         in_file<<"set ylabel \"BIC\""<<endl;
00150         in_file<<"set key top left"<<endl;
00151         in_file<<"set output \"graph_eval"<<pid<<".eps\""<<endl;
00152         in_file<<"set terminal postscript eps enh color \"Times\""<<endl;
00153         in_file<<"set size 1.0,1.0"<<endl;
00154         in_file<<"plot \\"<<endl;
00155 
00156 //      double minBIC = DBL_MAX;
00157 //      for(std::map< std::string, EvalStruct>::iterator it=evalGraph.begin();it!=evalGraph.end();it++) {
00158 //              if(it->second.second.size()==0) continue;
00159 //              if(minBIC > it->second.second.rbegin()->second)
00160 //                      minBIC = it->second.second.rbegin()->second;
00161 //      }
00162 
00163         // compute segments
00164         map<int,int> x;
00165         for(std::map< std::string, EvalStruct>::iterator it=evalGraph.begin();it!=evalGraph.end();it++) {
00166                 for(std::map<int,EvalStampStruct>::iterator j=it->second.stampEval.begin();j!=it->second.stampEval.end();j++) {
00167                         x[j->first] = j->first;
00168                 }
00169         }
00170         if(x.size()==0) return;
00171         map<int,int>::iterator j=x.begin(); j++;
00172         map<int,int>::iterator i=x.begin();
00173         while(j!=x.end()) {
00174                 j->second = i->first;
00175                 i++;
00176                 j++;
00177         }
00178 
00179 //      cout << endl;
00180         for(std::map< std::string, EvalStruct>::iterator it=evalGraph.begin();it!=evalGraph.end();it++) {
00181                 int segment = -1;
00182                 int lastX = -1;
00183 //              cout <<"segmenting "<<it->first<<":"<<endl;
00184                 for(std::map<int,EvalStampStruct>::iterator j=it->second.stampEval.begin();j!=it->second.stampEval.end();j++) {
00185                         if(lastX != x[j->first]) {
00186                                 segment++;
00187                         }
00188 //                      cout <<"x="<<j->first <<" segment="<<segment << endl;;
00189                         lastX = j->first;
00190                         j->second.segment = segment;
00191                         j->second.segment = 0;
00192                 }
00193                 it->second.segments = segment+1;
00194                 it->second.segments = 1;
00195 //              cout <<"-- segments="<<it->second.segments<<endl;
00196         }
00197 
00198         bool first = true;
00199         int lt = 1;
00200         for(std::map< std::string, EvalStruct>::iterator it=evalGraph.begin();it!=evalGraph.end();it++) {
00201                 if(it->second.stampEval.size()==0) continue;
00202                 if(it->second.bestGraphOnce) continue; // skip all named graphs
00203                 for(int i=0;i<it->second.segments;i++) {
00204                         if(first) first = false; else in_file << ", \\"<< endl;
00205                         in_file<<"'-' with lines ";
00206                         in_file <<" lw 1 lt "<<lt<<" lc rgb '#7f7f7f' t''";
00207                 }
00208         }
00209         if(!first) lt++;
00210         for(std::map< std::string, EvalStruct>::iterator it=evalGraph.begin();it!=evalGraph.end();it++) {
00211                 if(it->second.stampEval.size()==0) continue;
00212                 if(!it->second.bestGraphOnce) continue; // skip all unnamed graphs
00213                 for(int i=0;i<it->second.segments;i++) {
00214                         if(first) first = false; else in_file << ", \\"<< endl;
00215                         in_file<<"'-' with lines lt "<<lt;
00216                         lt++;
00217                         if(i==0) {
00218                                 if(it->second.stampEval.rbegin()->second.bestGraph) {
00219                                         in_file <<" lw 5 t'"<<it->first<<"*'";
00220                                 } else {
00221                                         in_file <<" lw 3 t'"<<it->first<<"'";
00222                                 }
00223                         } else {
00224                                 if(it->second.stampEval.rbegin()->second.bestGraph) {
00225                                         in_file <<" lw 5 t''";
00226                                 } else {
00227                                         in_file <<" lw 3 t''";
00228                                 }
00229                         }
00230                 }
00231         }
00232         in_file<<endl<<endl;
00233         for(std::map< std::string, EvalStruct>::iterator it=evalGraph.begin();it!=evalGraph.end();it++) {
00234                 if(it->second.stampEval.size()==0) continue;
00235                 if(it->second.bestGraphOnce) continue;
00236                 int lastSeg = 0;
00237                 for( std::map<int,EvalStampStruct>::iterator j = it->second.stampEval.begin();j!=it->second.stampEval.end();j++ ) {
00238                         in_file<< j->first <<"\t"<<j->second.BIC<<endl;
00239                         if(lastSeg != j->second.segment) {
00240                                 in_file<<"e"<<endl;
00241                                 lastSeg = j->second.segment;
00242                         }
00243                 }
00244                 in_file<<"e"<<endl;
00245         }
00246         for(std::map< std::string, EvalStruct>::iterator  it=evalGraph.begin();it!=evalGraph.end();it++) {
00247                 if(it->second.stampEval.size()==0) continue;
00248                 if(!it->second.bestGraphOnce) continue;
00249                 int lastSeg = 0;
00250                 for( std::map<int,EvalStampStruct>::iterator  j = it->second.stampEval.begin();j!=it->second.stampEval.end();j++ ) {
00251                         in_file<< j->first <<"\t"<<j->second.BIC <<endl;
00252                         if(lastSeg != j->second.segment) {
00253                                 in_file<<"e"<<endl;
00254                                 lastSeg = j->second.segment;
00255                         }
00256                 }
00257                 in_file<<"e"<<endl;
00258         }
00259 
00260         in_file.close();
00261 }
00262 
00263 void saveIntDouble(ofstream &in_file,std::map< int, double> values) {
00264         for(std::map< int, double>::iterator i=values.begin();i!=values.end();i++) {
00265                 in_file << i->first << " " << i->second<<endl;
00266         }
00267         in_file<<"e"<<endl;
00268 }
00269 
00270 void KinematicStructureLearner::saveBICEval() {
00271         ofstream in_file;
00272         string pid = boost::str(boost::format( "%1%") % getpid() );
00273         in_file.open ((string("")+"bic_eval"+pid+".gnuplot").c_str());
00274         in_file.precision(10);
00275         in_file<<"set xlabel \"number of samples\""<<endl;
00276         in_file<<"set ylabel \"BIC\""<<endl;
00277         in_file<<"set key top left"<<endl;
00278         in_file<<"set output \"bic_eval"<<pid<<".eps\""<<endl;
00279         in_file<<"set terminal postscript eps enh color \"Times\""<<endl;
00280         in_file<<"set size 1.0,1.0"<<endl;
00281         in_file<<"plot \\"<<endl;
00282 
00283         for(std::map< std::string, EvalStruct>::iterator it=evalGraph.begin();it!=evalGraph.end();it++) {
00284                 if(it->second.stampEval.size()==0) continue;
00285                 in_file<<"'-' with lines  lw 1 lt 1 lc rgb '#7f7f7f' t'', \\"<<endl;
00286         }
00287 
00288         in_file <<" '-' with lines lw 3 lt 1 lc rgb '#0000ff' t'spanning tree', \\"<<endl;
00289         in_file <<" '-' with lines lw 3 lt 2 lc rgb '#00ff00' t'greedy graph search', \\"<<endl;
00290         in_file <<" '-' with lines lw 3 lt 3 lc rgb '#ff0000' t'brute force graph search';"<<endl;
00291 
00292         for(std::map< std::string, EvalStruct>::iterator it=evalGraph.begin();it!=evalGraph.end();it++) {
00293                 for( std::map<int,EvalStampStruct>::iterator j = it->second.stampEval.begin();j!=it->second.stampEval.end();j++ ) {
00294                         in_file<< j->first <<"\t"<<j->second.BIC<<endl;
00295                 }
00296                 in_file<<"e"<<endl;
00297         }
00298 
00299         saveIntDouble(in_file,evalTreeBIC);
00300         saveIntDouble(in_file,evalFastBIC);
00301         saveIntDouble(in_file,evalGraphBIC);
00302 
00303 
00304         in_file.close();
00305 }
00306 
00307 void KinematicStructureLearner::saveRuntimeEval() {
00308         ofstream in_file;
00309         string pid = boost::str(boost::format( "%1%") % getpid() );
00310         in_file.open ((string("")+"runtime_eval"+pid+".gnuplot").c_str());
00311         in_file.precision(10);
00312         in_file<<"set xlabel \"number of samples\""<<endl;
00313         in_file<<"set ylabel \"time [s]\""<<endl;
00314         in_file<<"set key top left"<<endl;
00315         in_file<<"set output \"runtime_eval"<<pid<<".eps\""<<endl;
00316         in_file<<"set terminal postscript eps enh color \"Times\""<<endl;
00317         in_file<<"set size 1.0,1.0"<<endl;
00318         in_file<<"plot \\"<<endl;
00319 
00320         in_file <<" '-' with lines lw 3 lt 4 lc rgb '#000000' t'local models', \\"<<endl;
00321         in_file <<" '-' with lines lw 3 lt 1 lc rgb '#0000ff' t'spanning tree', \\"<<endl;
00322         in_file <<" '-' with lines lw 3 lt 2 lc rgb '#00ff00' t'greedy graph search', \\"<<endl;
00323         in_file <<" '-' with lines lw 3 lt 3 lc rgb '#ff0000' t'brute force graph search';"<<endl;
00324 
00325         saveIntDouble(in_file,evalModelsRuntime);
00326         saveIntDouble(in_file,evalTreeRuntime);
00327         saveIntDouble(in_file,evalFastRuntime);
00328         saveIntDouble(in_file,evalGraphRuntime);
00329 
00330         in_file.close();
00331 }
00332 
00333 void KinematicStructureLearner::saveDOFLinkEval() {
00334         ofstream in_file;
00335         string pid = boost::str(boost::format( "%1%") % getpid() );
00336         in_file.open ((string("")+"doflink_eval"+pid+".gnuplot").c_str());
00337         in_file.precision(10);
00338         in_file<<"set xlabel \"number of samples\""<<endl;
00339         in_file<<"set ylabel \"time [s]\""<<endl;
00340         in_file<<"set key top left"<<endl;
00341         in_file<<"set output \"doflink_eval"<<pid<<".eps\""<<endl;
00342         in_file<<"set terminal postscript eps enh color \"Times\""<<endl;
00343         in_file<<"set size 1.0,1.0"<<endl;
00344         in_file<<"plot \\"<<endl;
00345 
00346         in_file <<" '-' with lines lw 3 lt 4 lc rgb '#000000' t'DOFs', \\"<<endl;
00347         in_file <<" '-' with lines lw 3 lt 1 lc rgb '#0000ff' t'Links'"<<endl;
00348 
00349         saveIntDouble(in_file,evalDOF);
00350         saveIntDouble(in_file,evalLinks);
00351 
00352         in_file.close();
00353 }
00354 
00355 
00356 void KinematicStructureLearner::sendStructureVisualization(KinematicGraph graph) {
00357         // send transform for root node
00358         if(!graph.size()) return;
00359 
00360         std::vector<double> stamps = intersectionOfStamps();
00361         PoseMap observationMarkers = getObservation(stamps.back());
00362         PoseMap predictionEmpty = getObservation(intersectionOfStamps().back());
00363         PoseMap predictedMarkers = graph.getPrediction(stamps.back(),observationMarkers,predictionEmpty,*this,*this);
00364 
00365         static tf::TransformListener listener;
00366 
00367     visualization_msgs::Marker marker;
00368     marker.header.frame_id = "/camera";
00369     marker.header.stamp = ros::Time::now();
00370     marker.ns = "structure";
00371     marker.id = 0;
00372     marker.type = visualization_msgs::Marker::LINE_LIST;
00373     marker.action = visualization_msgs::Marker::ADD;
00374     marker.pose.orientation.w = 1.0;
00375     marker.scale.x = 0.005;
00376     marker.scale.y = 0.005;
00377     marker.scale.z = 0.005;
00378     marker.color.r = 0.0f;
00379     marker.color.g = 0.0f;
00380     marker.color.b = 1.0f;
00381     marker.color.a = 1.0;
00382     marker.lifetime = ros::Duration();
00383 
00384     visualization_msgs::Marker text_marker = marker;
00385     text_marker.type = visualization_msgs::Marker::TEXT_VIEW_FACING;
00386     text_marker.ns = "model_names";
00387     text_marker.scale.x = 0.035;
00388     text_marker.scale.y = 0.035;
00389     text_marker.scale.z = 0.035;
00390 
00391     static int old_marker_id = 0;
00392     static int old_text_marker_id = 0;
00393     int model_count=0;
00394         for(KinematicGraphType::iterator
00395                         it = graph.begin(); it != graph.end();it++)
00396         {
00397                 double model_r = model_count / (double)graph.size();
00398 //              if(it->first.first > it->first.second) continue;
00399                 if(it->second->model.track.pose_projected.size()==0) continue;
00400 
00401                 if(it->second->getModelName() == "rigid") {
00402                         marker.color = HSV_to_RGB(0.0,0.0,model_r/3 + 0.3);
00403                     marker.id++;
00404                         marker.points.clear();
00405                         marker.points.push_back(predictedMarkers[it->first.first ].position);
00406                         marker.points.push_back(predictedMarkers[it->first.second].position);
00407                     marker_pub.publish(marker);
00408 
00409                 } else
00410                         if(it->second->getModelName() == "prismatic") {
00411                                 marker.color = HSV_to_RGB((model_r-0.5)/6 + 0.15,1.0,1.0);
00412                             marker.id++;
00413                                 marker.points.clear();
00414                                 marker.points.push_back(predictedMarkers[it->first.first ].position);
00415                                 marker.points.push_back(predictedMarkers[it->first.second].position);
00416                             marker_pub.publish(marker);
00417                         } else
00418                                 if(it->second->getModelName() == "rotational") {
00419                                         geometry_msgs::Point rot_center = vectorToPosition( poseToTransform(predictedMarkers[it->first.first ])*
00420                                                         boost::static_pointer_cast<RotationalModel>(it->second)->rot_center);
00421 
00422                                         marker.color = HSV_to_RGB((model_r-0.5)/6 +  0.66,0.5,0.5);
00423 
00424                                     marker.id++;
00425                                         marker.points.clear();
00426                                         marker.points.push_back(predictedMarkers[it->first.first ].position);
00427                                         marker.points.push_back(rot_center );
00428                                     marker_pub.publish(marker);
00429 
00430                                         marker.color = HSV_to_RGB((model_r-0.5)/6 +  0.66,1.0,1.0);
00431 
00432                                     marker.id++;
00433                                         marker.points.clear();
00434                                         marker.points.push_back(rot_center );
00435                                         marker.points.push_back(predictedMarkers[it->first.second].position);
00436                                     marker_pub.publish(marker);
00437 
00438                                 } else
00439                                         if(it->second->getModelName() == "pca_gp") {
00440                                                 marker.color = HSV_to_RGB((model_r-0.5)/6 +  0.33,1.0,1.0);
00441                                             marker.id++;
00442                                                 marker.points.clear();
00443                                                 marker.points.push_back(predictedMarkers[it->first.first ].position);
00444                                                 marker.points.push_back(predictedMarkers[it->first.second].position);
00445                                             marker_pub.publish(marker);
00446                                         } else
00447                                         {
00448                                                 marker.color = HSV_to_RGB(0,0,0);
00449                                             marker.id++;
00450                                                 marker.points.clear();
00451                                                 marker.points.push_back(predictedMarkers[it->first.first ].position);
00452                                                 marker.points.push_back(predictedMarkers[it->first.second].position);
00453                                             marker_pub.publish(marker);
00454                                         }
00455 
00456 
00457             text_marker.id++;
00458             text_marker.text = it->second->getModelName();
00459             text_marker.pose.position.x = (predictedMarkers[it->first.first ].position.x + predictedMarkers[it->first.second ].position.x)/2;
00460             text_marker.pose.position.y = (predictedMarkers[it->first.first ].position.y + predictedMarkers[it->first.second ].position.y)/2;
00461             text_marker.pose.position.z = (predictedMarkers[it->first.first ].position.z + predictedMarkers[it->first.second ].position.z)/2;
00462             text_marker.color = marker.color;
00463             marker_pub.publish(text_marker);
00464 
00465             model_count++;
00466         }
00467 
00468     text_marker.pose.position.x = 0;
00469     text_marker.pose.position.y = +0.16;
00470     text_marker.pose.position.z = 1;
00471     text_marker.color.r=1.0;
00472     text_marker.color.g=1.0;
00473     text_marker.color.b=1.0;
00474     text_marker.scale.x = 0.025;
00475     text_marker.scale.y = 0.025;
00476     text_marker.scale.z = 0.025;
00477     text_marker.text = boost::str(boost::format( "selected model: %d DOF, %d links") % graph.DOF % graph.size()  );
00478     text_marker.id++;
00479     marker_pub.publish(text_marker);
00480     text_marker.pose.position.y += 0.028;
00481 
00482     text_marker.text = boost::str(boost::format( "global error: %0.3fm, %0.3frad (%d samples)") % graph.avg_pos_err % graph.avg_orient_err % intersectionOfStamps().size());
00483     text_marker.id++;
00484     marker_pub.publish(text_marker);
00485     text_marker.pose.position.y += 0.028;
00486 
00487     text_marker.scale.x = 0.02;
00488     text_marker.scale.y = 0.02;
00489     text_marker.scale.z = 0.02;
00490     text_marker.text = boost::str(boost::format( "kinematic structure: %s") % graph.getTreeName(true,true,false) );
00491     text_marker.id++;
00492     marker_pub.publish(text_marker);
00493 
00494 
00495         int new_marker_id = marker.id;
00496         int new_text_marker_id = text_marker.id;
00497         while(marker.id < old_marker_id) {
00498                 marker.id++;
00499                 marker.action = visualization_msgs::Marker::DELETE;
00500             marker_pub.publish(marker);
00501         }
00502 
00503         while(text_marker.id < old_text_marker_id) {
00504                 text_marker.id++;
00505                 text_marker.action = visualization_msgs::Marker::DELETE;
00506                 marker_pub.publish(text_marker);
00507         }
00508         old_marker_id = new_marker_id;
00509         old_text_marker_id = new_text_marker_id;
00510 
00511 }
00512 
00513 std::vector<double>  KinematicStructureLearner::downsampleStamps(std::vector<double> vec,size_t num) {
00514         std::vector<int> idx;
00515         for(size_t i=0;i<vec.size();i++) idx.push_back(i);
00516         random_shuffle( idx.begin(), idx.end() );
00517         if(num<vec.size())
00518                 idx.erase(idx.begin()+num,idx.end());
00519         sort(idx.begin(),idx.end());
00520         std::vector<double> res;
00521         for(size_t i=0;i<vec.size() && i<num;i++)
00522                 res.push_back( vec[ idx[i] ] );
00523         return(res);
00524 }
00525 
00526 int dist(string a,string b) {
00527         int d = fabs(a.length()-b.length());
00528         for(size_t i=0;i<a.length() && i<b.length();i++) {
00529                 if(a[i] != b[i]) d++;
00530         }
00531         return( d );
00532 }
00533 
00534 void KinematicStructureLearner::addPreviousGraphs() {
00535         cout <<"adding previous graphs, n="<<previousGraphs.size()<<endl;
00536 
00537         for(map< string, KinematicGraph >::iterator it= previousGraphs.begin();it!=previousGraphs.end();it++) {
00538                 if(graphMap.find(it->first) != graphMap.end()) continue;
00539 
00540                 KinematicGraph graph(it->second,true);
00541                 bool skip_this = false;
00542                 for(KinematicGraph::iterator j=graph.begin();j!=graph.end();j++) {
00543                         bool updated = false;
00544                         for(std::vector<articulation_models::GenericModelPtr>::iterator
00545                                         k=models_all[j->first.first][j->first.second].begin();k!=models_all[j->first.first][j->first.second].end();k++) {
00546                                 if(k->get()->getModelName() == j->second->getModelName()) {
00547                                         j->second = *k; // update model pointer
00548                                         updated = true;
00549                                         break;
00550                                 }
00551                         }
00552                         if(!updated) {
00553                                 skip_this = true;
00554                                 cout <<"skipping model because not all models updatable:"<<graph.getTreeName(true,false,true)<<endl;
00555                                 break;
00556                         }
00557                 }
00558                 if(!skip_this) {
00559                         graphMap[ it->first ] = graph;
00560                         cout <<"adding previous "<<graph.getTreeName(true,false,true)<<endl;
00561                 }
00562         }
00563 }
00564 
00565 void KinematicStructureLearner::selectSceneModel() {
00566         std::vector<double> stamps= intersectionOfStamps();
00567 
00568         if(stamps.size()==0) {
00569                 cout <<"no intersecting timestamps.."<<endl;
00570                 return;
00571         }
00572 
00573         if(full_eval=="tree") {
00574                 evalTree();
00575         }
00576 
00577         if(full_eval=="full") {
00578                 evalFull();
00579         } else
00580 
00581         if(full_eval=="fast") {
00582                 // initialize possible graphs
00583                 evalFast(true);
00584         } else {
00585                 cerr <<"warning!!! unknown evaluation type: full_eval="<<full_eval<<endl;
00586         }
00587 }
00588 
00589 void KinematicStructureLearner::evalTree() {
00590         ros::Time t = ros::Time::now();
00591 
00592         std::vector<double> stamps= intersectionOfStamps();
00593         currentGraph = getSpanningTree(true);
00594         currentGraph.evaluate(stamps,*this,*this);
00595         evalTreeRuntime[stamps.size()] = (ros::Time::now() - t).toSec();
00596 
00597         evalDOF[stamps.size()] = currentGraph.DOF;
00598         evalLinks[stamps.size()] = currentGraph.size();
00599 
00600         sendTreeTransforms(currentGraph);
00601 
00602         evalGraph[currentGraph.getTreeName(true,false,true)].stampEval[stamps.size()].bestTree = true;
00603         evalGraph[currentGraph.getTreeName(true,false,true)].stampEval[stamps.size()].BIC = currentGraph.BIC;
00604         evalTreeBIC[stamps.size()] = currentGraph.BIC;
00605         saveGraphEval();
00606         saveBICEval();
00607         saveRuntimeEval();
00608 
00609 }
00610 
00611 void KinematicStructureLearner::evalFull() {
00612         ros::Time t = ros::Time::now();
00613 
00614         std::vector<double> stamps= intersectionOfStamps();
00615         KinematicGraph tree;
00616 
00617         KinematicGraph bestGraph;
00618         enumerateGraphs();
00619         addPreviousGraphs();
00620 
00621         for(map< string, KinematicGraph >::iterator  j=graphMap.begin();j!=graphMap.end();j++) {
00622                 KinematicGraph& copyOfTree = j->second;
00623                 string gname_short = copyOfTree.getTreeName(false,false,true);
00624                 string gname_models = copyOfTree.getTreeName(true,false,true);
00625                 string gname_models_samples = copyOfTree.getTreeName(true,false,true);
00626                 copyOfTree.evaluate(stamps,*this,*this);
00627                 if(evalGraph.find(gname_models) == evalGraph.end()) {
00628 
00629 
00630                         // spawn this new model from somewhere
00631                         // find a model that has the previous time slice defined
00632                         string previous_model;
00633                         int previous_time=0;
00634                         for(std::map< std::string, EvalStruct>::iterator k=evalGraph.begin();k != evalGraph.end();k++) {
00635                                 int t = 0;
00636                                 for(std::map<int,EvalStampStruct>::iterator l=k->second.stampEval.begin();l!=k->second.stampEval.end();l++) {
00637                                         if(l->first > t && l->first < (int)stamps.size())
00638                                                 t = l->first;
00639                                 }
00640                                 if( k->second.stampEval.find(t) != k->second.stampEval.end() && (t>previous_time || dist(previous_model,gname_models) > dist(k->first,gname_models)) ) {
00641                                         previous_model = k->first;
00642                                         previous_time = t;
00643                                 }
00644                         }
00645                         if(previous_model.length()) {
00646                                 evalGraph[gname_models].stampEval[previous_time] = evalGraph[previous_model].stampEval[previous_time];
00647                         }
00648 
00649                 }
00650                 evalGraph[gname_models].stampEval[stamps.size()].BIC = copyOfTree.BIC;
00651 
00652                 if(copyOfTree.BIC < bestGraph.BIC) {
00653                         bestGraph = copyOfTree;
00654                 }
00655                 cout <<"adding "<<copyOfTree.getTreeName(true,true,true)<<endl;;
00656 
00657                 // should we finish?
00658                 static ros::NodeHandle n;
00659                 if(!n.ok()) return;
00660 
00661         }
00662 
00663         currentGraph = bestGraph;
00664         if(currentGraph.DOF != -1) {
00665                 string gname_models = currentGraph.getTreeName(true,false,true);
00666                 evalGraph[gname_models].stampEval[stamps.size()].BIC = currentGraph.BIC;
00667                 cout <<"*** STORING evalGraph"<<gname_models<<" bic" <<currentGraph.BIC<<endl;
00668                 evalGraph[gname_models].stampEval[stamps.size()].bestGraph = true;
00669                 evalGraph[gname_models].bestGraphOnce= true;
00670 
00671                 evalDOF[stamps.size()] = currentGraph.DOF;
00672                 evalLinks[stamps.size()] = currentGraph.size();
00673 
00674                 previousGraphs[currentGraph.getTreeName(true,false,true)] = currentGraph;
00675 
00676                 evalGraphBIC[stamps.size()] = currentGraph.BIC;
00677         }
00678         evalGraphRuntime[stamps.size()] = (ros::Time::now() - t).toSec();
00679 
00680         showEvaluation();
00681 //      analyzeTopologyOfGraphs();
00682 
00683         evalFast(false);
00684 
00685         saveGraphEval();
00686         saveBICEval();
00687         saveRuntimeEval();
00688         saveDOFLinkEval();
00689 }
00690 
00691 void KinematicStructureLearner::evalFast(bool setCurrent) {
00692         ros::Time t = ros::Time::now();
00693 
00694         std::vector<double> stamps= intersectionOfStamps();
00695         if(setCurrent)
00696                 enumerateGraphs();
00697 
00698         // initialize with spanning tree
00699         KinematicGraph tree = getSpanningTree(true);
00700         tree.evaluate(stamps,*this,*this);
00701         evalTreeRuntime[stamps.size()] = (ros::Time::now() - t).toSec();
00702 
00703         cout <<"spanning tree: "<<tree.getTreeName(true,false,true)<<endl;
00704         // find it graph list (ordering might be different, but topological distance should be zero)
00705         string current;
00706         for(map< string, KinematicGraph >::iterator  j=graphMap.begin();j!=graphMap.end();j++) {
00707 //                              cout <<"  "<<j->second.getTreeName(true,false,true)<< " "<< tree.distanceTo(j->second)<<endl;
00708                 if(tree.distanceTo(j->second)==0) {
00709                         current = j->second.getTreeName(true,false,true);
00710                         break;
00711                 }
00712         }
00713         cout <<"starting from current graph: "<<current<<endl;
00714         cout <<"finding neighbors, total graphs = "<<graphMap.size()<<endl;
00715 
00716         if(graphMap.find(current)==graphMap.end()) {
00717                 cout <<"current graph is not in graphMap???"<<endl;
00718                 return;
00719         }
00720 //      if(setCurrent)
00721         graphMap[current].evaluate(stamps,*this,*this);
00722         evalGraph[current].stampEval[stamps.size()].BIC = graphMap[current].BIC;
00723         evalGraph[current].stampEval[stamps.size()].bestTree = true;
00724         evalGraph[current].stampEval[stamps.size()].evalInFastSearch = true;
00725         evalTreeBIC[stamps.size()] = graphMap[current].BIC;
00726 
00727 
00728 //      cout <<"pre computed BIC of tree is "<<evalGraph[current].stampEval[stamps.size()].BIC<<endl;
00729 //      graphMap[current].evaluate(stamps,*this,*this);
00730 //      cout <<"now computed BIC of tree is "<<graphMap[current].BIC<<endl;
00731 
00732         int evals = 0;
00733         cout <<"  starting   "<<graphMap[current].BIC<<"  "<<current<<" pos="<<graphMap[current].avg_pos_err<<" orient="<<graphMap[current].avg_orient_err<< endl;
00734         string previous;
00735         while(current!=previous) {
00736                 previous = current;
00737 
00738 
00739                 for(map< string, KinematicGraph >::iterator  j=graphMap.begin();j!=graphMap.end();j++) {
00740                         if(graphMap[current].distanceTo(j->second)==1) {
00741                                 evals ++;
00742 //                              if(setCurrent){
00743                                 j->second.evaluate(stamps,*this,*this);
00744                                 evalGraph[j->second.getTreeName(true,false,true)].stampEval[stamps.size()].BIC = j->second.BIC;
00745 //                              }
00746                                 evalGraph[j->second.getTreeName(true,false,true)].stampEval[stamps.size()].evalInFastSearch = true;
00747                                 cout <<"  evaluating "<< j->second.BIC<<" ("<< evalGraph[j->second.getTreeName(true,true,true)].stampEval[stamps.size()].BIC <<"): "<<j->second.getTreeName(true,true,true)<<" pos="<<j->second.avg_pos_err<<" orient="<<j->second.avg_orient_err<< endl;
00748                                 if(j->second.BIC < graphMap[current].BIC) {
00749                                         current = j->second.getTreeName(true,false,true);
00750                                         break;
00751                                 }
00752                         } else {
00753 //                                      cout <<"  not evaluating " <<j->second.getTreeName(true,true,true)<<" dist="<< graphMap[current].distanceTo(j->second)<< endl;
00754                         }
00755                 }
00756                 cout <<graphMap[current].BIC<<"  "<<current<<endl;
00757         }
00758         evalGraph[current].stampEval[stamps.size()].bestFast = true;
00759         evalFastBIC[stamps.size()] = graphMap[current].BIC;
00760 
00761         cout <<"final:  "<<graphMap[current].BIC<<"  "<<current<<" pos="<<graphMap[current].avg_pos_err<<" orient="<<graphMap[current].avg_orient_err<< " stamps="<<stamps.size()<<endl;
00762         cout <<" evals: "<<evals;
00763         cout << endl;
00764 
00765         if(setCurrent) {
00766                 currentGraph = graphMap[current];
00767                 evalDOF[stamps.size()] = currentGraph.DOF;
00768                 evalLinks[stamps.size()] = currentGraph.size();
00769 
00770                 saveGraphEval();
00771                 saveBICEval();
00772                 saveRuntimeEval();
00773                 saveDOFLinkEval();
00774         }
00775         evalFastRuntime[stamps.size()] = (ros::Time::now() - t).toSec();
00776 }
00777 
00778 void KinematicStructureLearner::enumerateGraphs() {
00779 //      cout <<"enumerating"<<endl;
00780         graphMap.clear();
00781         KinematicGraph tree;
00782         map<int,int> marker_to_vertex;
00783         map<int,int> vertex_to_marker;
00784         int n=0;
00785         for(map<int,double>::iterator it = latestTimestamp.begin();
00786                         it != latestTimestamp.end(); it++ ) {
00787                 marker_to_vertex[it->first] = n;
00788                 vertex_to_marker[n] = it->first;
00789                 n++;
00790         }
00791 
00792         int vertices = models.size();
00793         int edges = vertices*vertices;
00794 
00795 //      cout <<"vertices="<<vertices<<endl;
00796 //      cout <<"edges="<<edges<<endl;
00797         for(long graph=1; graph < (1<<(edges-1)); graph++) {
00798                 // iterate over all possible graphs
00799                 std::vector<bool> connected(vertex_to_marker.size(),false);
00800                 connected[0] = true;
00801                 tree.clear();
00802                 for(int e=0;e<edges;e++) {
00803                         if((graph & (1<<e))>0) {
00804                                 // edge is present in this particular graph
00805                                 int e_from = vertex_to_marker[e / vertices];
00806                                 int e_to = vertex_to_marker[e % vertices];
00807                                 if(e_from>=e_to){
00808                                         tree.clear();
00809                                         break;
00810                                 }
00811                                 connected[e % vertices] = connected[e / vertices];
00812                                 if(!models[e_from][e_to]) {
00813                                         tree.clear();
00814                                         break;
00815                                 }
00816                                 if(!models[e_to][e_from]) {
00817                                         tree.clear();
00818                                         break;
00819                                 }
00820                                 tree.push_back(pair< pair<int,int>,GenericModelPtr>(pair<int,int>(e_from,e_to),models[e_from][e_to]));
00821 //                                      tree.push_back(pair< pair<int,int>,GenericModelPtr>(pair<int,int>(e_to,e_from),models[e_to][e_from]));
00822                         }
00823                 }
00824                 tree.DOF = tree.getNominalDOFs();// compute sum
00825                 if((int)tree.size()<vertices-1) continue;
00826                 if( restrict_graphs ) {
00827                         if(
00828                                         (restricted_graphs.find(" "+tree.getTreeName(false,false,false)+" ")==restricted_graphs.npos) &&
00829                                         (restricted_graphs.find(" "+tree.getTreeName(true,false,false)+" ")==restricted_graphs.npos) &&
00830                                         (restricted_graphs.find(" "+tree.getTreeName(true,true,false)+" ")==restricted_graphs.npos)  &&
00831                                         (restricted_graphs.find(" "+tree.getTreeName(true,true,true)+" ")==restricted_graphs.npos) )
00832                                 continue;
00833                 }
00834 
00835                 bool allConnected = true;
00836                 for(size_t i=0;i<connected.size();i++) {
00837                         if(!connected[i]) allConnected=false;
00838                 }
00839                 if(allConnected) {
00840                         // generate tree with all possible link models
00841                         // find the number of possible combinations
00842                         KinematicGraph basetree = tree;
00843                         tree.clear();
00844                         int combination_total = 1;
00845                         for(KinematicGraphType::iterator it=basetree.begin();it!=basetree.end();it++) {
00846                                 combination_total *= models_all[it->first.first][it->first.second].size();
00847                         }
00848 //                      cout <<"combination_total="<<combination_total<<endl;
00849                         for(int combination=0;combination<combination_total;combination++) {
00850                                 if(search_all_models) {
00851                                         tree.clear();
00852                                         int c_tmp = combination;
00853                                         for(KinematicGraphType::iterator it=basetree.begin();it!=basetree.end();it++) {
00854                                                 int idx = c_tmp % models_all[it->first.first][it->first.second].size();
00855                                                 tree.push_back( pair< pair<int,int>,GenericModelPtr> ( pair<int,int>(it->first.first,it->first.second), models_all[it->first.first][it->first.second][idx]));
00856                                                 c_tmp /= models_all[it->first.first][it->first.second].size();
00857                                         }
00858                                 } else {
00859                                         tree = basetree;
00860                                 }
00861 
00862                                 int DOFs = tree.getNominalDOFs();// compute sum
00863                                 tree.DOF = DOFs;
00864 //                              cout <<"DOFs="<<DOFs<<endl;
00865                                 for(int reducedDOFs=(reduce_dofs?(DOFs==0?0:1):DOFs);reducedDOFs<=DOFs;reducedDOFs++) {
00866                                         KinematicGraph copyOfTree(tree,true);
00867                                         copyOfTree.DOF = reducedDOFs;
00868                                         graphMap[copyOfTree.getTreeName(true,false,true)] = KinematicGraph(copyOfTree,true);
00869                                 }
00870                                 if(!search_all_models) break;
00871                         }
00872                 }
00873         }
00874 }
00875 
00876 void KinematicStructureLearner::showEvaluation() {
00877         cout <<"Evaluation @ t="<<intersectionOfStamps().size()<<endl;
00878         map<double, KinematicGraph> sorted;
00879         for(map< string, KinematicGraph >::iterator it = graphMap.begin();it!=graphMap.end();it++) {
00880                 sorted[it->second.BIC] = it->second;
00881         }
00882         for(map<double, KinematicGraph>::iterator it = sorted.begin();it!=sorted.end();it++) {
00883                 cout << it->first <<"      " << it->second.getTreeName(true,true,true)<<" pos="<<it->second.avg_pos_err<<" orient="<<it->second.avg_orient_err<< endl;
00884         }
00885         cout <<"---"<<endl;
00886 }
00887 
00888 void KinematicStructureLearner::sendSceneModel() {
00889         // need to update models first!!
00890         sendTreeTransforms(currentGraph);
00891         sendModels(currentGraph);
00892         sendStructureVisualization(currentGraph);
00893 }
00894 
00895 void KinematicStructureLearner::poseCallback(const PoseStampedIdMsgConstPtr& pose) {
00896 //      ROS_INFO("Received pose [%d]", pose->id);
00897         boost::mutex::scoped_lock a(frame_mutex_);
00898         double stamp = pose->pose.header.stamp.toSec();
00899         size_t id = pose->id;
00900 
00901         // compare to previous markers, skip if too close (bad perception)
00902         tf::Transform seen_marker = poseToTransform(pose->pose.pose);
00903         for (map<int, map<double, PoseStampedIdMsgConstPtr> >::iterator it =
00904                         markerStamped.begin(); it != markerStamped.end(); it++) {
00905                 if((size_t)it->first == id) continue;
00906                 if(it->second.size()==0) continue;
00907 
00908                 Pose p;
00909                 p = it->second.rbegin()->second->pose.pose;
00910                 tf::Transform other_marker = poseToTransform( p );
00911                 tf::Transform diff_to_known = seen_marker.inverseTimes( other_marker);
00912                 double diff_position = diff_to_known.getOrigin().length();
00913 //              double diff_orientation = fabs(diff_to_known.getRotation().getAngle());
00914 //              if(diff_position < sigma_position/2 && diff_orientation < sigma_orientation/2) {
00915                 if(diff_position < sigma_position) {
00916                         cout <<"skipping false positive marker detection"<<endl;
00917                         return;
00918                 }
00919 
00920         }
00921 
00922 
00923 
00924         // lookup any existing data
00925         for (map<int, PoseStampedIdMsgConstPtr>::iterator it =
00926                         stampedMarker[stamp].begin(); it != stampedMarker[stamp].end(); it++) {
00927                 if (it->second->id == id)
00928                         continue;
00929                 addPose(pose->pose, it->second->pose, id, it->second->id,*this);
00930                 addPose(it->second->pose, pose->pose, it->second->id, id,*this);
00931 
00932                 static tf::TransformBroadcaster br;
00933                 br.sendTransform( tf::StampedTransform(
00934                                 poseToTransform( pose->pose.pose ),
00935                                 pose->pose.header.stamp,
00936                                 "/camera",
00937                                 boost::str(boost::format( "/marker/%1%") % pose->id)
00938                 ));
00939 
00940         }
00941 
00942         stampedMarker[stamp][pose->id] = pose;
00943         markerStamped[pose->id][stamp] = pose;
00944 }
00945 
00946 void KinematicStructureLearner::poseCallback(const PoseStampedConstPtr& pose, size_t id) {
00947         latestTimestamp[id] = pose->header.stamp.toSec();
00948 
00949         bool invalid = false;
00950         if(pose->pose.position.x == 0 && pose->pose.position.y == 0 && pose->pose.position.z == 0 &&
00951                         pose->pose.orientation.x == 0 && pose->pose.orientation.y == 0 && pose->pose.orientation.z == 0 && pose->pose.orientation.w == 0
00952         ) invalid = true;
00953 
00954         if(!invalid) {
00955                 PoseStampedIdMsgPtr p = boost::make_shared<PoseStampedIdMsg>();
00956                 p->pose = *pose;
00957                 p->id = id;
00958                 poseCallback(p);
00959         }
00960 
00961         bool allDone = true;
00962 //      cout<<setprecision(15) <<"process? "<<latestTimestamp.begin()->second;
00963         for(map<int, double >::iterator it=latestTimestamp.begin();it!=latestTimestamp.end();it++) {
00964                 if(latestTimestamp.begin()->second != it->second) allDone = false;
00965 //              cout <<" "<<it->second;
00966         }
00967 //      cout << endl;
00968 
00969 //      cout <<"intersections="<<intersectionOfStamps().size()<<endl;
00970         static size_t last_stamp = 0;
00971         if(allDone) {
00972                 int a = ((int)pow(intersectionOfStamps().size(),1.00/eval_every_power));
00973                 int b = (((int)pow(last_stamp,1.00/eval_every_power)));
00974                 if ( (a%eval_every == 0)
00975                                 && ( a>b ) ) {
00976 
00977                         last_stamp = intersectionOfStamps().size();
00978                         b = (((int)pow(last_stamp,1.00/eval_every_power)));
00979                         cout << "stamps="<<intersectionOfStamps().size()<<endl;
00980                         ros::Time t1 = ros::Time::now();
00981                         cout << "updating models.."<<endl;
00982                         //update all models
00983                         for(map< int, map<int,TrackMsgPtr> >::iterator i=trajectories.begin();
00984                                 i != trajectories.end();i++) {
00985                                 for(map<int,TrackMsgPtr >::iterator j = i->second.begin();
00986                                         j != i->second.end();j++) {
00987 //                                              if(i->first < j->first) {
00988                                                         updateModel(i->first,j->first,*this);
00989 //                                              }
00990                                 }
00991                         }
00992                         ros::Time t2 = ros::Time::now();
00993                         evalModelsRuntime[last_stamp] = (t2-t1).toSec();
00994 
00995                         cout << "selecting scene model.."<<endl;
00996                         selectSceneModel();
00997                         ros::Time t3 = ros::Time::now();
00998                         cout <<"updating models took "<< (t2-t1).toSec() <<"s, graph selection took "<<(t3-t2).toSec()<<"s"<<endl;
00999                         sendSceneModel();
01000                 }
01001         }
01002 }
01003 
01004 
01005 void KinematicStructureLearner::poseCallback1(const PoseStampedConstPtr& pose) {
01006         poseCallback( pose,1 );
01007 }
01008 
01009 void KinematicStructureLearner::poseCallback2(const PoseStampedConstPtr& pose) {
01010         poseCallback( pose,2);
01011 }
01012 
01013 void KinematicStructureLearner::poseCallback3(const PoseStampedConstPtr& pose) {
01014         poseCallback( pose,3 );
01015 }
01016 
01017 void KinematicStructureLearner::poseCallback4(const PoseStampedConstPtr& pose) {
01018         poseCallback( pose,4 );
01019 }
01020 
01021 void KinematicStructureLearner::analyzeTopologyOfGraphs() {
01022         // does every node have a neighbor that has a lower BIC? (except for the optimal one?)
01023         map<string,bool> isHead;
01024         for(map< string, KinematicGraph >::iterator i=graphMap.begin();i!=graphMap.end();i++) {
01025                 // consider node i, might be a head in the graph (no incoming arrows)
01026                 isHead[i->second.getTreeName(true,false,true)] = true;
01027                 for(map< string, KinematicGraph >::iterator  j=graphMap.begin();j!=graphMap.end();j++) {
01028                         // is node j a neighbor?
01029 //                      cout << i->second.getTreeName(true,false,true) <<" -- " << j->second.getTreeName(true,false,true) << " dist="<<i->second.distanceTo(j->second)<<endl;
01030                         if(i->second.distanceTo(j->second)<=1) {
01031                                 // has the neighbor a lower BIC?
01032                                 if(j->second.BIC < i->second.BIC) {
01033                                         isHead[i->second.getTreeName(true,false,true)] = false; // we have a better neighbor
01034                                 }
01035                         }
01036                 }
01037         }
01038 
01039         // now check for heads
01040         cout <<"found heads: ";//<<isHead.size()<<endl;
01041         for(map<string,bool>::iterator i=isHead.begin();i!=isHead.end();i++) {
01042                 if(i->second) {
01043                         cout <<"  "<<i->first;
01044                         if(i->first == currentGraph.getTreeName(true,false,true) ) {
01045                                 cout <<"*";
01046                         }
01047                         cout<<endl;
01048                 }
01049         }
01050         cout <<"---"<<endl;
01051 
01052         // would we find the optimium, starting from the spanning tree and using a greedy strategy?
01053         KinematicGraph tree = getSpanningTree(true);
01054         string current = tree.getTreeName(true,false,true);
01055         string previous;
01056         cout <<"spanning tree: "<<current<<endl;
01057         // find it in list
01058         for(map< string, KinematicGraph >::iterator  j=graphMap.begin();j!=graphMap.end();j++) {
01059                 if(tree.distanceTo(j->second)==0) {
01060                         current = j->first;
01061                         cout <<"distance zero. "<<current<<endl;
01062                         break;
01063                 }
01064         }
01065         cout <<"(modified) spanning tree: "<<current<<endl;
01066 
01067         if(graphMap.find(current)==graphMap.end()) {
01068                 cout <<"spanning tree not in graphMap???"<<endl;
01069                 return;
01070         }
01071         int evals = 0;
01072         cout <<graphMap[current].BIC<<"  "<<current<<endl;
01073         while(current!=previous) {
01074                 previous = current;
01075                 for(map< string, KinematicGraph >::iterator  j=graphMap.begin();j!=graphMap.end();j++) {
01076                         if(graphMap[current].distanceTo(j->second)<=1) {
01077                                 evals ++;
01078                                 if(j->second.BIC < graphMap[current].BIC) {
01079                                         current = j->second.getTreeName(true,false,true);
01080                                         break;
01081                                 }
01082                         }
01083                 }
01084                 cout <<graphMap[current].BIC<<"  "<<current<<endl;
01085         }
01086         cout <<"finished: ";
01087         if(current == currentGraph.getTreeName(true,false,true) ) {
01088                 cout <<" optimal!!";
01089         } else {
01090                 cout <<" not optimal!!";
01091                 cout <<"currently best graph is: "<<currentGraph.getTreeName(true,false,true);
01092         }
01093         cout <<" evals: "<<evals;
01094         cout << endl;
01095 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Properties Friends Defines


articulation_structure
Author(s): sturm
autogenerated on Wed Dec 26 2012 15:37:59