vrpn 07.35
Virtual Reality Peripheral Network
Loading...
Searching...
No Matches
vrpn_Tracker.h
Go to the documentation of this file.
1#ifndef vrpn_TRACKER_H
2#define vrpn_TRACKER_H
3#include <stdio.h> // for NULL, FILE
4
5// NOTE: a vrpn tracker must call user callbacks with tracker data (pos and
6// ori info) which represent the transformation xfSourceFromSensor.
7// This means that the pos info is the position of the origin of
8// the sensor coord sys in the source coord sys space, and the
9// quat represents the orientation of the sensor relative to the
10// source space (ie, its value rotates the source's axes so that
11// they coincide with the sensor's)
12// Positions from all trackers in VRPN are reported in meters.
13// Velocities are reported in meters/second.
14// Accelerations are reported in meters/second/second.
15// These are all reported in three-element double arrays
16// in the order (X=0, Y=1, Z=2).
17// They are translated into this format from the native format for each device.
18// Orientations from all trackers in VRPN are reported in quaternions
19// (see Quatlib for more info) in four-element double arrays
20// in the order (X=0, Y=1, Z=2, W=3).
21// They are translated into this format from the native format for each device.
22
23// to use time synched tracking, just pass in a sync connection to the
24// client and the server
25
26#include "vrpn_BaseClass.h" // for vrpn_Callback_List, etc
27#include "vrpn_Configure.h" // for VRPN_CALLBACK, VRPN_API, etc
28#include "vrpn_Connection.h"
29#include "vrpn_Shared.h" // for timeval
30#include "vrpn_Types.h" // for vrpn_float64, vrpn_int32, etc
31
33
34// tracker status flags
35const int vrpn_TRACKER_SYNCING = (3);
38const int vrpn_TRACKER_PARTIAL = (0);
39const int vrpn_TRACKER_RESETTING = (-1);
40const int vrpn_TRACKER_FAIL = (-2);
41
42// index for the change_list that should be called for all sensors.
43// Not an in-range index.
44const int vrpn_ALL_SENSORS = -1;
45
46typedef vrpn_float64 vrpn_Tracker_Pos[3];
47typedef vrpn_float64 vrpn_Tracker_Quat[4];
48
50public:
51 // vrpn_Tracker.cfg, in the "local" directory, is the default config file
52 // . You can specify a different config file in the constructor. When
53 // you do this, you must also specify a vrpn_Connection. Pass in NULL
54 // if you don't have one. This awkwardness is because C++ requires that
55 // only the rightmost arguments can use the default values, and that the
56 // order of arguments must match the base class :(
57 vrpn_Tracker(const char *name, vrpn_Connection *c = NULL,
58 const char *tracker_cfg_file_name = NULL);
59
60 virtual ~vrpn_Tracker(void);
61
62 int read_config_file(FILE *config_file, const char *tracker_name);
63 void print_latest_report(void);
64 // a tracker server should call the following to register the
65 // default xform and workspace request handlers
66 int register_server_handlers(void);
67 void get_local_t2r(vrpn_float64 *vec, vrpn_float64 *quat);
68 void get_local_u2s(vrpn_int32 sensor, vrpn_float64 *vec,
69 vrpn_float64 *quat);
70 static int VRPN_CALLBACK
71 handle_t2r_request(void *userdata, vrpn_HANDLERPARAM p);
72 static int VRPN_CALLBACK
73 handle_u2s_request(void *userdata, vrpn_HANDLERPARAM p);
74 static int VRPN_CALLBACK
75 handle_workspace_request(void *userdata, vrpn_HANDLERPARAM p);
76 // static int VRPN_CALLBACK handle_update_rate_request (void *,
77 // vrpn_HANDLERPARAM);
78
79protected:
80 vrpn_int32 position_m_id; // ID of tracker position message
81 vrpn_int32 velocity_m_id; // ID of tracker velocity message
82 vrpn_int32 accel_m_id; // ID of tracker acceleration message
83 vrpn_int32 tracker2room_m_id; // ID of tracker tracker2room message
84 vrpn_int32 unit2sensor_m_id; // ID of tracker unit2sensor message
85 vrpn_int32 request_t2r_m_id; // ID of tracker2room request message
86 vrpn_int32 request_u2s_m_id; // ID of unit2sensor request message
87 vrpn_int32 request_workspace_m_id; // ID of workspace request message
88 vrpn_int32 workspace_m_id; // ID of workspace message
89 vrpn_int32 update_rate_id; // ID of update rate message
90 vrpn_int32 connection_dropped_m_id; // ID of connection dropped message
91 vrpn_int32 reset_origin_m_id; // ID of reset origin message
92
93 // Description of the next report to go out
94 vrpn_int32 d_sensor; // Current sensor
95 vrpn_float64 pos[3], d_quat[4]; // Current pose, (x,y,z), (qx,qy,qz,qw)
96 vrpn_float64 vel[3], vel_quat[4]; // Cur velocity and dQuat/vel_quat_dt
97 vrpn_float64 vel_quat_dt; // delta time (in secs) for vel_quat
98 vrpn_float64 acc[3], acc_quat[4]; // Cur accel and d2Quat/acc_quat_dt2
99 vrpn_float64 acc_quat_dt; // delta time (in secs) for acc_quat
100 struct timeval timestamp; // Current timestamp
101 vrpn_int32 frame_count; // Current framecount
102
103 // The timestamp that the last report was received (Used by the Liberty
104 // Driver)
105 // Other trackers use timestamp as the watchdog, however due to variable USB
106 // latency the Liberty driver uses the device timestamp and not the computer
107 // clock
108 // at the time the report was received. This however can drift
109 // from the computer time, and hence it can cause a reset when things are
110 // working fine
111 struct timeval watchdog_timestamp;
112
113 vrpn_float64 tracker2room[3], tracker2room_quat[4]; // Current t2r xform
114 vrpn_int32 num_sensors;
115
116 // Arrays of values, one per sensor. Includes function to ensure there are
117 // enough there for a specified number of sensors.
119 vrpn_Tracker_Quat *unit2sensor_quat; // Current u2s xforms
121 bool ensure_enough_unit2sensors(unsigned num);
122
123 // bounding box for the tracker workspace (in tracker space)
124 // these are the points with (x,y,z) minimum and maximum
125 // note: we assume the bounding box edges are aligned with the tracker
126 // coordinate system
127 vrpn_float64 workspace_min[3], workspace_max[3];
128
129 int status; // What are we doing?
130
131 virtual int register_types(void); //< Called by BaseClass init()
132 virtual int encode_to(char *buf); // Encodes the position report
133 // Not all trackers will call the velocity and acceleration packers
134 virtual int encode_vel_to(char *buf); // Encodes the velocity report
135 virtual int encode_acc_to(char *buf); // Encodes the acceleration report
136 virtual int encode_tracker2room_to(char *buf); // Encodes the tracker2room
137 virtual int encode_unit2sensor_to(char *buf); // and unit2sensor xforms
138 virtual int encode_workspace_to(char *buf); // Encodes workspace info
139};
140
141#ifndef VRPN_CLIENT_ONLY
142#define VRPN_TRACKER_BUF_SIZE 100
143
145public:
146 vrpn_Tracker_Serial(const char *name, vrpn_Connection *c,
147 const char *port = "/dev/ttyS1", long baud = 38400);
148 virtual ~vrpn_Tracker_Serial();
149
150protected:
151 char portname[VRPN_TRACKER_BUF_SIZE];
154
155 unsigned char buffer[VRPN_TRACKER_BUF_SIZE]; // Characters read in from the
156 // tracker so far
157 vrpn_uint32 bufcount; // How many characters in the buffer?
158
161 virtual int get_report(void) = 0;
162
163 // Sends the report that was just read.
164 virtual void send_report(void);
165
167 virtual void reset(void) = 0;
168
169public:
172 virtual void mainloop();
173};
174
175// This driver uses the VRPN-preferred LibUSB-1.0 to control the device.
176#if defined(VRPN_USE_LIBUSB_1_0)
177struct libusb_device_handle; // IWYU pragma: keep
178struct libusb_context; // IWYU pragma: keep
179#define VRPN_TRACKER_USB_BUF_SIZE 1000
180
182public:
183 vrpn_Tracker_USB(const char *name, vrpn_Connection *c, vrpn_uint16 vendor,
184 vrpn_uint16 product, long baud = 115200);
185 virtual ~vrpn_Tracker_USB();
186
187protected:
188 struct libusb_device_handle *_device_handle; // Handle for the USB device
189 struct libusb_context *_context; // LibUSB context used for this device
190 vrpn_uint16 _vendor; // Vendor ID for usb device
191 vrpn_uint16 _product; // Product ID for usb device
193
194 vrpn_uint8 buffer[VRPN_TRACKER_USB_BUF_SIZE]; // Characters read in from the
195 // tracker
196 vrpn_uint32 bufcount; // How many characters in the buffer?
197
200 virtual int get_report(void) = 0;
201
202 // Sends the report that was just read.
203 virtual void send_report(void);
204
206 virtual void reset(void) = 0;
207
208public:
211 virtual void mainloop();
212};
213
214// End of VRPN_USE_LIBUSB_1_0
215#endif
216
217#endif // VRPN_CLIENT_ONLY
218
219// This is an example of a tracker server. It basically reports the
220// position at the origin with zero velocity and acceleration over and
221// over again at the rate requested. It is here mostly as an example of
222// how to build a tracker server, and also serves as a test object for
223// client codes and VRPN builds.
224
226public:
227 vrpn_Tracker_NULL(const char *name, vrpn_Connection *c,
228 vrpn_int32 sensors = 1, vrpn_float64 Hz = 1.0);
229 virtual void mainloop();
230
231 void setRedundantTransmission(vrpn_RedundantTransmission *);
232
233protected:
234 vrpn_float64 update_rate;
235
237};
238
239// This is an example of a tracker server. It stays at the
240// origina and spins around the specified axis at the
241// specified rate of rotation, reporting orientation and
242// orientation velocity at the specified
243// rate. It was designed to help test the smoothness of
244// rendering for VR systems by providing a ground-truth
245// smoothly-rotating tracker source.
246
248public:
249 vrpn_Tracker_Spin(const char *name, vrpn_Connection *c,
250 vrpn_int32 sensors = 1, vrpn_float64 reportRateHz = 1.0,
251 vrpn_float64 axisX = 0, vrpn_float64 axisY = 0,
252 vrpn_float64 axisZ = 1, vrpn_float64 spinRateHz = 0.5);
253 virtual void mainloop();
254
255protected:
256 vrpn_float64 update_rate;
257 vrpn_float64 x, y, z, spin_rate_Hz;
258 struct timeval start;
259};
260
261// This is a tracker server that can be used by an application that
262// just wants to generate tracker reports but does not really have
263// a tracker device to drive. Similar to the vrpn_Analog_Server, it
264// provides a quick and easy way for an application to report things.
265//
266// The application creates an object of this class, specifying the
267// number of sensors and the connection that is to be used. It then
268// reports poses (position + quat), pose velocities, and pose
269// accelerations as desired using the provided functions. The
270// mainloop() function needs to be called periodically even when
271// there is nothing to report.
272
274public:
275 vrpn_Tracker_Server(const char *name, vrpn_Connection *c,
276 vrpn_int32 sensors = 1);
277
279 virtual void mainloop();
280
283 virtual int report_pose(
284 const int sensor, const struct timeval t,
285 const vrpn_float64 position[3], const vrpn_float64 quaternion[4],
286 const vrpn_uint32 class_of_service = vrpn_CONNECTION_LOW_LATENCY);
287 virtual int report_pose_velocity(
288 const int sensor, const struct timeval t,
289 const vrpn_float64 position[3], const vrpn_float64 quaternion[4],
290 const vrpn_float64 interval,
291 const vrpn_uint32 class_of_service = vrpn_CONNECTION_LOW_LATENCY);
292 virtual int report_pose_acceleration(
293 const int sensor, const struct timeval t,
294 const vrpn_float64 position[3], const vrpn_float64 quaternion[4],
295 const vrpn_float64 interval,
296 const vrpn_uint32 class_of_service = vrpn_CONNECTION_LOW_LATENCY);
297};
298
299//----------------------------------------------------------
300// ************** Users deal with the following *************
301
302// User routine to handle a tracker position update. This is called when
303// the tracker callback is called (when a message from its counterpart
304// across the connection arrives).
305
306typedef struct _vrpn_TRACKERCB {
307 struct timeval msg_time; // Time of the report
308 vrpn_int32 sensor; // Which sensor is reporting
309 vrpn_float64 pos[3]; // Position of the sensor
310 vrpn_float64 quat[4]; // Orientation of the sensor
313 void *userdata, const vrpn_TRACKERCB info);
314
315// User routine to handle a tracker velocity update. This is called when
316// the tracker callback is called (when a message from its counterpart
317// across the connetion arrives).
318
319typedef struct _vrpn_TRACKERVELCB {
320 struct timeval msg_time; // Time of the report
321 vrpn_int32 sensor; // Which sensor is reporting
322 vrpn_float64 vel[3]; // Velocity of the sensor
323 vrpn_float64 vel_quat[4]; // Rotation of the sensor per vel_quat_dt
324 vrpn_float64 vel_quat_dt; // delta time (in secs) for vel_quat
327 void *userdata, const vrpn_TRACKERVELCB info);
328
329// User routine to handle a tracker acceleration update. This is called when
330// the tracker callback is called (when a message from its counterpart
331// across the connetion arrives).
332
333typedef struct _vrpn_TRACKERACCCB {
334 struct timeval msg_time; // Time of the report
335 vrpn_int32 sensor; // Which sensor is reporting
336 vrpn_float64 acc[3]; // Acceleration of the sensor
337 vrpn_float64 acc_quat[4]; // Change in vel_quat of the sensor per acc_quat_dt
338 vrpn_float64 acc_quat_dt; // delta time (in secs) for acc_quat
339
342 void *userdata, const vrpn_TRACKERACCCB info);
343
344// User routine to handle a tracker room2tracker xform update. This is called
345// when the tracker callback is called (when a message from its counterpart
346// across the connection arrives).
347
348typedef struct _vrpn_TRACKERTRACKER2ROOMCB {
349 struct timeval msg_time; // Time of the report
350 vrpn_float64 tracker2room[3]; // position offset
351 vrpn_float64 tracker2room_quat[4]; // orientation offset
354 void *userdata, const vrpn_TRACKERTRACKER2ROOMCB info);
355
356typedef struct _vrpn_TRACKERUNIT2SENSORCB {
357 struct timeval msg_time; // Time of the report
358 vrpn_int32 sensor; // Which sensor this is for
359 vrpn_float64 unit2sensor[3]; // position offset
360 vrpn_float64 unit2sensor_quat[4]; // orientation offset
363 void *userdata, const vrpn_TRACKERUNIT2SENSORCB info);
364
365typedef struct _vrpn_TRACKERWORKSPACECB {
366 struct timeval msg_time; // Time of the report
367 vrpn_float64 workspace_min[3]; // minimum corner of box (tracker CS)
368 vrpn_float64 workspace_max[3]; // maximum corner of box (tracker CS)
371 void *userdata, const vrpn_TRACKERWORKSPACECB info);
372
373// Structure to hold all of the callback lists for one sensor
374// (also used for the "all sensors" sensor).
391
392// Open a tracker that is on the other end of a connection
393// and handle updates from it. This is the type of tracker that user code will
394// deal with.
395
397public:
398 // The name of the tracker to connect to, including connection name,
399 // for example "Ceiling_tracker@ceiling.cs.unc.edu". If you already
400 // have the connection open, you can specify it as the second parameter.
401 // This allows both servers and clients in the same thread, for example.
402 // If it is not specified, then the connection will be looked up based
403 // on the name passed in.
404 vrpn_Tracker_Remote(const char *name, vrpn_Connection *c = NULL);
405
406 // unregister all of the handlers registered with the connection
407 virtual ~vrpn_Tracker_Remote(void);
408
409 // request room from tracker xforms
410 int request_t2r_xform(void);
411 // request all available sensor from unit xforms
412 int request_u2s_xform(void);
413 // request workspace bounding box
414 int request_workspace(void);
415
416 // set rate of p/v/a updates from the tracker
417 int set_update_rate(vrpn_float64 samplesPerSecond);
418
419 // reset origin to current tracker location (e.g. - to reinitialize
420 // a PHANToM in its reset position)
421 int reset_origin(void);
422
423 // This routine calls the mainloop of the connection it's on
424 virtual void mainloop();
425
426 // **** to register handlers for sensor-specific messages: ****
427 // Default is to register them for all sensors.
428
429 // (un)Register a callback handler to handle a position change
430 virtual int register_change_handler(void *userdata,
432 vrpn_int32 sensor = vrpn_ALL_SENSORS);
433 virtual int unregister_change_handler(void *userdata,
435 vrpn_int32 sensor = vrpn_ALL_SENSORS);
436
437 // (un)Register a callback handler to handle a velocity change
438 virtual int register_change_handler(void *userdata,
440 vrpn_int32 sensor = vrpn_ALL_SENSORS);
441 virtual int unregister_change_handler(void *userdata,
443 vrpn_int32 sensor = vrpn_ALL_SENSORS);
444
445 // (un)Register a callback handler to handle an acceleration change
446 virtual int register_change_handler(void *userdata,
448 vrpn_int32 sensor = vrpn_ALL_SENSORS);
449 virtual int unregister_change_handler(void *userdata,
451 vrpn_int32 sensor = vrpn_ALL_SENSORS);
452
453 // (un)Register a callback handler to handle a unit2sensor change
454 virtual int
455 register_change_handler(void *userdata,
457 vrpn_int32 sensor = vrpn_ALL_SENSORS);
458 virtual int
459 unregister_change_handler(void *userdata,
461 vrpn_int32 sensor = vrpn_ALL_SENSORS);
462
463 // **** to get workspace information ****
464 // (un)Register a callback handler to handle a workspace change
465 virtual int
468 {
469 return d_workspacechange_list.register_handler(userdata, handler);
470 };
471 virtual int
474 {
475 return d_workspacechange_list.unregister_handler(userdata, handler);
476 }
477
478 // (un)Register a callback handler to handle a tracker2room change
479 virtual int
482 {
483 return d_tracker2roomchange_list.register_handler(userdata, handler);
484 };
485 virtual int
488 {
489 return d_tracker2roomchange_list.unregister_handler(userdata, handler);
490 };
491
492protected:
493 // Callbacks with one per sensor (plus one for "all")
497 bool ensure_enough_sensor_callbacks(unsigned num);
498
499 // Callbacks that are one per tracker
502
503 static int VRPN_CALLBACK
504 handle_change_message(void *userdata, vrpn_HANDLERPARAM p);
505 static int VRPN_CALLBACK
506 handle_vel_change_message(void *userdata, vrpn_HANDLERPARAM p);
507 static int VRPN_CALLBACK
508 handle_acc_change_message(void *userdata, vrpn_HANDLERPARAM p);
509 static int VRPN_CALLBACK
510 handle_tracker2room_change_message(void *userdata, vrpn_HANDLERPARAM p);
511 static int VRPN_CALLBACK
512 handle_unit2sensor_change_message(void *userdata, vrpn_HANDLERPARAM p);
513 static int VRPN_CALLBACK
514 handle_workspace_change_message(void *userdata, vrpn_HANDLERPARAM p);
515};
516
517// End of vrpn_TRACKER_H
518#endif
Class from which all user-level (and other) classes that communicate with vrpn_Connections should der...
virtual void mainloop()=0
Called once through each main loop iteration to handle updates. Remote object mainloop() should call ...
virtual int register_types(void)=0
Register the types of messages this device sends/receives. Return 0 on success, -1 on fail.
Generic connection class not specific to the transport mechanism.
Helper class for vrpn_Connection that automates redundant transmission for unreliable (low-latency) m...
vrpn_float64 update_rate
vrpn_RedundantTransmission * d_redundancy
vrpn_Tracker_Sensor_Callbacks * sensor_callbacks
unsigned num_sensor_callbacks
vrpn_Tracker_Sensor_Callbacks all_sensor_callbacks
virtual int unregister_change_handler(void *userdata, vrpn_TRACKERWORKSPACECHANGEHANDLER handler)
vrpn_Callback_List< vrpn_TRACKERWORKSPACECB > d_workspacechange_list
virtual int unregister_change_handler(void *userdata, vrpn_TRACKERTRACKER2ROOMCHANGEHANDLER handler)
virtual int register_change_handler(void *userdata, vrpn_TRACKERTRACKER2ROOMCHANGEHANDLER handler)
vrpn_Callback_List< vrpn_TRACKERTRACKER2ROOMCB > d_tracker2roomchange_list
virtual int register_change_handler(void *userdata, vrpn_TRACKERWORKSPACECHANGEHANDLER handler)
vrpn_Callback_List< vrpn_TRACKERCB > d_change
vrpn_Callback_List< vrpn_TRACKERVELCB > d_velchange
vrpn_Callback_List< vrpn_TRACKERACCCB > d_accchange
void operator=(const vrpn_Tracker_Sensor_Callbacks &from)
vrpn_Callback_List< vrpn_TRACKERUNIT2SENSORCB > d_unit2sensorchange
virtual void reset(void)=0
Reset the tracker.
virtual int get_report(void)=0
Gets a report if one is available, returns 0 if not, 1 if complete report.
vrpn_float64 update_rate
vrpn_float64 spin_rate_Hz
virtual void reset(void)=0
Reset the tracker.
struct libusb_device_handle * _device_handle
virtual int get_report(void)=0
Gets reports if some are available, returns 0 if not, 1 if complete report(s).
vrpn_uint16 _vendor
vrpn_uint16 _product
vrpn_uint32 bufcount
struct libusb_context * _context
vrpn_int32 request_t2r_m_id
vrpn_int32 reset_origin_m_id
vrpn_int32 connection_dropped_m_id
vrpn_int32 velocity_m_id
vrpn_float64 vel_quat_dt
vrpn_int32 request_workspace_m_id
vrpn_int32 update_rate_id
vrpn_float64 acc_quat_dt
vrpn_int32 accel_m_id
vrpn_int32 workspace_m_id
vrpn_int32 request_u2s_m_id
vrpn_int32 d_sensor
vrpn_Tracker_Quat * unit2sensor_quat
vrpn_int32 num_sensors
unsigned num_unit2sensors
vrpn_int32 frame_count
vrpn_int32 unit2sensor_m_id
vrpn_Tracker_Pos * unit2sensor
vrpn_int32 tracker2room_m_id
vrpn_int32 position_m_id
This structure is what is passed to a vrpn_Connection message callback.
vrpn_float64 acc_quat_dt
vrpn_int32 sensor
vrpn_float64 vel_quat_dt
All types of client/server/peer objects in VRPN should be derived from the vrpn_BaseClass type descri...
#define VRPN_API
#define VRPN_CALLBACK
const vrpn_uint32 vrpn_CONNECTION_LOW_LATENCY
#define VRPN_TRACKER_BUF_SIZE
void(VRPN_CALLBACK * vrpn_TRACKERTRACKER2ROOMCHANGEHANDLER)(void *userdata, const vrpn_TRACKERTRACKER2ROOMCB info)
#define VRPN_TRACKER_USB_BUF_SIZE
const int vrpn_TRACKER_FAIL
const int vrpn_ALL_SENSORS
const int vrpn_TRACKER_RESETTING
void(VRPN_CALLBACK * vrpn_TRACKERACCCHANGEHANDLER)(void *userdata, const vrpn_TRACKERACCCB info)
vrpn_float64 vrpn_Tracker_Quat[4]
const int vrpn_TRACKER_SYNCING
const int vrpn_TRACKER_PARTIAL
void(VRPN_CALLBACK * vrpn_TRACKERCHANGEHANDLER)(void *userdata, const vrpn_TRACKERCB info)
vrpn_float64 vrpn_Tracker_Pos[3]
const int vrpn_TRACKER_REPORT_READY
void(VRPN_CALLBACK * vrpn_TRACKERVELCHANGEHANDLER)(void *userdata, const vrpn_TRACKERVELCB info)
const int vrpn_TRACKER_AWAITING_STATION
void(VRPN_CALLBACK * vrpn_TRACKERUNIT2SENSORCHANGEHANDLER)(void *userdata, const vrpn_TRACKERUNIT2SENSORCB info)
void(VRPN_CALLBACK * vrpn_TRACKERWORKSPACECHANGEHANDLER)(void *userdata, const vrpn_TRACKERWORKSPACECB info)