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
00079
00080
00081
00082
00083
00084
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
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
00217
00218
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
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
00328 CConfiguration config("Data");
00329
00330 config.load(filename.c_str());
00331
00332
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
00377 CConfiguration config("Data");
00378
00379 config.load(filename.c_str());
00380
00381
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
00468 counter = 0;
00469
00470
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;
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
00581 out.clear();
00582
00583
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
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 }