PageRenderTime 48ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/src/param_handler.cpp

https://gitlab.com/fspinelli/Pose-Estimation-Library
C++ | 323 lines | 272 code | 12 blank | 39 comment | 40 complexity | 9e06cc49405185732d42ea6759ccf707 MD5 | raw file
  1. /*
  2. * Software License Agreement (BSD License)
  3. *
  4. * Pose Estimation Library (PEL) - https://bitbucket.org/Tabjones/pose-estimation-library
  5. * Copyright (c) 2014-2015, Federico Spinelli (fspinelli@gmail.com)
  6. * All rights reserved.
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions are met:
  10. *
  11. * * Redistributions of source code must retain the above copyright notice, this
  12. * list of conditions and the following disclaimer.
  13. *
  14. * * Redistributions in binary form must reproduce the above copyright notice,
  15. * this list of conditions and the following disclaimer in the documentation
  16. * and/or other materials provided with the distribution.
  17. *
  18. * * Neither the name of copyright holder(s) nor the names of its
  19. * contributors may be used to endorse or promote products derived from
  20. * this software without specific prior written permission.
  21. *
  22. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  23. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  24. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  25. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  26. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  27. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  28. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  29. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  30. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  31. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  32. */
  33. #include <pel/param_handler.h>
  34. using namespace pcl::console;
  35. namespace pel
  36. {
  37. ParamHandler::ParamHandler ()
  38. {
  39. params_["verbosity"]= 1;
  40. params_["use_vfh"]= params_["use_esf"]=params_["use_cvfh"]=params_["use_ourcvfh"]=1;
  41. params_["downsamp"] = 1;
  42. params_["downsamp_leaf_size"]=0.005f;
  43. params_["upsamp"] = params_["filter"]=0;
  44. params_["lists_size"]=20;
  45. params_["upsamp_poly_order"]=2;
  46. params_["upsamp_point_density"]=200;
  47. params_["upsamp_poly_fit"]=1;
  48. params_["upsamp_search_radius"]=0.05f;
  49. params_["filter_mean_k"]=50;
  50. params_["filter_std_dev_mul_thresh"]=3;
  51. params_["normals_radius_search"]=0.02;
  52. params_["cvfh_ang_thresh"]=7.5;
  53. params_["cvfh_curv_thresh"]=0.025;
  54. params_["cvfh_clus_tol"]=0.01;
  55. params_["cvfh_clus_min_points"]=50;
  56. params_["ourcvfh_ang_thresh"]=7.5;
  57. params_["ourcvfh_curv_thresh"]=0.025;
  58. params_["ourcvfh_clus_tol"]=0.01;
  59. params_["ourcvfh_clus_min_points"]=50;
  60. params_["ourcvfh_axis_ratio"]=0.95;
  61. params_["ourcvfh_min_axis_value"]=0.01;
  62. params_["ourcvfh_refine_clusters"]=1;
  63. size_of_valid_params_ = params_.size();
  64. }
  65. void
  66. ParamHandler::checkAndFixMinParam(std::string key, const float min)
  67. {
  68. if (params_.count(key))
  69. if(params_.at(key) < min)
  70. {
  71. if (params_.at("verbosity") > 0 )
  72. print_warn("%*s]\tParameter '%s' has value %g, which is below minimum allowed of %g, setting it to minimum...\n",20,__func__, key.c_str(),params_.at(key), min);
  73. params_.at(key) = min;
  74. }
  75. }
  76. void
  77. ParamHandler::checkAndFixMinMaxParam(std::string key, const float min, const float max)
  78. {
  79. checkAndFixMinParam(key,min);
  80. if (params_.count(key))
  81. if(params_.at(key) > max)
  82. {
  83. if (params_.at("verbosity") > 0 )
  84. print_warn("%*s]\tParameter '%s' has value %g, which is above maximum allowed of %g, setting it to maximum...\n",20,__func__, key.c_str(),params_.at(key), max);
  85. params_.at(key) = min;
  86. }
  87. }
  88. void
  89. ParamHandler::fixParameters ()
  90. {
  91. //Check Parameters correctness
  92. checkAndFixMinMaxParam("verbosity", 0, 2);
  93. checkAndFixMinMaxParam("downsamp", 0, 1);
  94. checkAndFixMinParam("downsamp_leaf_size", 0.0001);
  95. checkAndFixMinMaxParam("upsamp", 0,1);
  96. checkAndFixMinParam("lists_size", 1);
  97. checkAndFixMinParam("upsamp_poly_order", 1);
  98. checkAndFixMinParam("upsamp_point_density", 1);
  99. checkAndFixMinMaxParam("upsamp_poly_fit", 0, 1);
  100. checkAndFixMinParam("upsamp_search_radius", 0.0001);
  101. checkAndFixMinParam("filter_mean_k", 1);
  102. checkAndFixMinParam("filter_std_dev_mul_thresh", 0.00001);
  103. checkAndFixMinParam("normals_radius_search", 0.0001);
  104. checkAndFixMinParam("cvfh_ang_thresh", 0.0001);
  105. checkAndFixMinParam("cvfh_curv_thresh", 0.0001);
  106. checkAndFixMinParam("cvfh_clus_tol", 0.0001);
  107. checkAndFixMinParam("cvfh_clus_min_points", 1);
  108. checkAndFixMinParam("ourcvfh_ang_thresh", 0.0001);
  109. checkAndFixMinParam("ourcvfh_curv_thresh", 0.0001);
  110. checkAndFixMinParam("ourcvfh_clus_tol", 0.0001);
  111. checkAndFixMinParam("ourcvfh_clus_min_points", 1);
  112. checkAndFixMinParam("ourcvfh_axis_ratio", 0.0001);
  113. checkAndFixMinParam("ourcvfh_min_axis_value", 0.0001);
  114. checkAndFixMinMaxParam("ourcvfh_refine_clusters", 0, 1);
  115. }
  116. bool
  117. ParamHandler::setParam (const std::string key, const float value)
  118. {
  119. float verb_level = getParam("verbosity");
  120. if (value < 0)
  121. {
  122. if (verb_level > 0)
  123. print_warn("%*s]\tParameter '%s' has a negative value (%g), ignoring...\n", 20,__func__, key.c_str(), value);
  124. return false;
  125. }
  126. params_[key]=value;
  127. //Check if key was a valid one, since the class has fixed number of parameters,
  128. //if one was mispelled, now we have one more
  129. if (params_.size() != size_of_valid_params_)
  130. {
  131. if (verb_level > 0)
  132. print_warn("%*s]\tInvalid key parameter '%s', ignoring...\n", 20,__func__, key.c_str());
  133. params_.erase(key);
  134. return false;
  135. }
  136. else if (verb_level > 1)
  137. print_info("%*s]\tSetting parameter: %s=%g\n",20,__func__,key.c_str(),value);
  138. return true;
  139. }
  140. bool
  141. ParamHandler::setParam (const std::string key, const std::string value)
  142. {
  143. float f;
  144. float verb_level = getParam("verbosity");
  145. try
  146. {
  147. f = stof(value);
  148. }
  149. catch (const std::invalid_argument& ia)
  150. {
  151. if ( verb_level > 0)
  152. print_warn("%*s]\tInvalid %s=%s : %s \n",20,__func__, key.c_str(), value.c_str(), ia.what());
  153. return false;
  154. }
  155. catch (const std::out_of_range& oor)
  156. {
  157. if (verb_level > 0)
  158. print_warn("%*s]\tInvalid %s=%s : %s \n", 20,__func__, key.c_str(), value.c_str(), oor.what());
  159. return false;
  160. }
  161. return (this->setParam(key, f));
  162. }
  163. int
  164. ParamHandler::loadParamsFromFile (const boost::filesystem::path config_file)
  165. {
  166. if ( boost::filesystem::exists(config_file) && boost::filesystem::is_regular_file(config_file))
  167. {
  168. float verb_level = getParam("verbosity");
  169. std::ifstream file (config_file.c_str());
  170. std::string line;
  171. if (file.is_open())
  172. {
  173. int count (0);
  174. while (getline (file, line))
  175. {
  176. boost::trim(line); //remove white spaces from line
  177. if (line.empty())
  178. {
  179. //do nothing empty line ...
  180. continue;
  181. }
  182. else if (line.compare(0,1,"#") == 0 )
  183. {
  184. //do nothing comment line ...
  185. continue;
  186. }
  187. else
  188. {
  189. std::vector<std::string> vst;
  190. //split the line to get a key and a token or trailing comments
  191. boost::split(vst, line, boost::is_any_of("#"), boost::token_compress_on);
  192. line = vst.at(0);
  193. boost::split(vst, line, boost::is_any_of(":"), boost::token_compress_on);
  194. if (vst.size()!=2)
  195. {
  196. if (verb_level > 0)
  197. print_warn("%*s]\tInvalid configuration line (%s), ignoring... Must be [Token]:[Value]\n", 20,__func__, line.c_str());
  198. continue;
  199. }
  200. std::string key (vst.at(0));
  201. std::string value (vst.at(1));
  202. boost::trim(key);
  203. boost::trim(value);
  204. if ( setParam(key, value) )
  205. {
  206. //success
  207. ++count;
  208. }
  209. }
  210. }//end of config file
  211. file.close();
  212. return (count);
  213. }
  214. else
  215. {
  216. print_error("%*s]\tCannot open config file! (%s)\n", 20,__func__, config_file.c_str());
  217. return (-1);
  218. }
  219. }
  220. else
  221. {
  222. print_error("%*s]\tPath to config_file is not valid, or non existant! (%s)\n", 20,__func__, config_file.c_str());
  223. return (-1);
  224. }
  225. }
  226. float
  227. ParamHandler::getParam (const std::string key) const
  228. {
  229. if (params_.count(key))
  230. return ( params_.at(key) );
  231. else
  232. return (-1);
  233. }
  234. int
  235. ParamHandler::setParamsFromMap (const parameters& par_map)
  236. {
  237. if (!par_map.empty())
  238. {
  239. int count (0);
  240. for (const auto& x: par_map)
  241. if (this->setParam(x.first, x.second))
  242. ++count;
  243. return (count);
  244. }
  245. else
  246. {
  247. print_error("%*s]\tEmpty map provided, cannot set parameters...\n", 20,__func__);
  248. return (-1);
  249. }
  250. }
  251. bool
  252. ParamHandler::dumpParamsToFile (boost::filesystem::path config_file, bool overwrite) const
  253. {
  254. float verb_level = getParam("verbosity");
  255. if (!config_file.has_extension())
  256. {
  257. config_file+=".yaml";
  258. }
  259. if (boost::filesystem::exists (config_file) && boost::filesystem::is_regular_file (config_file))
  260. {
  261. if (overwrite)
  262. {
  263. boost::filesystem::remove (config_file);
  264. if (verb_level > 0)
  265. print_warn("%*s]\t File %s already exists, overwriting it as requested.\n", 20,__func__, config_file.c_str());
  266. }
  267. else
  268. {
  269. print_error("%*s]\t File %s already exists, not overwriting it as requested. Aborting...\n", 20,__func__, config_file.c_str());
  270. return false;
  271. }
  272. }
  273. std::ofstream file;
  274. file.open(config_file.c_str());
  275. if (file.is_open())
  276. {
  277. try
  278. {
  279. for (const auto& x: params_)
  280. file << x.first << ": " << x.second << std::endl;
  281. }
  282. catch (...)
  283. {
  284. print_error("%*s]\tError writing into %s file, aborting...\n",20,__func__, config_file.c_str());
  285. return false;
  286. }
  287. }
  288. else
  289. {
  290. print_error("%*s]\tCannot open %s file for writing, aborting...\n",20,__func__, config_file.c_str());
  291. return false;
  292. }
  293. if (verb_level > 1)
  294. print_info("%*s]\tParameters written into %s succesfully.\n",20,__func__, config_file.c_str());
  295. return true;
  296. }
  297. void
  298. ParamHandler::printAllParams () const
  299. {
  300. for (const auto& x: params_)
  301. print_info("%*s]\t%s: %g\n",20,__func__,x.first.c_str(), x.second);
  302. }
  303. void
  304. ParamHandler::printParam (const std::string key) const
  305. {
  306. if (params_.count(key))
  307. print_info("%*s]\t%s: %g\n",20,__func__,key.c_str(), params_.at(key) );
  308. else
  309. print_error("%*s]\tParam %s does not exists!\n",20,__func__,key.c_str());
  310. }
  311. }