vrpn  07.33
Virtual Reality Peripheral Network
vrpn_Tracker_WiimoteHead.C
Go to the documentation of this file.
1 
15 /*
16  Copyright Iowa State University 2009-2010
17  Distributed under the Boost Software License, Version 1.0.
18  (See accompanying comment below or copy at
19  http://www.boost.org/LICENSE_1_0.txt)
20 
21  Boost Software License - Version 1.0 - August 17th, 2003
22 
23  Permission is hereby granted, free of charge, to any person or organization
24  obtaining a copy of the software and accompanying documentation covered by
25  this license (the "Software") to use, reproduce, display, distribute,
26  execute, and transmit the Software, and to prepare derivative works of the
27  Software, and to permit third-parties to whom the Software is furnished to
28  do so, all subject to the following:
29 
30  The copyright notices in the Software and this entire statement, including
31  the above license grant, this restriction and the following disclaimer,
32  must be included in all copies of the Software, in whole or in part, and
33  all derivative works of the Software, unless such copies or derivative
34  works are solely in the form of machine-executable object code generated by
35  a source language processor.
36 
37  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
38  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
39  FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
40  SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
41  FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
42  ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
43  DEALINGS IN THE SOFTWARE.
44 */
45 
46 
47 
48 // Local Includes
49 #include "quat.h" // for q_xyz_quat_type, q_vec_copy, etc
50 #include "vrpn_Connection.h" // for vrpn_Connection, etc
52 #include "vrpn_Types.h" // for vrpn_float64
53 
54 // Standard includes
55 #include <math.h> // for tan, atan2, sqrt
56 #include <stdio.h> // for NULL, fprintf, stderr
57 #include <algorithm> // for swap
58 #include <iostream> // for operator<<, basic_ostream, etc
59 
60 #undef VERBOSE
61 
64 inline static bool wm_isnan(const double x) {
65  return (x != x);
66 }
67 
70 const double two = 2;
71 
72 // Some stats source: http://wiibrew.org/wiki/Wiimote#IR_Camera
73 const double xResSensor = 1024.0, yResSensor = 768.0;
74 
77 const double fovX = Q_DEG_TO_RAD(43.0), fovY = Q_DEG_TO_RAD(32.00);
78 //const double fovX = Q_DEG_TO_RAD(45.0), fovY = (fovX / xResSensor) * yResSensor;
79 
80 const double radPerPx = fovX / xResSensor;
81 const double cvtDistToAngle = radPerPx / two;
83 
86 #define MAKE_IDENTITY_QUAT(dest) \
87  dest[0] = dest[1] = dest[2] = 0; dest[3] = 1
88 
91 #define MAKE_NULL_VEC(dest) \
92  dest[0] = dest[1] = dest[2] = 0
93 
94 
96  vrpn_Connection* trackercon,
97  const char* wiimote,
98  float update_rate,
99  float led_spacing) :
100  vrpn_Tracker(name, trackercon),
101  d_name(wiimote),
102  d_update_interval(update_rate ? (1.0 / update_rate) : 1.0 / 60.0),
103  d_blobDistance(led_spacing),
104  d_flipState(FLIP_UNKNOWN),
105  d_points(0),
106  d_ana(NULL),
107  d_contact(false),
108  d_lock(false),
109  d_updated(false),
110  d_gravDirty(true) {
111  // If the name is NULL, we're done.
112  if (wiimote == NULL) {
113  d_name = NULL;
114  fprintf(stderr, "vrpn_Tracker_WiimoteHead: "
115  "Can't start without a valid specified Wiimote device!");
116  return;
117  }
118 
119  setup_wiimote();
120 
121  //--------------------------------------------------------------------
122  // Whenever we get a connection, set a flag so we make sure to send an
123  // update. Set up a handler to do this.
125  handle_connection, this);
126 
127  //--------------------------------------------------------------------
128  // Set the current matrix to identity, the current timestamp to "now",
129  // the current matrix to identity in case we never hear from the Wiimote.
130  // Also, set the updated flag to send a single report
131  reset();
132 
133  // put a little z translation as a saner default
134  d_currentPose.xyz[2] = 1;
135 
136  // Set up our initial "default" pose to make sure everything is
137  // safely initialized before our first report.
139 }
140 
142 
143  // If the analog pointer is NULL, we're done.
144  if (d_ana == NULL) {
145  return;
146  }
147 
148  // Turn off the callback handler
149  int ret;
151 
152  // Delete the analog device.
153  delete d_ana;
154  d_ana = NULL;
155 }
156 
161  _reset_gravity();
162  _reset_pose();
163  _reset_points();
164 }
165 
167  if (d_ana) {
168  // Turn off the callback handler and delete old analog
169  // if we already have an analog source
171  delete d_ana;
172  d_ana = NULL;
173  }
174 
175  // Open the analog device and point the remote at it.
176  // If the name starts with the '*' character, use the server
177  // connection rather than making a new one.
178  if (d_name[0] == '*') {
180  } else {
182  }
183 
184  if (d_ana == NULL) {
185  fprintf(stderr, "vrpn_Tracker_WiimoteHead: "
186  "Can't open Analog %s\n", d_name);
187  return;
188  }
189 
190  // register callback
192  if (ret == -1) {
193  fprintf(stderr, "vrpn_Tracker_WiimoteHead: "
194  "Can't setup change handler on Analog %s\n", d_name);
195  delete d_ana;
196  d_ana = NULL;
197  return;
198  }
199 
200  // will notify when we catch the first report.
201  d_contact = false;
202 }
203 
205  struct timeval now;
206 
207  // Call generic server mainloop, since we are a server
208  server_mainloop();
209 
210  // Mainloop() the wiimote to get fresh values
211  if (d_ana != NULL) {
212  d_ana->mainloop();
213  }
214 
215  // See if we have new data, or if it has been too long since our last
216  // report. Send a new report in either case.
217  vrpn_gettimeofday(&now, NULL);
218  double interval = vrpn_TimevalDurationSeconds(now, d_prevtime);
219 
220  if (_should_report(interval)) {
221  // Figure out the new matrix based on the current values and
222  // the length of the interval since the last report
223  update_pose();
224 
225  report();
226  }
227 }
228 
230  q_xyz_quat_type newPose;
231 
232  // Start at the identity pose
233  MAKE_NULL_VEC(newPose.xyz);
234  MAKE_IDENTITY_QUAT(newPose.quat);
235 
236  // If our gravity vector has changed and it's not 0,
237  // we need to update our gravity correction transform.
238  if (d_gravDirty && _have_gravity()) {
240  }
241 
242  // Update pose estimate
243  _update_2_LED_pose(newPose);
244 
245  if (d_lock) {
246  // Gravity correction
247  if (_have_gravity()) {
248  q_xyz_quat_compose(&d_currentPose, &d_currentPose, &d_gravityXform);
249  }
250 
251  if (d_flipState == FLIP_UNKNOWN) {
253  if (d_flipState == FLIP_180) {
254  return; // must throw away first update after setting flip to 180
255  }
256  }
257 
258  // Copy final pose into the tracker position and quaternion structures.
260  }
261 }
262 
264  // pack and deliver tracker report;
265  if (d_connection) {
266  char msgbuf[1000];
267  int len = encode_to(msgbuf);
269  position_m_id, d_sender_id, msgbuf,
271  fprintf(stderr, "vrpn_Tracker_WiimoteHead: "
272  "cannot write message: tossing\n");
273  }
274  } else {
275  fprintf(stderr, "vrpn_Tracker_WiimoteHead: "
276  "No valid connection\n");
277  }
278 
279  // We just sent a report, so reset the time
281  d_updated = false;
282 }
283 
284 // static
285 void vrpn_Tracker_WiimoteHead::handle_analog_update(void* userdata, const vrpn_ANALOGCB info) {
287 
288  if (!wh) {
289  return;
290  }
291  if (!wh->d_contact) {
292 #ifdef VERBOSE
293  fprintf(stderr, "vrpn_Tracker_WiimoteHead: "
294  "got first report from Wiimote!\n");
295 #endif
296  }
297 
298  int i, firstchan;
299  // Grab all the blobs
300  for (i = 0; i < 4; i++) {
301  firstchan = i * 3 + 4;
302  // -1 should signal a missing blob, but experimentally
303  // we sometimes get 0 instead
304  if (info.channel[firstchan] > 0
305  && info.channel[firstchan + 1] > 0
306  && info.channel[firstchan + 2] > 0) {
307  wh->d_vX[i] = info.channel[firstchan];
308  wh->d_vY[i] = info.channel[firstchan + 1];
309  wh->d_vSize[i] = info.channel[firstchan + 2];
310  wh->d_points = i + 1;
311  } else {
312  break;
313  }
314  }
315 
316  wh->d_contact = true;
317  wh->d_updated = true;
318 
319  bool newgrav = false;
320 
321  // Grab gravity
322  for (i = 0; i < 3; i++) {
323  if (info.channel[1 + i] != wh->d_vGrav[i]) {
324  newgrav = true;
325  break;
326  }
327  }
328 
329  if (newgrav) {
330  if (!wh->d_gravDirty) {
331  // only slide back the previous gravity if we actually used it once.
332  q_vec_copy(wh->d_vGravAntepenultimate, wh->d_vGravPenultimate);
333  q_vec_copy(wh->d_vGravPenultimate, wh->d_vGrav);
334  }
335  for (i = 0; i < 3; i++) {
336  wh->d_vGrav[i] = info.channel[1 + i];
337  }
338  wh->d_gravDirty = true;
339  }
340 
341  // Store the time of the report into the tracker's timestamp field.
342  wh->vrpn_Tracker::timestamp = info.msg_time;
343 }
344 
345 // static
348 
349  // Indicate that we should send a report with whatever we have.
350  wh->d_updated = true;
351 
352  // Always return 0 here, because nonzero return means that the input data
353  // was garbage, not that there was an error. If we return nonzero from a
354  // vrpn_Connection handler, it shuts down the connection.
355  return 0;
356 }
357 
359  // Moving average of last three gravity vectors
361  q_vec_type movingAvg = Q_NULL_VECTOR;
362 
363  q_vec_copy(movingAvg, d_vGrav);
364  q_vec_add(movingAvg, movingAvg, d_vGravPenultimate);
365  q_vec_add(movingAvg, movingAvg, d_vGravAntepenultimate);
366  q_vec_scale(movingAvg, 0.33333, movingAvg);
367 
368  // reset gravity transform
371 
372  q_vec_type regulargravity = Q_NULL_VECTOR;
373  regulargravity[2] = 1;
374 
375  q_from_two_vecs(d_gravityXform.quat, movingAvg, regulargravity);
376  d_gravDirty = false;
377 }
378 
379 void vrpn_Tracker_WiimoteHead::_update_2_LED_pose(q_xyz_quat_type & newPose) {
380  if (d_points != 2) {
381  // we simply stop updating our pos+orientation if we lost LED's
382  // TODO: right now if we don't have exactly 2 points we lose the lock
383  d_lock = false;
385  return;
386  }
387 
388  // TODO right now only handling the 2-LED glasses
389 
390  d_lock = true;
391  double rx, ry, rz;
392  rx = ry = rz = 0;
393 
394  double X0, X1, Y0, Y1;
395 
396  X0 = d_vX[0];
397  X1 = d_vX[1];
398  Y0 = d_vY[0];
399  Y1 = d_vY[1];
400 
401  if (d_flipState == FLIP_180) {
408  std::swap(X0, X1);
409  std::swap(Y0, Y1);
410  }
411 
412  const double dx = X0 - X1;
413  const double dy = Y0 - Y1;
414  const double dist = sqrt(dx * dx + dy * dy);
415  const double angle = dist * cvtDistToAngle;
416  // Note that this is an approximation, since we don't know the
417  // distance/horizontal position. (I think...)
418 
419  const double headDist = (d_blobDistance / 2.0) / tan(angle);
420 
421  // Translate the distance along z axis, and tilt the head
422  newPose.xyz[2] = headDist; // translate along Z
423  rz = atan2(dy, dx); // rotate around Z
424 
425  // Find the sensor pixel of the line of sight - directly between
426  // the LEDs
427  const double avgX = (X0 + X1) / 2.0;
428  const double avgY = (Y0 + Y1) / 2.0;
429 
434  if (wm_isnan(avgX)) {
435  std::cerr << "NaN detected in avgX: X0 = " << X0 << ", X1 = " << X1 << std::endl;
436  return;
437  }
438 
439  if (wm_isnan(avgY)) {
440  std::cerr << "NaN detected in avgY: Y0 = " << Y0 << ", Y1 = " << Y1 << std::endl;
441  return;
442  }
443 
444  // b is the virtual depth in the sensor from a point to the full sensor
445  // used for finding similar triangles to calculate x/y translation
446  const double bHoriz = xResSensor / 2 / tan(fovX / 2);
447  const double bVert = yResSensor / 2 / tan(fovY / 2);
448 
449  // World head displacement (X and Y) from a centered origin at
450  // the calculated distance from the sensor
451  newPose.xyz[0] = headDist * (avgX - xResSensor / 2) / bHoriz;
452  newPose.xyz[1] = headDist * (avgY - yResSensor / 2) / bVert;
453 
454  // set the quat. part of our pose with rotation angles
455  q_from_euler(newPose.quat, rz, ry, rx);
456 
457  // Apply the new pose
458  q_vec_copy(d_currentPose.xyz, newPose.xyz);
459  q_copy(d_currentPose.quat, newPose.quat);
460 }
461 
463  if (d_flipState != FLIP_UNKNOWN) {
464  return;
465  }
466 
467  q_vec_type upVec = {0, 1, 0};
468 
469  q_xform(upVec, d_currentPose.quat, upVec);
470  if (upVec[1] < 0) {
471  // We are upside down - we will need to rotate 180 about the sensor Z
472  // Must recalculate now.
473 #ifdef VERBOSE
474  fprintf(stderr, "vrpn_Tracker_WiimoteHead: d_flipState = FLIP_180\n");
475 #endif
477  update_pose();
478  } else {
479  // OK, we are fine - there is a positive Y component to our up vector
480 #ifdef VERBOSE
481  fprintf(stderr, "vrpn_Tracker_WiimoteHead: d_flipState = FLIP_NORMAL\n");
482 #endif
484  }
485 }
486 
488  q_vec_copy(pos, d_currentPose.xyz); // set position;
489  q_copy(d_quat, d_currentPose.quat); // set orientation
490 }
491 
492 
496 
500 
501  // Default earth gravity is (0, 1, 0)
503 
504  d_gravDirty = true;
505 }
506 
508  d_vX[0] = d_vX[1] = d_vX[2] = d_vX[3] = -1;
509  d_vY[0] = d_vY[1] = d_vY[2] = d_vY[3] = -1;
510  d_vSize[0] = d_vSize[1] = d_vSize[2] = d_vSize[3] = -1;
511  d_points = 0;
512 
513 
515  d_lock = false;
516 }
517 
519  // Reset to the identity pose
522 
524 
525  // Set the updated flag to send a report
526  d_updated = true;
528  d_lock = false;
529 
530  // Convert the matrix into quaternion notation and copy into the
531  // tracker pos and quat elements.
533 }
534 
535 bool vrpn_Tracker_WiimoteHead::_should_report(double elapsedInterval) const {
536  // If we've gotten new wiimote reports since our last report, return true.
537  if (d_updated) {
538  return true;
539  }
540 
541  // If it's been more than our max interval, send an update anyway
542  if (elapsedInterval >= d_update_interval) {
543  return true;
544  }
545 
546  // Not time has elapsed, and nothing has changed, so return false.
547  return false;
548 }
549 
551  return (d_vGrav[0] != 0 || d_vGrav[1] != 1 || d_vGrav[2] != 0);
552 }
vrpn_Tracker_WiimoteHead.h
vrpn_Tracker interface provided by processing Wii Remote data for head tracking.
fovX
const double fovX
Field of view experimentally determined at Iowa State University March 2010.
Definition: vrpn_Tracker_WiimoteHead.C:77
vrpn_BaseClassUnique::register_autodeleted_handler
int register_autodeleted_handler(vrpn_int32 type, vrpn_MESSAGEHANDLER handler, void *userdata, vrpn_int32 sender=vrpn_ANY_SENDER)
Registers a handler with the connection, and remembers to delete at destruction.
Definition: vrpn_BaseClass.C:503
vrpn_Connection::pack_message
virtual int pack_message(vrpn_uint32 len, struct timeval time, vrpn_int32 type, vrpn_int32 sender, const char *buffer, vrpn_uint32 class_of_service)
Pack a message that will be sent the next time mainloop() is called. Turn off the RELIABLE flag if yo...
Definition: vrpn_Connection.C:4632
vrpn_Tracker
Definition: vrpn_Tracker.h:49
vrpn_Tracker_WiimoteHead::d_blobDistance
const double d_blobDistance
distance between LEDs on glasses, in meters
Definition: vrpn_Tracker_WiimoteHead.h:185
vrpn_got_connection
const char * vrpn_got_connection
Definition: vrpn_Connection.C:185
vrpn_Tracker_WiimoteHead::reset
virtual void reset()
reset pose, gravity transform, and cached points and gravity
Definition: vrpn_Tracker_WiimoteHead.C:160
vrpn_Tracker::encode_to
virtual int encode_to(char *buf)
Definition: vrpn_Tracker.C:533
vrpn_Tracker_WiimoteHead::d_name
const char * d_name
Tracker device name.
Definition: vrpn_Tracker_WiimoteHead.h:179
vrpn_Tracker_WiimoteHead::~vrpn_Tracker_WiimoteHead
virtual ~vrpn_Tracker_WiimoteHead()
destructor
Definition: vrpn_Tracker_WiimoteHead.C:141
vrpn_Types.h
vrpn_TimevalDurationSeconds
double vrpn_TimevalDurationSeconds(struct timeval endT, struct timeval startT)
Return the number of seconds between startT and endT as a floating-point value.
Definition: vrpn_Shared.C:135
vrpn_Tracker_WiimoteHead::setup_wiimote
void setup_wiimote()
set up connection to wiimote-like analog device
Definition: vrpn_Tracker_WiimoteHead.C:166
vrpn_Tracker_WiimoteHead::d_gravityXform
q_xyz_quat_type d_gravityXform
Gravity correction transformation.
Definition: vrpn_Tracker_WiimoteHead.h:213
vrpn_Tracker_WiimoteHead::_reset_gravity
void _reset_gravity()
reset gravity transform and cached gravity vectors
Definition: vrpn_Tracker_WiimoteHead.C:493
vrpn_Tracker_WiimoteHead::d_vSize
double d_vSize[4]
Definition: vrpn_Tracker_WiimoteHead.h:198
vrpn_Analog_Remote
Definition: vrpn_Analog.h:181
vrpn_BaseClassUnique::userdata
void * userdata
Definition: vrpn_BaseClass.h:287
vrpn_Tracker_WiimoteHead::_reset_points
void _reset_points()
reset cached points, point count, and flip state,
Definition: vrpn_Tracker_WiimoteHead.C:507
vrpn_Tracker::d_quat
vrpn_float64 d_quat[4]
Definition: vrpn_Tracker.h:95
vrpn_Tracker_WiimoteHead::d_vGravPenultimate
q_vec_type d_vGravPenultimate
Definition: vrpn_Tracker_WiimoteHead.h:235
vrpn_Tracker_WiimoteHead::handle_connection
static int VRPN_CALLBACK VRPN_CALLBACK handle_connection(void *, vrpn_HANDLERPARAM)
Callback triggered when a new client connects to the tracker.
Definition: vrpn_Tracker_WiimoteHead.C:346
vrpn_Tracker_WiimoteHead::_update_gravity_moving_avg
void _update_gravity_moving_avg()
based on cached gravity data, use a moving average to update the tracker's stored gravity transform.
Definition: vrpn_Tracker_WiimoteHead.C:358
xResSensor
const double xResSensor
Definition: vrpn_Tracker_WiimoteHead.C:73
vrpn_Tracker::timestamp
struct timeval timestamp
Definition: vrpn_Tracker.h:100
MAKE_IDENTITY_QUAT
#define MAKE_IDENTITY_QUAT(dest)
Utility function to set a quat equal to the identity rotation.
Definition: vrpn_Tracker_WiimoteHead.C:86
MAKE_NULL_VEC
#define MAKE_NULL_VEC(dest)
Utility function to set a 3-vector equal to the zero vector.
Definition: vrpn_Tracker_WiimoteHead.C:91
vrpn_Tracker_WiimoteHead::d_ana
vrpn_Analog_Remote * d_ana
Source of analog data, traditionally vrpn_WiiMote Must present analog channels in this order:
Definition: vrpn_Tracker_WiimoteHead.h:209
vrpn_Tracker_WiimoteHead::FLIP_180
@ FLIP_180
Definition: vrpn_Tracker_WiimoteHead.h:187
vrpn_Tracker_WiimoteHead::d_update_interval
const double d_update_interval
maximum time between updates, in seconds
Definition: vrpn_Tracker_WiimoteHead.h:182
vrpn_CONNECTION_LOW_LATENCY
const vrpn_uint32 vrpn_CONNECTION_LOW_LATENCY
Definition: vrpn_Connection.h:122
vrpn_BaseClassUnique::d_connection
vrpn_Connection * d_connection
Connection that this object talks to.
Definition: vrpn_BaseClass.h:224
vrpn_Tracker_WiimoteHead::d_currentPose
q_xyz_quat_type d_currentPose
Current pose estimate.
Definition: vrpn_Tracker_WiimoteHead.h:216
vrpn_Connection::register_message_type
virtual vrpn_int32 register_message_type(const char *name)
Definition: vrpn_Connection.C:5074
vrpn_Tracker_WiimoteHead::d_contact
bool d_contact
Flag: Have we received the first message from the Wiimote?
Definition: vrpn_Tracker_WiimoteHead.h:221
fovY
const double fovY
Definition: vrpn_Tracker_WiimoteHead.C:77
vrpn_Tracker_WiimoteHead::d_vX
double d_vX[4]
Definition: vrpn_Tracker_WiimoteHead.h:196
vrpn_Tracker_WiimoteHead::_should_report
bool _should_report(double elapsedInterval) const
return true if we have new data or max time elapsed
Definition: vrpn_Tracker_WiimoteHead.C:535
vrpn_HANDLERPARAM
This structure is what is passed to a vrpn_Connection message callback.
Definition: vrpn_Connection.h:44
vrpn_Tracker_WiimoteHead::d_vY
double d_vY[4]
Definition: vrpn_Tracker_WiimoteHead.h:197
vrpn_Tracker_WiimoteHead::update_pose
void update_pose()
function to drive the full pose update process
Definition: vrpn_Tracker_WiimoteHead.C:229
vrpn_BaseClassUnique::d_sender_id
vrpn_int32 d_sender_id
Sender ID registered with the connection.
Definition: vrpn_BaseClass.h:228
vrpn_Tracker_WiimoteHead::_update_2_LED_pose
void _update_2_LED_pose(q_xyz_quat_type &newPose)
Create tracker-relative pose estimate based on sensor location of 2 tracked points.
Definition: vrpn_Tracker_WiimoteHead.C:379
vrpn_Tracker_WiimoteHead::_have_gravity
bool _have_gravity() const
return true if our gravity values look like real data
Definition: vrpn_Tracker_WiimoteHead.C:550
cvtDistToAngle
const double cvtDistToAngle
Definition: vrpn_Tracker_WiimoteHead.C:81
vrpn_Tracker_WiimoteHead::d_vGravAntepenultimate
q_vec_type d_vGravAntepenultimate
Definition: vrpn_Tracker_WiimoteHead.h:234
vrpn_Tracker_WiimoteHead::d_updated
bool d_updated
Flag: Have we received updated Wiimote data since last report?
Definition: vrpn_Tracker_WiimoteHead.h:227
vrpn_Analog_Remote::unregister_change_handler
virtual int unregister_change_handler(void *userdata, vrpn_ANALOGCHANGEHANDLER handler)
Definition: vrpn_Analog.h:197
vrpn_Analog_Remote::mainloop
virtual void mainloop()
Called once through each main loop iteration to handle updates. Remote object mainloop() should call ...
Definition: vrpn_Analog.C:328
vrpn_Tracker_WiimoteHead::mainloop
virtual void mainloop()
VRPN mainloop function.
Definition: vrpn_Tracker_WiimoteHead.C:204
vrpn_Tracker::position_m_id
vrpn_int32 position_m_id
Definition: vrpn_Tracker.h:80
vrpn_Connection
Generic connection class not specific to the transport mechanism.
Definition: vrpn_Connection.h:510
vrpn_Connection.h
vrpn_Tracker_WiimoteHead::d_points
double d_points
Definition: vrpn_Tracker_WiimoteHead.h:199
vrpn_gettimeofday
#define vrpn_gettimeofday
Definition: vrpn_Shared.h:89
vrpn_Tracker_WiimoteHead::FLIP_NORMAL
@ FLIP_NORMAL
Definition: vrpn_Tracker_WiimoteHead.h:187
vrpn_Tracker_WiimoteHead::_update_flip_state
void _update_flip_state()
If flip state is unknown, set flip state appropriately.
Definition: vrpn_Tracker_WiimoteHead.C:462
two
const double two
Definition: vrpn_Tracker_WiimoteHead.C:70
vrpn_Tracker_WiimoteHead::d_lock
bool d_lock
Flag: Does the tracking algorithm report a lock?
Definition: vrpn_Tracker_WiimoteHead.h:224
yResSensor
const double yResSensor
Definition: vrpn_Tracker_WiimoteHead.C:73
vrpn_Tracker_WiimoteHead::report
void report()
Pack and send tracker report.
Definition: vrpn_Tracker_WiimoteHead.C:263
vrpn_Tracker_WiimoteHead::_convert_pose_to_tracker
void _convert_pose_to_tracker()
Set the vrpn_Tracker position and rotation to that indicated by our d_currentPose;.
Definition: vrpn_Tracker_WiimoteHead.C:487
vrpn_Tracker_WiimoteHead::_reset_pose
void _reset_pose()
reset current pose, last report time, and tracker pose
Definition: vrpn_Tracker_WiimoteHead.C:518
vrpn_Tracker_WiimoteHead::d_vGrav
q_vec_type d_vGrav
Definition: vrpn_Tracker_WiimoteHead.h:236
vrpn_Tracker_WiimoteHead::vrpn_Tracker_WiimoteHead
vrpn_Tracker_WiimoteHead(const char *name, vrpn_Connection *trackercon, const char *wiimote, float update_rate, float led_spacing=0.145)
constructor
Definition: vrpn_Tracker_WiimoteHead.C:95
radPerPx
const double radPerPx
Definition: vrpn_Tracker_WiimoteHead.C:80
vrpn_Tracker_WiimoteHead::d_gravDirty
bool d_gravDirty
Flag: Have we received updated gravity data since last gravity update?
Definition: vrpn_Tracker_WiimoteHead.h:231
vrpn_Tracker::pos
vrpn_float64 pos[3]
Definition: vrpn_Tracker.h:95
vrpn_Analog_Remote::register_change_handler
virtual int register_change_handler(void *userdata, vrpn_ANALOGCHANGEHANDLER handler)
Definition: vrpn_Analog.h:192
vrpn_Tracker_WiimoteHead::d_flipState
FlipState d_flipState
Whether we need to flip the order of the tracked points before calculating a pose.
Definition: vrpn_Tracker_WiimoteHead.h:190
vrpn_BaseClassUnique::server_mainloop
void server_mainloop(void)
Handles functions that all servers should provide in their mainloop() (ping/pong, for example) Should...
Definition: vrpn_BaseClass.C:603
vrpn_Tracker_WiimoteHead::FLIP_UNKNOWN
@ FLIP_UNKNOWN
Definition: vrpn_Tracker_WiimoteHead.h:187
vrpn_Tracker_WiimoteHead::handle_analog_update
static void VRPN_CALLBACK VRPN_CALLBACK handle_analog_update(void *userdata, const vrpn_ANALOGCB info)
Callback triggered when our data source issues an update.
Definition: vrpn_Tracker_WiimoteHead.C:285
vrpn_Tracker_WiimoteHead::d_prevtime
struct timeval d_prevtime
Time of last tracker report issued.
Definition: vrpn_Tracker_WiimoteHead.h:193
vrpn_Tracker_WiimoteHead
Provides a tracker device given data from a Wii Remote and LED glasses.
Definition: vrpn_Tracker_WiimoteHead.h:69