OSVR Framework (Internal Development Docs)  0.6-1962-g59773924
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
OfflineFusion.cpp
Go to the documentation of this file.
1 
11 // Copyright 2015 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 #ifdef OSVR_FPE
26 #include <FPExceptionEnabler.h>
27 #endif
28 
29 // Internal Includes
30 #include "VideoIMUFusion.h"
31 #include <osvr/Util/EigenInterop.h>
32 #include <osvr/Common/JSONEigen.h>
34 
35 // Library/third-party includes
36 #include <json/value.h>
37 #include <json/reader.h>
38 
39 // Standard includes
40 #include <string>
41 #include <iostream>
42 #include <fstream>
43 
44 namespace ei = osvr::util::eigen_interop;
45 
46 static const auto IMU_PATH =
47  "/com_osvr_Multiserver/OSVRHackerDevKit0/semantic/hmd";
48 static const auto VIDEO_PATH =
49  "/com_osvr_VideoBasedHMDTracker/TrackedCamera0_0/semantic/hmd/front";
50 void processReports(Json::Value const &log) {
51  VideoIMUFusion fusion;
52  auto reportNumber = std::size_t{0};
53  bool gotRunning = false;
54  auto firstRunningReport = std::size_t{0};
55  bool gotOri = false;
57  for (auto &report : log) {
58  std::cout << "\n***********************\nReport #" << reportNumber;
59  if (gotRunning) {
60  std::cout << " (report #" << (reportNumber - firstRunningReport)
61  << " in running state)";
62  }
63  auto timestamp = osvr::common::timevalueFromJson(report["timestamp"]);
64  Eigen::Quaterniond quat =
65  osvr::common::quatFromJson(report["rotation"]);
66  auto &path = report["path"];
67  if (path == IMU_PATH) {
68  std::cout << " - IMU" << std::endl;
69  gotOri = true;
70  ei::map(ori.rotation) = quat;
71  fusion.handleIMUData(timestamp, ori);
72  } else if (path == VIDEO_PATH) {
73  std::cout << " - Video-based tracker" << std::endl;
74  OSVR_PoseReport pose;
75  ei::map(pose.pose).translation() =
76  osvr::common::vec3FromJson(report["translation"]);
77  ei::map(pose.pose).rotation() = quat;
78  if (fusion.running()) {
79  fusion.handleVideoTrackerDataWhileRunning(timestamp, pose);
80  } else {
81  if (!gotOri) {
82  std::cout
83  << "Video data before IMU data, skipping this one."
84  << std::endl;
85  continue;
86  }
87  fusion.handleVideoTrackerDataDuringStartup(timestamp, pose,
88  ori.rotation);
89  }
90  } else {
91  std::cerr << "Unrecognized path: " << path.toStyledString()
92  << std::endl;
93  throw std::runtime_error("Unrecognized path: " +
94  path.toStyledString());
95  }
96  if (fusion.running()) {
97  if (!gotRunning) {
98  gotRunning = true;
99  firstRunningReport = reportNumber;
100  std::cout << "---- Fusion just switched to running state!"
101  << std::endl;
102  }
103  std::cout << "Error Covariance:\n"
104  << fusion.getErrorCovariance().diagonal() << std::endl;
105  if ((fusion.getErrorCovariance().diagonal().array() < 0.).any()) {
106  std::cout << std::flush;
107  std::cerr << std::flush
108  << "Got a negative variance (diagonal of state "
109  "covariance matrix) - bailing out!"
110  << std::endl;
111  throw std::runtime_error("Negative variance!");
112  }
113  }
114  reportNumber++;
115  }
116 }
117 int main(int argc, char *argv[]) {
118  if (argc < 2) {
119  std::cerr << "Must pass the path to the input file!" << std::endl;
120  return -1;
121  }
122  Json::Value log;
123  {
124  auto fn = std::string{argv[1]};
125  std::ifstream dataFile(fn);
126  if (!dataFile) {
127  std::cerr << "Couldn't open data file '" << fn << "''" << std::endl;
128  return -1;
129  }
130  Json::Reader reader;
131  if (!reader.parse(dataFile, log)) {
132  std::cerr << "Couldn't parse data file '" << fn
133  << "' as JSON! Error(s): "
134  << reader.getFormattedErrorMessages() << std::endl;
135  return -1;
136  }
137  }
138  try {
139  processReports(log);
140  } catch (std::exception const &e) {
141  std::cerr << "Exception: " << e.what() << std::endl;
142  return -2;
143  }
144  std::cout << "Reached end of log!" << std::endl;
145  return 0;
146 }
OSVR_PoseState pose
The pose structure, containing a position vector and a rotation quaternion.
void handleVideoTrackerDataWhileRunning(const OSVR_TimeValue &timestamp, const OSVR_PoseReport &report)
Eigen::Matrix< double, 12, 12 > const & getErrorCovariance() const
EIGEN_MAKE_ALIGNED_OPERATOR_NEW void handleIMUData(const OSVR_TimeValue &timestamp, const OSVR_OrientationReport &report)
Eigen::Map< Eigen::Vector3d > translation() const
Definition: EigenInterop.h:334
void handleVideoTrackerDataDuringStartup(const OSVR_TimeValue &timestamp, const OSVR_PoseReport &report, const OSVR_OrientationState &orientation)
Report type for an orientation callback on a tracker interface.
Header.
Header for interoperation between the Eigen math library, the internal mini math library, and VRPN's quatlib.
OSVR_OrientationState rotation
The rotation unit quaternion.
Report type for a pose (position and orientation) callback on a tracker interface.