OSVR Framework (Internal Development Docs)  0.6-1962-g59773924
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
ThreadsafeBodyReporting.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
27 #include "AngVelTools.h"
28 
29 // Library/third-party includes
31 #include <osvr/Util/EigenInterop.h>
34 
35 // Standard includes
36 // - none
37 
38 namespace osvr {
39 namespace vbtracker {
40  static const double VELOCITY_DT = 0.02;
41  static const std::size_t REPORT_QUEUE_SIZE = 16;
42 
48  template <typename Derived>
49  inline Eigen::Quaterniond
50  angVelVecToQuat(Eigen::Quaterniond const &orientation, double dt,
51  Eigen::MatrixBase<Derived> const &vec) {
52  EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Derived, 3);
53 
54  Eigen::Quaterniond result =
55  orientation * angVelVecToIncRot(vec, dt) * orientation.conjugate();
56  return result;
57  }
58 
61  inline void
62  assignStateToBodyReport(BodyState const &state, BodyReport &report,
63  Eigen::Isometry3d const &trackerToRoom) {
64  Eigen::Isometry3d output = trackerToRoom * state.getIsometry();
65  Eigen::Quaterniond orientation =
66  Eigen::Quaterniond(output.rotation()).normalized();
67  util::eigen_interop::map(report.pose).rotation() = orientation;
68  util::eigen_interop::map(report.pose).translation() =
69  output.translation();
70 
71  util::eigen_interop::map(
72  report.vel.angularVelocity.incrementalRotation) =
73  angVelVecToQuat(orientation, VELOCITY_DT, state.angularVelocity());
74  report.vel.angularVelocity.dt = VELOCITY_DT;
75  report.vel.angularVelocityValid = OSVR_TRUE;
76 
77  util::eigen_interop::map(report.vel.linearVelocity) =
78  trackerToRoom * state.velocity();
79  report.vel.linearVelocityValid = OSVR_TRUE;
80  }
81 
82  std::unique_ptr<BodyReporting> BodyReporting::make() {
83  std::unique_ptr<BodyReporting> ret(new BodyReporting);
84  return ret;
85  }
86 
87  bool BodyReporting::getReport(double additionalPrediction,
88  BodyReport &report) {
89 
90  QueueValueType queueVal;
91  bool gotOne = false;
92  // Read all the queued-up states, but only keep the most recent one.
93  while (m_queue.read(queueVal)) {
94  gotOne = true;
95  }
96  if (!gotOne) {
97  return false;
98  }
99 
101  m_dataTime = queueVal.timestamp;
102  Eigen::Map<QueueValueVec> valMap(queueVal.stateData.data());
103  m_state.incrementalOrientation() = Eigen::Vector3d::Zero();
104  m_state.position() = valMap.head<3>();
105  m_state.setQuaternion(Eigen::Quaterniond(valMap.segment<4>(3)));
106  m_state.velocity() = valMap.segment<3>(7);
107  m_state.angularVelocity() = valMap.tail<3>();
108 
109  // If we have a process model, and have non-zero velocity, then we can
110  // do some prediction.
111  bool doingPrediction =
112  m_hasProcessModel && (m_state.stateVector().tail<6>() !=
114 
115  if (doingPrediction) {
116  // If we have non-zero velocity, then we can do some prediction.
117  auto currentTime = util::time::getNow();
119  auto dt = osvrTimeValueDurationSeconds(&currentTime, &m_dataTime);
121  dt += additionalPrediction;
122 
125  m_state.setStateVector(m_process.computeEstimate(m_state, dt));
127  m_state.postCorrect();
128 
130  report.timestamp = currentTime + std::chrono::duration<double>(
131  additionalPrediction);
132  } else {
133  report.timestamp = m_dataTime;
134  }
135  assignStateToBodyReport(m_state, report, m_trackerToRoom);
136  report.status = ReportStatus::Valid;
137  return true;
138  }
139 
141  BodyState const &state) {
142  QueueValueType val;
144  QueueValueVec::Map(val.stateData.data()) << state.position(),
145  state.getQuaternion().coeffs(), state.velocity(),
146  state.angularVelocity();
147 
148  val.timestamp = tv;
149  return m_queue.write(std::move(val));
150  }
151 
153  m_process = process;
154  m_hasProcessModel = true;
155  }
156 
157  void
158  BodyReporting::setTrackerToRoomTransform(Eigen::Isometry3d const &xform) {
159  m_trackerToRoom = xform;
160  }
161 
162  BodyReporting::BodyReporting()
163  : m_trackerToRoom(Eigen::Isometry3d::Identity()),
164  m_queue(REPORT_QUEUE_SIZE) {}
165 
166 } // namespace vbtracker
167 } // namespace osvr
Eigen::Matrix< Scalar, n, 1 > Vector
A vector of length n.
OSVR_EXTERN_C_END double osvrTimeValueDurationSeconds(const OSVR_TimeValue *tvA, const OSVR_TimeValue *tvB)
Compute the difference between the two time values, returning the duration as a double-precision floa...
Definition: TimeValueC.h:185
StateVector const & stateVector() const
xhat
Definition: PoseState.h:177
void setQuaternion(Eigen::Quaterniond const &quaternion)
Intended for startup use.
Definition: PoseState.h:189
bool getReport(double additionalPrediction, BodyReport &report)
void getNow(TimeValue &tv)
Set the given TimeValue to the current time.
Definition: TimeValue.h:51
Header wrapping include of and for warning quieting.
#define OSVR_TRUE
Canonical "true" value for OSVR_CBool.
Definition: BoolC.h:52
void setTrackerToRoomTransform(Eigen::Isometry3d const &xform)
bool updateState(util::time::TimeValue const &tv, BodyState const &state)
static std::unique_ptr< BodyReporting > make()
Factory function.
Header for interoperation between the Eigen math library, the internal mini math library, and VRPN's quatlib.
void initProcessModel(BodyProcessModel const &process)
Standardized, portable parallel to struct timeval for representing both absolute times and time inter...
Definition: TimeValueC.h:81
void setStateVector(StateVector const &state)
set xhat
Definition: PoseState.h:175