OSVR Framework (Internal Development Docs)  0.6-1962-g59773924
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
TrackerRemoteFactory.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 // Internal Includes
26 #include "TrackerRemoteFactory.h"
27 #include "PureClientContext.h"
28 #include "RemoteHandlerInternals.h"
35 #include <osvr/Common/Tracing.h>
37 #include <osvr/Common/Transform.h>
39 #include <osvr/Util/EigenInterop.h>
41 #include <osvr/Util/UniquePtr.h>
42 #include <osvr/Util/Verbosity.h>
43 
44 // Library/third-party includes
45 #include <boost/any.hpp>
46 #include <boost/lexical_cast.hpp>
47 #include <boost/variant/get.hpp>
48 #include <json/reader.h>
49 #include <json/value.h>
50 #include <vrpn_Tracker.h>
51 
52 // Standard includes
53 // - none
54 
55 namespace ei = osvr::util::eigen_interop;
56 
57 namespace osvr {
58 namespace client {
60  public:
61  struct Options {
62  bool reportPose = false;
63  bool reportPosition = false;
64  bool reportOrientation = false;
65  };
66  VRPNTrackerHandler(vrpn_ConnectionPtr const &conn, const char *src,
67  Options const &options,
68  common::TrackerSensorInfo const &info,
69  common::Transform const &t,
70  boost::optional<int> sensor,
71  common::InterfaceList &ifaces,
73  : m_remote(new vrpn_Tracker_Remote(src, conn.get())),
74  m_transform(t), m_ctx(ctx), m_internals(ifaces), m_opts(options),
75  m_info(info), m_sensor(sensor) {
76  if (m_info.reportsPosition || m_info.reportsOrientation) {
77  m_remote->register_change_handler(this,
78  &VRPNTrackerHandler::handle,
79  m_sensor.get_value_or(-1));
80  }
81  if (m_info.reportsLinearVelocity || m_info.reportsAngularVelocity) {
82  m_remote->register_change_handler(
83  this, &VRPNTrackerHandler::handleVel,
84  m_sensor.get_value_or(-1));
85  }
86  if (m_info.reportsLinearAcceleration ||
87  m_info.reportsAngularAcceleration) {
88  m_remote->register_change_handler(
89  this, &VRPNTrackerHandler::handleAccel,
90  m_sensor.get_value_or(-1));
91  }
92  OSVR_DEV_VERBOSE("Constructed a TrackerHandler for "
93  << src << " sensor " << m_sensor.get_value_or(-1));
94  }
95  virtual ~VRPNTrackerHandler() {
96  if (m_info.reportsPosition || m_info.reportsOrientation) {
97  m_remote->unregister_change_handler(this,
98  &VRPNTrackerHandler::handle,
99  m_sensor.get_value_or(-1));
100  }
101  if (m_info.reportsLinearVelocity || m_info.reportsAngularVelocity) {
102  m_remote->unregister_change_handler(
103  this, &VRPNTrackerHandler::handleVel,
104  m_sensor.get_value_or(-1));
105  }
106  if (m_info.reportsLinearAcceleration ||
107  m_info.reportsAngularAcceleration) {
108  m_remote->unregister_change_handler(
109  this, &VRPNTrackerHandler::handleAccel,
110  m_sensor.get_value_or(-1));
111  }
112  }
113 
114  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
115 
116  common::Transform getCurrentTransform() const {
117  auto ret = m_transform;
118  ret.transform(m_ctx.getRoomToWorldTransform());
119  return ret;
120  }
121 
122  static void VRPN_CALLBACK handle(void *userdata, vrpn_TRACKERCB info) {
123  auto self = static_cast<VRPNTrackerHandler *>(userdata);
124  self->m_handle(info);
125  }
126  static void VRPN_CALLBACK handleVel(void *userdata,
127  vrpn_TRACKERVELCB info) {
128  auto self = static_cast<VRPNTrackerHandler *>(userdata);
129  self->m_handle(info);
130  }
131  static void VRPN_CALLBACK handleAccel(void *userdata,
132  vrpn_TRACKERACCCB info) {
133  auto self = static_cast<VRPNTrackerHandler *>(userdata);
134  self->m_handle(info);
135  }
136  virtual void update() { m_remote->mainloop(); }
137 
138  private:
140  void m_handle(vrpn_TRACKERCB const &info) {
141  common::tracing::markNewTrackerData();
142  OSVR_PoseReport report;
143  report.sensor = info.sensor;
144  OSVR_TimeValue timestamp;
145  osvrStructTimevalToTimeValue(&timestamp, &(info.msg_time));
146  osvrQuatFromQuatlib(&(report.pose.rotation), info.quat);
147  osvrVec3FromQuatlib(&(report.pose.translation), info.pos);
148  auto xform = getCurrentTransform();
149  ei::map(report.pose) =
150  xform.transform(ei::map(report.pose).matrix());
151 
152  if (m_opts.reportPose) {
153  m_internals.setStateAndTriggerCallbacks(timestamp, report);
154  }
155 
156  if (m_opts.reportPosition) {
157  OSVR_PositionReport positionReport;
158  positionReport.sensor = info.sensor;
159  positionReport.xyz = report.pose.translation;
160 
161  m_internals.setStateAndTriggerCallbacks(timestamp,
162  positionReport);
163  }
164 
165  if (m_opts.reportOrientation) {
166  OSVR_OrientationReport oriReport;
167  oriReport.sensor = info.sensor;
168  oriReport.rotation = report.pose.rotation;
169 
170  m_internals.setStateAndTriggerCallbacks(timestamp, oriReport);
171  }
172  }
173 
175  void m_handle(vrpn_TRACKERVELCB const &info) {
177  // common::tracing::markNewTrackerData();
178 
179  OSVR_TimeValue timestamp;
180  osvrStructTimevalToTimeValue(&timestamp, &(info.msg_time));
181 
182  OSVR_VelocityReport overallReport;
183  overallReport.sensor = info.sensor;
184  auto xform = getCurrentTransform();
185 
186  overallReport.state.linearVelocityValid =
187  m_info.reportsLinearVelocity;
188  if (m_info.reportsLinearVelocity) {
190  osvrVec3FromQuatlib(&(vel), info.vel);
191 
192  ei::map(vel) = xform.transformDerivative(ei::map(vel));
193 
194  overallReport.state.linearVelocity = vel;
196  report.sensor = info.sensor;
197  report.state = vel;
198  m_internals.setStateAndTriggerCallbacks(timestamp, report);
199  }
200 
201  overallReport.state.angularVelocityValid =
202  m_info.reportsAngularVelocity;
203  if (m_info.reportsAngularVelocity) {
205  osvrQuatFromQuatlib(&(state.incrementalRotation),
206  info.vel_quat);
207  state.dt = info.vel_quat_dt;
208 
209  ei::map(state.incrementalRotation) = xform.transformDerivative(
210  ei::map(state.incrementalRotation));
211 
212  overallReport.state.angularVelocity = state;
214  report.sensor = info.sensor;
215  report.state = state;
216  m_internals.setStateAndTriggerCallbacks(timestamp, report);
217  }
218 
219  m_internals.setStateAndTriggerCallbacks(timestamp, overallReport);
220  }
221 
223  void m_handle(vrpn_TRACKERACCCB const &info) {
225  // common::tracing::markNewTrackerData();
226  OSVR_TimeValue timestamp;
227  osvrStructTimevalToTimeValue(&timestamp, &(info.msg_time));
228 
229  OSVR_AccelerationReport overallReport;
230  overallReport.sensor = info.sensor;
231 
232  auto xform = getCurrentTransform();
233 
234  overallReport.state.linearAccelerationValid =
235  m_info.reportsLinearAcceleration;
236  if (m_info.reportsLinearAcceleration) {
238  osvrVec3FromQuatlib(&(accel), info.acc);
239 
240  ei::map(accel) = xform.transformDerivative(ei::map(accel));
241 
242  overallReport.state.linearAcceleration = accel;
244  report.sensor = info.sensor;
245  report.state = accel;
246  m_internals.setStateAndTriggerCallbacks(timestamp, report);
247  }
248  overallReport.state.angularAccelerationValid =
249  m_info.reportsAngularAcceleration;
250  if (m_info.reportsAngularAcceleration) {
251 
253  osvrQuatFromQuatlib(&(state.incrementalRotation),
254  info.acc_quat);
255  state.dt = info.acc_quat_dt;
256 
257  ei::map(state.incrementalRotation) = xform.transformDerivative(
258  ei::map(state.incrementalRotation));
259 
260  overallReport.state.angularAcceleration = state;
262  report.sensor = info.sensor;
263  report.state = state;
264  m_internals.setStateAndTriggerCallbacks(timestamp, report);
265  }
266 
267  m_internals.setStateAndTriggerCallbacks(timestamp, overallReport);
268  }
269  unique_ptr<vrpn_Tracker_Remote> m_remote;
270  common::Transform m_transform;
271  common::ClientContext &m_ctx;
272  RemoteHandlerInternals m_internals;
273  Options m_opts;
274  common::TrackerSensorInfo m_info;
275  boost::optional<int> m_sensor;
276  };
277 
278  TrackerRemoteFactory::TrackerRemoteFactory(
279  VRPNConnectionCollection const &conns)
280  : m_conns(conns) {}
281 
282  shared_ptr<RemoteHandler> TrackerRemoteFactory::
284  common::InterfaceList &ifaces, common::ClientContext &ctx) {
285 
286  shared_ptr<RemoteHandler> ret;
287 
288  auto info = common::getTrackerSensorInfo(source);
289 
295  opts.reportPose = info.reportsPosition || info.reportsOrientation;
296  opts.reportPosition = info.reportsPosition;
297  opts.reportOrientation = info.reportsOrientation;
298 
299  auto const &devElt = source.getDeviceElement();
300 
301  common::Transform xform{};
302  if (source.hasTransform()) {
303  common::JSONTransformVisitor xformParse(source.getTransformJson());
304  xform = xformParse.getTransform();
305  }
306 
308  ret.reset(new VRPNTrackerHandler(
309  m_conns.getConnection(devElt), devElt.getFullDeviceName().c_str(),
310  opts, info, xform, source.getSensorNumber(), ifaces, ctx));
311  return ret;
312  }
313 
314 } // namespace client
315 } // namespace osvr
int32_t sensor
Identifies the sensor that the report comes from.
void transform(Transform const &other)
Update this transformation by the application of another transformation around it.
Definition: Transform.h:64
The result of resolving a tree node to a device: either an original source to connect to...
OSVR_LinearAccelerationState state
The state itself.
OSVR_PoseState pose
The pose structure, containing a position vector and a rotation quaternion.
OSVR_CBool linearAccelerationValid
Whether the data source reports valid data for #OSVR_AccelerationState::linearAcceleration.
OSVR_LinearVelocityState state
The state itself.
Report type for a linear acceleration callback on a tracker interface.
OSVR_AngularVelocityState state
The state itself.
osvr::common::Transform const & getRoomToWorldTransform() const
Gets the transform from room space to world space.
A structure defining a 3D vector, often a position/translation.
Definition: Vec3C.h:48
Header including PathTree.h and all additional headers needed to define related types.
fully-resolved data about a tracker sensor. Defaults per the schema.
OSVR_Quaternion rotation
Orientation as a unit quaternion.
Definition: Pose3C.h:58
int32_t sensor
Identifies the sensor that the report comes from.
Header to bring unique_ptr into the osvr namespace.
The quaternion represents the incremental rotation taking place over a period of dt seconds...
int32_t sensor
Identifies the sensor that the report comes from.
Report type for an acceleration (linear and angular) callback on a tracker interface.
Header.
shared_ptr< RemoteHandler > operator()(common::OriginalSource const &source, common::InterfaceList &ifaces, common::ClientContext &ctx)
TrackerSensorInfo getTrackerSensorInfo(OriginalSource const &source)
int32_t sensor
Identifies the sensor that the report comes from.
TransformType transform() const
Read-only accessor for the pose as an Eigen transform.
Definition: EigenInterop.h:280
int32_t sensor
Identifies the sensor that the report comes from.
Report type for an orientation callback on a tracker interface.
OSVR_CBool linearVelocityValid
Whether the data source reports valid data for #OSVR_VelocityState::linearVelocity.
void setStateAndTriggerCallbacks(const OSVR_TimeValue &timestamp, ReportType const &report)
Set state and call callbacks for a report type.
Report type for an angular acceleration callback on a tracker interface.
OSVR_CBool angularVelocityValid
Whether the data source reports valid data for #OSVR_VelocityState::angularVelocity.
OSVR_VelocityState state
The data state - note that not all fields are neccesarily valid, use the Valid members to check the s...
OSVR_AngularAccelerationState state
The state itself.
void osvrStructTimevalToTimeValue(OSVR_TimeValue *dest, const struct timeval *src)
Converts from a TimeValue struct to your system's struct timeval.
Internal, configured header file for verbosity macros.
int32_t sensor
Identifies the sensor that the report comes from.
Header.
Header for interoperation between the Eigen math library, the internal mini math library, and VRPN's quatlib.
OSVR_PositionState xyz
The position vector.
Report type for a position callback on a tracker interface.
Report type for a velocity (linear and angular) callback on a tracker interface.
int32_t sensor
Identifies the sensor that the report comes from.
Report type for an angular velocity callback on a tracker interface.
int32_t sensor
Identifies the sensor that the report comes from.
Standardized, portable parallel to struct timeval for representing both absolute times and time inter...
Definition: TimeValueC.h:81
int32_t sensor
Identifies the sensor that the report comes from.
OSVR_OrientationState rotation
The rotation unit quaternion.
OSVR_AccelerationState state
The data state - note that not all fields are neccesarily valid, use the Valid members to check the s...
Base class for remote device handler classes.
Definition: RemoteHandler.h:40
Spatial transformation, consisting of both pre and post components.
Definition: Transform.h:44
OSVR_Vec3 translation
Position vector.
Definition: Pose3C.h:56
Report type for a linear velocity callback on a tracker interface.
OSVR_CBool angularAccelerationValid
Whether the data source reports valid data for #OSVR_AccelerationState::angularAcceleration.
Report type for a pose (position and orientation) callback on a tracker interface.