OSVR Framework (Internal Development Docs)  0.6-1962-g59773924
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
TrackedBodyIMU.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 "TrackedBodyIMU.h"
27 #include "AngVelTools.h"
28 #include "TrackedBody.h"
29 #include "TrackingSystem.h"
30 #include <osvr/Util/EigenExtras.h>
31 
32 // Library/third-party includes
33 #include <boost/assert.hpp>
34 
35 // Standard includes
36 #include <cmath>
37 
38 namespace osvr {
39 namespace vbtracker {
40  TrackedBodyIMU::TrackedBodyIMU(TrackedBody &body,
41  double orientationVariance,
42  double angularVelocityVariance)
43  : m_body(body), m_yaw(0),
44  m_useOrientation(getParams().imu.useOrientation),
45  m_orientationVariance(orientationVariance),
46  m_useAngularVelocity(getParams().imu.useAngularVelocity),
47  m_angularVelocityVariance(angularVelocityVariance) {}
48  void
50  Eigen::Quaterniond const &quat) {
51  // Choose the equivalent quaternion to the input that makes the data
52  // smooth with previous quaternions.
53  Eigen::Quaterniond rawSmoothQuat = quat;
54  if (m_hasRawQuat) {
55  util::flipQuatSignToMatch(rawSmoothQuat, m_rawQuat);
56  } else {
57  // first report: we'll arbitrarily choose w to be positive.
58  if (quat.w() < 0) {
59  rawSmoothQuat = Eigen::Quaterniond(-quat.coeffs());
60  }
61  m_hasRawQuat = true;
62  }
63  m_rawQuat = rawSmoothQuat;
64 
65  if (!m_yawKnown) {
66  // This needs to go to calibration instead of to our own pose.
67  getBody().getSystem().calibrationHandleIMUData(getBody().getId(),
68  tv, rawSmoothQuat);
69  return;
70  }
71  // Save some local state: we do have orientation ourselves now.
72  m_quat = transformRawIMUOrientation(rawSmoothQuat);
73  m_hasOrientation = true;
74  m_last = tv;
75 
76  if (!getParams().imu.useOrientation) {
77  return;
78  }
79  // Can it and update the pose with it.
80  updatePoseFromMeasurement(tv, preprocessOrientation(tv, rawSmoothQuat));
81  }
83  util::time::TimeValue const &tv, Eigen::Quaterniond const &deltaquat,
84  double dt) {
85  if (!m_yawKnown) {
86  // No calibration yet, and angular velocity isn't useful there.
87  return;
88  }
89 
90  if (!m_useAngularVelocity) {
91  return;
92  }
93  // Can it and update the pose with it.
94  updatePoseFromMeasurement(tv,
95  preprocessAngularVelocity(tv, deltaquat, dt));
96  }
97 
98  Eigen::Quaterniond TrackedBodyIMU::transformRawIMUOrientation(
99  Eigen::Quaterniond const &input) const {
100  BOOST_ASSERT_MSG(
101  calibrationYawKnown(),
102  "transform called before calibration transform known!");
103  return m_yawCorrection * input;
104  // return input;
105  }
106 
107  Eigen::Quaterniond TrackedBodyIMU::transformRawIMUAngularVelocity(
108  Eigen::Quaterniond const &deltaquat) const {
109  BOOST_ASSERT_MSG(
110  calibrationYawKnown(),
111  "transform called before calibration transform known!");
113 
118  // return m_yawCorrection.inverse() * deltaquat * m_yawCorrection;
119  return deltaquat;
120  }
121 
122  CannedIMUMeasurement
123  TrackedBodyIMU::preprocessOrientation(util::time::TimeValue const &tv,
124  Eigen::Quaterniond const &quat) {
125 
126  auto ret = CannedIMUMeasurement{};
127  ret.setYawCorrection(m_yaw);
128  ret.setOrientation(transformRawIMUOrientation(quat),
129  Eigen::Vector3d::Constant(m_orientationVariance));
130  return ret;
131  }
132 
134  CannedIMUMeasurement TrackedBodyIMU::preprocessAngularVelocity(
135  util::time::TimeValue const &tv, Eigen::Quaterniond const &deltaquat,
136  double dt) {
137  Eigen::Vector3d rot =
138  incRotToAngVelVec(transformRawIMUAngularVelocity(deltaquat), dt);
139  auto ret = CannedIMUMeasurement{};
140  ret.setYawCorrection(m_yaw);
141  ret.setAngVel(rot,
142  Eigen::Vector3d::Constant(m_angularVelocityVariance));
143  return ret;
144  }
145 
146  bool TrackedBodyIMU::updatePoseFromMeasurement(
147  util::time::TimeValue const &tv, CannedIMUMeasurement const &meas) {
148  if (!meas.orientationValid() && !meas.angVelValid()) {
149  return false;
150  }
151  getBody().incorporateNewMeasurementFromIMU(tv, meas);
152  return true;
153  }
154 
155  ConfigParams const &TrackedBodyIMU::getParams() const {
156  return getBody().getParams();
157  }
158 } // namespace vbtracker
159 } // namespace osvr
void updatePoseFromOrientation(util::time::TimeValue const &tv, Eigen::Quaterniond const &quat)
Processes an orientation.
::OSVR_TimeValue TimeValue
C++-friendly typedef for the OSVR_TimeValue structure.
Definition: TimeValue.h:48
ConfigParams const & getParams() const
Definition: TrackedBody.cpp:96
void updatePoseFromAngularVelocity(util::time::TimeValue const &tv, Eigen::Quaterniond const &deltaquat, double dt)
Processes an angular velocity.
Standardized, portable parallel to struct timeval for representing both absolute times and time inter...
Definition: TimeValueC.h:81
void calibrationHandleIMUData(BodyId id, util::time::TimeValue const &tv, Eigen::Quaterniond const &quat)
void incorporateNewMeasurementFromIMU(util::time::TimeValue const &tv, CannedIMUMeasurement const &meas)