OSVR Framework (Internal Development Docs)  0.6-1962-g59773924
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
TrackerParameterFinder.cpp
Go to the documentation of this file.
1 
11 // Copyright 2016 Sensics, Inc.
12 //
13 // Licensed under the Apache License, Version 2.0 (the "License");
14 // you may not use this file except in compliance with the License.
15 // You may obtain a copy of the License at
16 //
17 // http://www.apache.org/licenses/LICENSE-2.0
18 //
19 // Unless required by applicable law or agreed to in writing, software
20 // distributed under the License is distributed on an "AS IS" BASIS,
21 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 // See the License for the specific language governing permissions and
23 // limitations under the License.
24 
25 // Internal Includes
26 #include "LoadRows.h"
27 #include "ParamFindingRoutine.h"
28 #include "ParameterSets.h"
30 
32 #include <osvr/TypePack/Head.h>
33 #include <osvr/TypePack/List.h>
34 
35 // Library/third-party includes
36 #include <boost/algorithm/string/predicate.hpp> // for argument handling
37 
38 // Standard includes
39 #include <iostream>
40 
42 #undef PAUSE_BEFORE_EXIT
43 
45 namespace ps {
47 using ParamSets =
50 using DefaultParamSet = osvr::typepack::head<ps::ParamSets>;
51 } // namespace ps
52 
55 enum class OptimizationRoutine {
56  RefTracker,
57  ParamViaRansac,
58  ParamViaRefTracker,
59  Unrecognized = -1
60 };
61 
62 static const auto DEFAULT_ROUTINE = OptimizationRoutine::RefTracker;
63 
64 static const auto RECOGNIZED_ROUTINES = {
65  OptimizationRoutine::RefTracker, OptimizationRoutine::ParamViaRansac,
66  OptimizationRoutine::ParamViaRefTracker};
67 
68 const char *routineToString(OptimizationRoutine routine) {
69  switch (routine) {
70  case OptimizationRoutine::RefTracker:
71  return "RefTracker";
72  break;
73  case OptimizationRoutine::ParamViaRansac:
74  return "ParamViaRansac";
75  break;
76  case OptimizationRoutine::ParamViaRefTracker:
77  return "ParamViaRefTracker";
78  break;
79  case OptimizationRoutine::Unrecognized:
80  default:
81  return "ERROR - UNRECOGNIZED";
82  break;
83  }
84 }
85 
86 OptimizationRoutine stringToRoutine(const char *routineName) {
87  for (auto &routine : RECOGNIZED_ROUTINES) {
88  if (boost::iequals(routineToString(routine), routineName)) {
89  return routine;
90  }
91  }
92  return OptimizationRoutine::Unrecognized;
93 }
94 
96  template <typename T> void operator()(T const &) {
97  std::cerr
98  << " "
100  << "\n";
101  }
102 };
103 
104 int usage(const char *argv0) {
105  std::cerr << "Usage: " << argv0 << " [<routine> [<paramset> [--cost]]]\n"
106  << std::endl;
107  std::cerr
108  << "where <routine> is one of the following (case insensitive): \n";
109  for (auto &routine : RECOGNIZED_ROUTINES) {
110  std::cerr << " " << routineToString(routine) << "\n";
111  }
112  std::cerr
113  << "\nThe various ParamViaX routines take an optional additional "
114  "argument specifying the parameter set that they optimize, one "
115  "of:\n";
116 
117  osvr::typepack::for_each_type<ps::ParamSets>(PrintParamSetOptions{});
118  std::cerr << "as well as an additional optional switch, --cost, if you'd "
119  "like to just run the current parameters through and compute "
120  "the cost, rather than optimize.\n\n";
121  std::cerr
122  << "\nIf no routine is explicitly specified, the default routine is "
123  << routineToString(DEFAULT_ROUTINE) << "\n";
124  std::cerr << "Too many arguments, or an unrecognized routine parameter "
125  "(including anything vaguely 'help-ish') will trigger this "
126  "message."
127  << std::endl;
128  return 1;
129 }
130 
131 template <typename RefSource> class ParseArgumentAsParamSet {
132  public:
133  ParseArgumentAsParamSet(osvr::vbtracker::ParamOptimizerFunc &outFunc,
134  std::string &paramSetName)
135  : outFunc_(outFunc), paramSetName_(paramSetName) {}
136  template <typename T> void operator()(T const &, const char *arg) {
138  if (boost::iequals(ParamSetName<T>::get(), arg)) {
139  // we've got a match!
140  outFunc_ = &osvr::vbtracker::runOptimizer<RefSource, T>;
141  paramSetName_ = ParamSetName<T>::get();
142  }
143  }
144 
145  private:
146  osvr::vbtracker::ParamOptimizerFunc &outFunc_;
147  std::string &paramSetName_;
148 };
149 
150 template <typename RefSource>
151 int parseParamSetForParamOptimizer(osvr::vbtracker::ParamOptimizerFunc &func,
152  bool &costOnly, int argc, char *argv[]) {
153  if (argc > 4) {
154  std::cerr << "Too many command line arguments!" << std::endl;
155  return usage(argv[0]);
156  }
157  if (argc > 3) {
158  if (boost::iequals(argv[3], "--cost")) {
159  std::cout << "Will run for just cost-only." << std::endl;
160  costOnly = true;
161  } else {
162  std::cerr << "Too many command line arguments - didn't recognize "
163  "the last one!"
164  << std::endl;
165  return usage(argv[0]);
166  }
167  }
168  if (argc == 2) {
169  // specified routine only, no param set
170  std::cout << "Will process default parameter set "
172  ps::DefaultParamSet>::get()
173  << "\n";
174  func = &osvr::vbtracker::runOptimizer<RefSource, ps::DefaultParamSet>;
175  costOnly = false;
176  return 0;
177  }
178  // OK, they specified a param set.
179  osvr::vbtracker::ParamOptimizerFunc result;
180  std::string paramSetName;
181  ParseArgumentAsParamSet<RefSource> functor(result, paramSetName);
182  osvr::typepack::for_each_type<ps::ParamSets>(functor, argv[2]);
183  if (result) {
184  std::cout << "Will process parameter set " << paramSetName
185  << " as specified on the command line.\n";
186  func = result;
187  return 0;
188  }
189 
190  std::cerr << "Did not recognize " << argv[2]
191  << " as one of the known parameter sets to optimize!"
192  << std::endl;
193 
194  return usage(argv[0]);
195 }
196 
197 int main(int argc, char *argv[]) {
198  OptimizationRoutine routine = DEFAULT_ROUTINE;
199  static const auto DATAFILE = "augmented-blobs.csv";
200 
201  auto withUsage = [&] { return usage(argv[0]); };
202  auto tooManyArguments = [&] {
203  std::cerr << "Too many command line arguments!" << std::endl;
204  return withUsage();
205  };
206 
207  if (argc > 1) {
208  routine = stringToRoutine(argv[1]);
209  if (OptimizationRoutine::Unrecognized == routine) {
210  std::cerr << "Didn't recognize '" << argv[1]
211  << "' as an optimization routine.\n"
212  << std::endl;
214  return withUsage();
215  }
217  std::cout << "Will execute optimization routine "
218  << routineToString(routine)
219  << " as specified on the command line." << std::endl;
220  } else {
221  std::cout << "No optimization routine specified on the command line, "
222  "will execute "
223  << routineToString(routine) << " by default." << std::endl;
224  }
225 
226  bool costOnly = false;
227  osvr::vbtracker::ParamOptimizerFunc paramOptFunc;
228  {
229  int ret = 0;
230  switch (routine) {
231  case OptimizationRoutine::ParamViaRansac:
232  ret =
233  parseParamSetForParamOptimizer<osvr::vbtracker::RansacOneEuro>(
234  paramOptFunc, costOnly, argc, argv);
235  if (ret != 0) {
238  return ret;
239  }
240  break;
241 
242  case OptimizationRoutine::ParamViaRefTracker:
243 
244  ret = parseParamSetForParamOptimizer<
245  osvr::vbtracker::ReferenceTracker>(paramOptFunc, costOnly, argc,
246  argv);
247  if (ret != 0) {
250  return ret;
251  }
252  break;
253 
254  case OptimizationRoutine::RefTracker:
256  default:
257  if (argc > 2) {
258 
259  std::cerr << "Too many command line arguments!" << std::endl;
260  return withUsage();
261  }
262  }
263  }
264 
265  std::cout << "Loading and parsing data from " << DATAFILE << " ";
266  auto data = osvr::vbtracker::loadData(DATAFILE);
267  std::cout << "\n";
268 
269  const auto camParams =
270  osvr::vbtracker::getHDKCameraParameters().createUndistortedVariant();
271 
273  params.performingOptimization = true;
274  params.silent = true;
275  params.debug = false;
276 
277  params.offsetToCentroid = false;
278  params.includeRearPanel = false;
279  params.imu.path = "";
280  params.imu.useOrientation = false;
281  params.imu.useAngularVelocity = false;
282 
283  std::cout << "Starting optimization routine " << routineToString(routine)
284  << std::endl;
285  switch (routine) {
286  case OptimizationRoutine::RefTracker:
290  osvr::vbtracker::computeRefTrackerTransform(
291  data, osvr::vbtracker::OptimCommonData{camParams, params});
292  break;
293 
294  case OptimizationRoutine::ParamViaRansac:
295 
296  paramOptFunc(data, costOnly,
297  osvr::vbtracker::OptimCommonData{camParams, params}, 30);
298  break;
299 
300  case OptimizationRoutine::ParamViaRefTracker:
301 
302  paramOptFunc(data, costOnly,
303  osvr::vbtracker::OptimCommonData{camParams, params}, 300);
304  break;
305 
306  default:
307  assert(false && "Should not happen - only recognized routines should "
308  "make it this far!");
309  }
310 
311 #ifdef PAUSE_BEFORE_EXIT
312  std::cout << "Press enter to exit." << std::endl;
313  std::cin.ignore();
314 #endif
315  return 0;
316 }
Header.
bool silent
For optimization usage.
Definition: ConfigParams.h:89
int main(int argc, char *argv[])
typename detail::split_list_< List...>::head head
Get the first element of a list.
Definition: SplitList.h:54
A wrapper for a template parameter pack of types.
Definition: List.h:52
IMUInputParams imu
IMU input-related parameters.
Definition: ConfigParams.h:254
General configuration parameters.
Definition: ConfigParams.h:82
Header.
Header.
bool debug
Whether to show the debug windows and debug messages.
Definition: ConfigParams.h:137
bool useAngularVelocity
Should angular velocity reports be used once calibration completes?
Definition: ConfigParams.h:60
Input from main to the optimization routine (wrapper)
Define to add a "press enter to exit" thing at the end.
bool useOrientation
Should orientation reports be used once calibration completes?
Definition: ConfigParams.h:52
CameraParameters createUndistortedVariant() const
Copy-constructs, with zero distortion parameters.