optimizer.cpp
Go to the documentation of this file.
00001 
00018 #include <cstdio>
00019 #include <iostream>
00020 #include <cstring>
00021 #include <fstream> 
00022 
00023 #include <boost/program_options.hpp>
00024 namespace po = boost::program_options;
00025 
00026 #include <log.h>
00027 #include <frame.h>
00028 #include <datapairs.h>
00029 #include <value_setter.h>
00030 #include <optimizer_goal.h>
00031 #include <optimizer_goal_global_position.h>
00032 #include <optimizer_goal_global_orientation.h>
00033 #include <optimizer_goal_orientation.h>
00034 #include <optimizer_goal_position.h>
00035 #include <optimizer_container.h>
00036 #include <optimizer.h>
00037 
00038 using namespace robotLibPbD;
00039 
00040 void COptimizer::setValue(double *x)
00041 {
00042   unsigned int counter = 0;
00043   for (unsigned int i=0; i<data.size(); i++)
00044     {
00045       data[i].setValue(x, counter);
00046       counter += data[i].dofs.size();
00047     }
00048 }
00049 
00050 std::string COptimizer::readFromFile(std::string filename)
00051 {
00052   std::vector<std::string> text;
00053   std::string line;
00054   std::ifstream textstream;
00055 
00056   textstream.open(filename.c_str());
00057   
00058 
00059   while (textstream.good() && std::getline(textstream, line)) {
00060     text.push_back(line + "\n");
00061   }
00062   textstream.close();
00063   std::string alltext;
00064   for (unsigned int i=0; i < text.size(); i++)
00065     alltext += text[i];
00066 
00067   return alltext;
00068 }
00069 
00070 
00071 void COptimizer::setData(std::vector<double> &values)
00072 {
00073   for (unsigned int i=0; i<valueSetters.size(); i++)
00074     {
00075       valueSetters[i].set(values);
00076     }
00077   /*
00078   for (unsigned int i=0; i<values.size(); i++)
00079     {
00080       LOG_MSG(10, "Setting: %s = %s\n", printToString("%d", i+1).c_str(), printToString("%f", values[i]).c_str());
00081       information.add(printToString("%d", i+1), printToString("%f", values[i]), true);
00082     }
00083   frames.loadFromFile(cfg.c_str(), information, config, false);
00084   frames.invalidate();
00085   */
00086 }
00087 
00088 void COptimizer::rosenbrockCallback(int nparam, double *x, double *fj, void *extraparams)
00089 {
00090   if (extraparams != NULL)
00091     ((COptimizer*) extraparams)->callback(nparam, x, fj);
00092 }
00093 
00094 void COptimizer::callback(int nparam, double *x, double *fj)
00095 {  
00096   LOG_MSG(10, "X: ");
00097   for (int i=0; i<nparam; i++)
00098     LOG_MSG(10, "%f ", x[i]);
00099   LOG_MSG(10, "\n");
00100 
00101   fj[0] = 0.0;
00102 
00103 
00104   for (unsigned int i=0; i<globalFunctions.size(); i++)
00105     globalFunctions[i]->reset();
00106 
00107   setValue(x);
00108 
00109   for (unsigned int j=0; j<examples.size(); j++)
00110     {
00111       setData(examples[j]);
00112    
00113       if (LOG_MSG_LEVEL(10))
00114         {
00115           CFrameInterface interface;
00116           for (unsigned int i=0; i<frames.getFrames().size(); i++)
00117             {
00118               interface.setFrame(frames.getFrame(i));
00119               LOG_MSG(10, "%s", interface.getFrameAsXml().c_str());
00120               LOG_MSG(10, "%s", frames.getFrame(i)->getRelativeToBase().toString().c_str());
00121             }
00122         }
00123 
00124       distances[j] = 0.0;
00125       for (unsigned int i=0; i<functions.size(); i++)
00126         {
00127           double tmpf = functions[i]->getDistance(); 
00128           LOG_MSG(6, "%d %d: %f\n", j, i, tmpf);
00129 
00130           distances[j] += tmpf;
00131 
00132           //fj[0] += tmpf / (double) examples.size();
00133         }
00134 
00135       
00136       for (unsigned int i=0; i<globalFunctions.size(); i++)
00137         globalFunctions[i]->add();
00138     }
00139 
00140   
00141   for (unsigned int i=0; i<globalFunctions.size(); i++)
00142     fj[0] += globalFunctions[i]->getDistance();  
00143   
00144   if (functions.size() > 0)
00145     {
00146       if (distances.size() == 1)
00147         {
00148           fj[0] += distances[0];
00149         } else
00150         {
00151           std::sort(distances.begin(), distances.end());
00152           for (unsigned int i=trimming; i<distances.size() - trimming; i++)
00153             fj[0] += distances[i] / (double) (distances.size() - 2*trimming);
00154         }
00155     }
00156 
00157   if (LOG_MSG_LEVEL(5))
00158     {
00159       LOG_MSG(2,"Value: %f X: ", fj[0]);
00160       for (int i=0; i<nparam; i++)
00161         LOG_MSG(2,"%f ", x[i]);
00162       LOG_MSG(2,"\n");
00163     }
00164 
00165   counter++;
00166   if (useShowResult || counter % counterMod == 0 )
00167     {
00168       LOG_MSG(2,"Goal-Value: %f State-Values: ", fj[0]);
00169       for (int i=0; i<nparam; i++)
00170         LOG_MSG(2,"%f ", x[i]);
00171       LOG_MSG(2,"\n");
00172       std::string tmp = generateOutput();
00173       LOG_MSG(2,"%s\n", tmp.c_str());
00174     }
00175 }
00176 
00177 bool COptimizer::isEqual(std::vector<double> &first, std::vector<double> &second, double eps)
00178 {
00179   for (unsigned int i=0; i<first.size() && i<second.size(); i++)
00180     if (fabsf(first[i] - second[i]) > eps)
00181       return false;
00182 
00183   return true;
00184 }
00185 
00186 void COptimizer::loadData(std::string filename, unsigned int startId)
00187 {
00188     std::string line, prev;
00189     std::ifstream textstream;
00190     std::vector<double> input;
00191     std::vector<std::vector<double> > examples2;
00192     LOG_VERBOSE("Reading data from %s.\n", filename.c_str());
00193 
00194     textstream.open(filename.c_str());
00195 
00196     unsigned int lines = 0;
00197     while (textstream.good() && std::getline(textstream, line))
00198     {
00199         lines++;
00200         if (lines <= startId)
00201         continue;
00202 
00203         input.clear();
00204 
00205         if (line.find(":") != std::string::npos)
00206         line = line.substr(line.find(":")+1, line.length());
00207 
00208 
00209 
00210         if (line.size() <= 0)
00211         continue;
00212 
00213         LOG_VERBOSE("%s\n", line.c_str());
00214         strToArray(line, input, ";");
00215 
00216         //ToDo: Debug isEqual
00217         //if (examples2.size() > 0 && isEqual(examples2.back(), input))
00218         //continue;
00219 
00220         examples2.push_back(input);
00221         prev = line;
00222     }
00223     textstream.close();
00224 
00225     int exampleCount = examples2.size();
00226     LOG_VERBOSE("Loaded %d ( %d ) examples\n", exampleCount, lines);
00227     unsigned int offset = examples2.size() / examplesMax;
00228     if (offset < 1)
00229     offset = 1;
00230     for (unsigned int i=0; i<examples2.size(); i+=offset)
00231     examples.push_back(examples2[i]);
00232 
00233     distances.resize(examples.size());
00234 }
00235 
00236 
00237 std::string COptimizer::generateOutput()
00238 {
00239     std::string tmp;
00240     CFrameInterface interface;
00241     for (unsigned int i=0; i<data.size(); i++)
00242     {
00243         CVec position, quater;
00244         CMatrix matrix = data[i].frame->getPose();
00245         position = matrix[3];
00246         CMathLib::quaternionFromMatrix(matrix, quater);
00247         interface.setFrame(data[i].frame);
00248         CVec eulerAngles;
00249         CMathLib::getEulerZXZ(matrix, eulerAngles);
00250         tmp += printToString("Result: %s", interface.getFrameAsXml().c_str());
00251         tmp += printToString("Position (xyz): %f %f %f Quaternion (wxyz): %f %f %f %f EulerAngles(ZXZ): %f %f %f \n\n", position.x, position.y, position.z,
00252          quater.w, quater.x, quater.y, quater.z, eulerAngles.x*180.0/M_PI, eulerAngles.y*180.0/M_PI, eulerAngles.z*180.0/M_PI);
00253     }
00254     tmp += printToString("<-- result -->\n\n");
00255     return tmp;
00256 }
00257 
00258 bool COptimizer::writeToFile(std::string filename, std::string buffer)
00259 {
00260   std::ofstream textstream(filename.c_str());
00261   if (textstream.fail())
00262     return false;
00263 
00264   textstream << buffer;
00265   textstream.close();
00266   return true;
00267 }
00268 
00269 int COptimizer::getValue(TiXmlElement *node, std::string item)
00270 {
00271   std::string tmp, tmp2;
00272   tmp = CConfiguration::getAttributeString(node, item.c_str(), "");
00273   size_t found = tmp.find("([");
00274   size_t found2 = tmp.find("])");
00275   
00276   if (found != std::string::npos && found2 !=std::string::npos)
00277     {
00278       tmp2 = tmp.substr(found+2, found2-found-2);
00279       LOG_MSG(2, "Value: %s\n", tmp2.c_str());
00280       return (int) atof(tmp2.c_str()) - 1;
00281     }
00282 
00283   return -1;
00284 }
00285  
00286 void COptimizer::loadDofs(std::string filename)
00287  {
00288   // load frame structure from xml 
00289   frames.loadFromFile(filename.c_str());
00290   frames.updateBaseLinks();
00291 
00292   CFrameInterface interface; 
00293   std::vector<double> dofs_max, dofs_min;
00294   std::vector<unsigned int> dofs; 
00295 
00296   unsigned int n = 0;
00297   for (unsigned int i=0; i<frames.getFrames().size(); i++)
00298     {
00299       interface.setFrame(frames.getFrame(i));
00300       LOG_VERBOSE("Frame: %s\n", interface.getFrameAsXml().c_str());
00301 
00302       frames.getFrame(i)->getDofs(dofs);
00303       if (dofs.size() > 0)
00304         {
00305           frames.getFrame(i)->getDofs(dofs_min, dofs_max);
00306           for (unsigned int j=0; j<dofs.size(); j++)
00307             LOG_VERBOSE("Loaded dof %d: %g %g\n", dofs[j], dofs_min[dofs[j]], dofs_max[dofs[j]]);
00308 
00309           n += dofs.size();
00310 
00311           OptimizerContainer item;
00312           item.frame = frames.getFrame(i);
00313           item.dofs_max = dofs_max;
00314           item.dofs_min = dofs_min;
00315           item.dofs = dofs; 
00316           data.push_back(item);
00317         }
00318     }
00319   
00320   LOG_VERBOSE("Total number of dofs: %d\n", n);
00321   this->dofs = n;
00322  }
00323 
00324 
00325 void COptimizer::loadValueSetters(std::string filename)
00326  {
00327   // load frame structure from xml
00328    CConfiguration config("Data"); 
00329   //bool okay = config.load(filename.c_str());
00330    config.load(filename.c_str());
00331  
00332   // Load goal
00333   std::vector<TiXmlElement*> result; 
00334   config.findNodes("Frames.Frame", result);
00335   for (unsigned int i=0; i<result.size(); i++)
00336     {
00337       LOG_MSG(2,"Frame: %s\n", CConfiguration::getAttributeString(result[i], "name", ""));
00338       ValueSetter valueSetter; 
00339 
00340       valueSetter.x = getValue(result[i], "x");
00341       valueSetter.y = getValue(result[i], "y");
00342       valueSetter.z = getValue(result[i], "z");
00343       valueSetter.qw = getValue(result[i], "qw");
00344       valueSetter.qx = getValue(result[i], "qx");
00345       valueSetter.qy = getValue(result[i], "qy");
00346       valueSetter.qz = getValue(result[i], "qz");
00347       valueSetter.a = getValue(result[i], "a");
00348       valueSetter.b = getValue(result[i], "b");
00349       valueSetter.g = getValue(result[i], "g");
00350 
00351       if (valueSetter.x < 0 &&
00352           valueSetter.y < 0 &&
00353           valueSetter.z < 0 &&
00354       valueSetter.qw < 0 &&
00355           valueSetter.qx < 0 &&
00356           valueSetter.qy < 0 &&
00357       valueSetter.qz < 0 &&
00358       valueSetter.a < 0 &&
00359       valueSetter.b < 0 &&
00360       valueSetter.g < 0)
00361         continue;
00362 
00363       int frameId = frames.getFrameByName(CConfiguration::getAttributeString(result[i], "name", ""));
00364       if (frameId < 0)
00365         continue;
00366 
00367       valueSetter.frame = frames.getFrame(frameId);
00368       
00369       valueSetters.push_back(valueSetter);
00370     }
00371  }
00372 
00373 
00374 void COptimizer::loadGoals(std::string filename)
00375  {
00376   // load frame structure from xml
00377    CConfiguration config("Data"); 
00378   //bool okay = config.load(filename.c_str());
00379    config.load(filename.c_str());
00380  
00381   // Load goal
00382   std::vector<TiXmlElement*> result;
00383   config.findNodes("Goal.Function", result);
00384   for (unsigned int i=0; i<result.size(); i++)
00385     {
00386       OptimizerGoal* goal = new OptimizerGoal();
00387       goal->loadFromXml(frames, result[i]);
00388       functions.push_back(goal);
00389     }
00390 
00391   result.clear();
00392   config.findNodes("Goal.GlobalPosition", result);
00393   for (unsigned int i=0; i<result.size(); i++)
00394     {
00395       OptimizerGoalGlobalPosition* goal = new OptimizerGoalGlobalPosition();
00396       goal->loadFromXml(frames, result[i]);
00397       goal->setTrimming(trimming);
00398       globalFunctions.push_back(goal);
00399     }
00400 
00401 
00402   result.clear();
00403   config.findNodes("Goal.GlobalOrientation", result);
00404   for (unsigned int i=0; i<result.size(); i++)
00405     {
00406       OptimizerGoalGlobalOrientation* goal = new OptimizerGoalGlobalOrientation();
00407       goal->loadFromXml(frames, result[i]);
00408       goal->setTrimming(trimming);
00409       globalFunctions.push_back(goal);
00410     }
00411 
00412   result.clear();
00413   config.findNodes("Goal.Position", result);
00414   for (unsigned int i=0; i<result.size(); i++)
00415     {
00416       OptimizerGoalPosition* goal = new OptimizerGoalPosition();
00417       goal->loadFromXml(frames, result[i]);
00418       functions.push_back(goal);
00419     }
00420 
00421   result.clear();
00422   config.findNodes("Goal.Orientation", result);
00423   for (unsigned int i=0; i<result.size(); i++)
00424     {
00425       OptimizerGoalOrientation* goal = new OptimizerGoalOrientation();
00426       goal->loadFromXml(frames, result[i]);
00427       functions.push_back(goal);
00428     }
00429  }
00430 
00431 
00432 void COptimizer::reset()
00433 {
00434   result.clear();
00435   valueSetters.clear();
00436   data.clear();
00437 
00438 
00439   globalFunctions.clear();
00440 
00441 
00442   functions.clear();
00443 
00444   information.clear();
00445   frames.clear();
00446 
00447   examples.clear();
00448   distances.clear();
00449 }
00450 
00451 void COptimizer::load(std::string cfg, std::string data, unsigned int start)
00452 {
00453   reset();
00454 
00455   loadData(data, start);
00456 
00457   loadDofs(cfg);
00458 
00459   loadGoals(cfg);
00460 
00461   loadValueSetters(cfg);
00462   
00463 }
00464 
00465 void COptimizer::run(const std::vector<double> &initialValues)
00466 {
00467   // reset
00468   counter = 0;
00469 
00470   // set trimming
00471   trimming = 0;
00472   if (trim > 0.0 && trim < 1.0)
00473     {
00474       trimming = (unsigned int) (trim / 2.0 * (double) examples.size());
00475       if (trimming == 0)
00476         trimming = 0;
00477 
00478       LOG_VERBOSE("Trimming best %d and worst %d items\n", trimming, trimming);
00479     }
00480   for (unsigned int i=0; i<globalFunctions.size(); i++)
00481     globalFunctions[i]->setTrimming(trimming);
00482   
00483   int nparam,maxIter,verbosity;
00484   double *st,*bl,*bu,bigbnd,eps;
00485   nparam=dofs;
00486   st=(double*)calloc(nparam,sizeof(double));
00487   bl=(double *)calloc(nparam,sizeof(double));
00488   bu=(double *)calloc(nparam,sizeof(double));
00489   bigbnd=1.e10;
00490   maxIter=iterations;
00491   eps=epsilon;//CHANGED 1.e-8;
00492   verbosity=0;
00493 
00494   for (int i=0; i<nparam; i++)
00495     {
00496       st[i] = 0.5;
00497       bl[i] = 0.0;
00498       bu[i] = 1.0;
00499     }
00500 
00501   if ((int)initialValues.size() >= nparam)
00502     for (int i=0; i<nparam; i++)
00503       {
00504         st[i] = initialValues[i];
00505         if (st[i] < 0.0 || st[i] > 1.0)
00506           LOG_MSG(2,"Error: %d'th value %f has to be in [0,1].\n", i, st[i]);
00507       }
00508   
00509   if (useRandom)
00510     for (int i=0; i<nparam; i++)
00511       {
00512         st[i] = getUniform(); 
00513       }
00514   double y[1];
00515 
00516 
00517   LOG_MSG(2, "Initial:\n");
00518   for (int i=0; i<nparam; i++)
00519     LOG_MSG(2, "%f\n", st[i]);
00520 
00521   if (doQuit)
00522     {
00523       rosenbrockCallback(nparam, st, y, this);
00524       exit(0);
00525     }
00526  
00527 
00528   rosenbrock(nparam,st,bl,bu,bigbnd,maxIter,eps,verbosity,rosenbrockCallback, this);
00529   
00530   rosenbrockCallback(nparam, st, y, this);
00531 
00532   LOG_MSG(2, "Best: %f\n", y[0]);
00533 
00534   LOG_MSG(2, "Result:\n");
00535   for (int i=0; i<nparam; i++)
00536     LOG_MSG(2, "%f\n", st[i]);
00537 
00538   LOG_MSG(1, "%f ", y[0]);
00539  
00540   for (int i=0; i<nparam; i++)
00541     LOG_MSG(1, "%f ", st[i]);
00542   LOG_MSG(1, "%f\n", y[0]);
00543  
00544   setValue(st);  
00545   std::string output = generateOutput();
00546   LOG_MSG(2, "Final result:\n");
00547   LOG_MSG(2, "%s\n", output.c_str()); 
00548   
00549   this->resultValue = y[0];
00550   
00551   this->result.resize(nparam);
00552   for (int i=0; i<nparam; i++)
00553     this->result[i] = st[i];
00554 
00555   free(st);
00556   free(bl);
00557   free(bu);
00558 }
00559 
00560 
00561 void COptimizerResult::clear()
00562 {
00563   allPoses.clear();
00564   optimizedPoses.clear();
00565   values.clear();
00566   timelineOfPoses.clear(); 
00567 }
00568 
00569 bool COptimizer::getResult(COptimizerResult &out)
00570 {
00571   if (result.size() == 0)
00572     return false;
00573 
00574   double *st = (double*)calloc(result.size(),sizeof(double));
00575   for (unsigned int i=0; i<result.size(); i++)
00576     st[i] = result[i];
00577   
00578   setValue(st); 
00579 
00580   // reset
00581   out.clear();
00582 
00583   // set result
00584   out.result = resultValue;
00585   out.values = result;
00586   for (unsigned int i=0; i<data.size(); i++)
00587     {
00588       out.optimizedPoses.push_back(make_pair((std::string)data[i].frame->getName(), data[i].frame->getPose()));
00589     }
00590 
00591   for (unsigned int i=0; i<frames.getFrames().size(); i++)
00592     out.allPoses.push_back(make_pair((std::string)frames.getFrame(i)->getName(), frames.getFrame(i)->getPose()));
00593     
00594   // generate timeline
00595   out.timelineOfPoses.resize(examples.size());
00596   for (unsigned int j=0; j<examples.size(); j++)
00597     {  
00598       setData(examples[j]);
00599       setValue(st); 
00600 
00601       for (unsigned int i=0; i<frames.getFrames().size(); i++)
00602         out.timelineOfPoses[j].push_back(make_pair((std::string)frames.getFrame(i)->getName(), frames.getFrame(i)->getPose()));
00603     }
00604 
00605   free(st);
00606   return true;
00607 }


asr_kinematic_chain_optimizer
Author(s): Aumann Florian, Heller Florian, Jäkel Rainer, Wittenbeck Valerij
autogenerated on Sat Jun 8 2019 19:42:49