vrpn  07.33
Virtual Reality Peripheral Network
vrpn_Analog_5dtUSB.C
Go to the documentation of this file.
1 
14 #include <string.h> // for memset
15 #include <iostream> // for operator<<, ostringstream, etc
16 #include <sstream>
17 #include <stdexcept> // for logic_error
18 
19 #include "vrpn_Analog_5dtUSB.h"
20 #include "vrpn_BaseClass.h" // for ::vrpn_TEXT_NORMAL, etc
21 
23 
24 #if defined(VRPN_USE_HID)
25 
26 // USB vendor and product IDs for the models we support
27 static const vrpn_uint16 vrpn_5DT_VENDOR = 0x5d70;
28 
29 static const vrpn_uint16 vrpn_5DT_LEFT_MASK = 0x0001;
30 static const vrpn_uint16 vrpn_5DT_RIGHT = 0x0000;
31 static const vrpn_uint16 vrpn_5DT_LEFT = 0x0001;
32 static const vrpn_uint16 vrpn_5DT_WIRELESS_PORTA_MASK = 0x0002;
33 static const vrpn_uint16 vrpn_5DT_WIRELESS_PORTB_MASK = 0x0006;
34 static const vrpn_uint16 vrpn_5DT_DATAGLOVE5_MASK = 0x0010;
35 static const vrpn_uint16 vrpn_5DT_DATAGLOVE5 = 0x0010;
36 static const vrpn_uint16 vrpn_5DT_DATAGLOVE14 = 0x0000;
37 
38 
39 static const vrpn_uint16 vrpn_5DT_DATAGLOVE14_RIGHT_WIRED = 0x0000;
40 static const vrpn_uint16 vrpn_5DT_DATAGLOVE14_LEFT_WIRED = 0x0001;
41 static const vrpn_uint16 vrpn_5DT_DATAGLOVE14_RIGHT_WIRELESS_PORTA = 0x0002;
42 static const vrpn_uint16 vrpn_5DT_DATAGLOVE14_LEFT_WIRELESS_PORTA = 0x0003;
43 static const vrpn_uint16 vrpn_5DT_DATAGLOVE14_RIGHT_WIRELESS_PORTB = 0x0006;
44 static const vrpn_uint16 vrpn_5DT_DATAGLOVE14_LEFT_WIRELESS_PORTB = 0x0007;
45 static const vrpn_uint16 vrpn_5DT_DATAGLOVE5_RIGHT_WIRED = 0x0010;
46 static const vrpn_uint16 vrpn_5DT_DATAGLOVE5_LEFT_WIRED = 0x0011;
47 static const vrpn_uint16 vrpn_5DT_DATAGLOVE5_RIGHT_WIRELESS_PORTA = 0x0012;
48 static const vrpn_uint16 vrpn_5DT_DATAGLOVE5_LEFT_WIRELESS_PORTA = 0x0013;
49 static const vrpn_uint16 vrpn_5DT_DATAGLOVE5_RIGHT_WIRELESS_PORTB = 0x0016;
50 static const vrpn_uint16 vrpn_5DT_DATAGLOVE5_LEFT_WIRELESS_PORTB = 0x0017;
51 
52 
54  int num_sensors,
55  bool isLeftHand,
56  const char *name,
57  vrpn_Connection *c) :
58  vrpn_Analog(name, c),
59  vrpn_HidInterface(filter),
60  _isLeftHand(isLeftHand),
61  _wasConnected(false) {
62 
63  if (num_sensors != 5 && num_sensors != 14) {
64  throw std::logic_error("The vrpn_Analog_5dtUSB driver only supports 5 or 14 sensors, and a different number was passed!");
65  }
66 
67  vrpn_Analog::num_channel = num_sensors;
68 
69  // Initialize the state of all the analogs
70  memset(channel, 0, sizeof(channel));
71  memset(last, 0, sizeof(last));
72 
73  // Set the timestamp
75 }
76 
78  delete _acceptor;
79 }
81  std::ostringstream ss;
82  if (product() & vrpn_5DT_LEFT_MASK) {
83  ss << "left";
84  } else {
85  ss << "right";
86  }
87 
88  ss << " hand, ";
89  if (product() & vrpn_5DT_DATAGLOVE5_MASK) {
90  ss << "5";
91  } else {
92  ss << "14";
93  }
94 
95  ss << " sensors, ";
96  if (product() & vrpn_5DT_WIRELESS_PORTA_MASK) {
97  ss << "wireless port A";
98  } else if (product() & vrpn_5DT_WIRELESS_PORTB_MASK) {
99  ss << "wireless port B";
100  } else {
101  ss << "wired USB";
102  }
103  return ss.str();
104 }
105 
106 void vrpn_Analog_5dtUSB::on_data_received(size_t bytes, vrpn_uint8 *buffer) {
107  if (bytes != 64) {
108  std::ostringstream ss;
109  ss << "Received a too-short report: " << bytes;
110  struct timeval ts;
111  vrpn_gettimeofday(&ts, NULL);
112  send_text_message(ss.str().c_str(), ts, vrpn_TEXT_WARNING);
113  return;
114  }
115 
116  // Decode all full reports.
117  const float scale = 1.0f / 4096.0f;
118  vrpn_uint8 * bufptr = buffer;
119  for (size_t i = 0; i < 16; i++) {
120  _rawVals[i] = vrpn_unbuffer<vrpn_int16>(bufptr) * scale;
121  }
122 
123  switch (vrpn_Analog::num_channel) {
124  case 5:
125  for (size_t i = 0; i < 5; ++i) {
126  channel[i] = _rawVals[i * 3];
127  // Report this event before parsing the next.
128  report_changes();
129  }
130  break;
131 
132  case 14:
133  for (size_t i = 0; i < 14; ++i) {
134  channel[i] = _rawVals[i];
135  // Report this event before parsing the next.
136  report_changes();
137  }
138  break;
139  default:
140  std::cerr << "Internal error - should not happen: Unrecognized number of channels!" << std::endl;
141  }
142 }
143 
146 
147  update();
148 
149  if (connected() && !_wasConnected) {
150  std::ostringstream ss;
151  ss << "Successfully connected to 5DT glove, " << get_description();
152  send_text_message(ss.str().c_str(), _timestamp, vrpn_TEXT_NORMAL);
153  }
155 
156  server_mainloop();
157 }
158 
159 void vrpn_Analog_5dtUSB::report_changes(vrpn_uint32 class_of_service) {
161 
162  vrpn_Analog::report_changes(class_of_service);
163 }
164 
165 void vrpn_Analog_5dtUSB::report(vrpn_uint32 class_of_service) {
167 
168  vrpn_Analog::report(class_of_service);
169 }
170 
171 
173  vrpn_Analog_5dtUSB(new vrpn_HidProductMaskAcceptor(vrpn_5DT_VENDOR, vrpn_5DT_LEFT_MASK | vrpn_5DT_DATAGLOVE5_MASK, vrpn_5DT_LEFT | vrpn_5DT_DATAGLOVE5),
174  5,
175  true,
176  name,
177  c) { }
178 
180  vrpn_Analog_5dtUSB(new vrpn_HidProductMaskAcceptor(vrpn_5DT_VENDOR, vrpn_5DT_LEFT_MASK | vrpn_5DT_DATAGLOVE5_MASK, vrpn_5DT_RIGHT | vrpn_5DT_DATAGLOVE5),
181  5,
182  false,
183  name,
184  c) { }
185 
187  vrpn_Analog_5dtUSB(new vrpn_HidProductMaskAcceptor(vrpn_5DT_VENDOR, vrpn_5DT_LEFT_MASK | vrpn_5DT_DATAGLOVE5_MASK, vrpn_5DT_LEFT | vrpn_5DT_DATAGLOVE14),
188  14,
189  true,
190  name,
191  c) { }
192 
194  vrpn_Analog_5dtUSB(new vrpn_HidProductMaskAcceptor(vrpn_5DT_VENDOR, vrpn_5DT_LEFT_MASK | vrpn_5DT_DATAGLOVE5_MASK, vrpn_5DT_RIGHT | vrpn_5DT_DATAGLOVE14),
195  14,
196  false,
197  name,
198  c) { }
199 
200 #endif
201 
vrpn_Analog_5dtUSB_Glove5Left(const char *name, vrpn_Connection *c=0)
void server_mainloop(void)
Handles functions that all servers should provide in their mainloop() (ping/pong, for example) Should...
void report(vrpn_uint32 class_of_service=vrpn_CONNECTION_LOW_LATENCY)
Send report whether or not changed.
virtual void report_changes(vrpn_uint32 class_of_service=vrpn_CONNECTION_LOW_LATENCY, const struct timeval time=vrpn_ANALOG_NOW)
Send a report only if something has changed (for servers) Optionally, tell what time to stamp the val...
Definition: vrpn_Analog.C:71
header for 5DT USB (HID) dataglove driver
double _rawVals[16]
The raw values extracted from the report: which ones we use to set analog channels varies based on th...
virtual void mainloop()
Standard VRPN mainloop method.
std::string get_description() const
Returns a string description of the device we&#39;ve connected to. Used internally, but also possibly use...
vrpn_uint16 product() const
Returns USB product ID of connected device.
struct timeval _timestamp
Timestamp updated during mainloop()
virtual ~vrpn_Analog_5dtUSB()
Destructor.
vrpn_float64 channel[vrpn_CHANNEL_MAX]
Definition: vrpn_Analog.h:38
bool _wasConnected
Flag indicating whether we were connected last time through the mainloop. Used to send a "normal"-sev...
Generic connection class not specific to the transport mechanism.
virtual void report(vrpn_uint32 class_of_service=vrpn_CONNECTION_LOW_LATENCY, const struct timeval time=vrpn_ANALOG_NOW)
Send a report whether something has changed or not (for servers) Optionally, tell what time to stamp ...
Definition: vrpn_Analog.C:94
5th Dimension Technologies (5dt) "Ultra" USB data glove driver
#define VRPN_SUPPRESS_EMPTY_OBJECT_WARNING()
HID acceptor subclass used by vrpn_Analog_5dtUSB since the bits of the product ID for these devices d...
All types of client/server/peer objects in VRPN should be derived from the vrpn_BaseClass type descri...
vrpn_int32 num_channel
Definition: vrpn_Analog.h:40
vrpn_Analog_5dtUSB_Glove14Left(const char *name, vrpn_Connection *c=0)
void on_data_received(size_t bytes, vrpn_uint8 *buffer)
Extracts the sensor values from each report.
vrpn_Analog_5dtUSB_Glove14Right(const char *name, vrpn_Connection *c=0)
int send_text_message(const char *msg, struct timeval timestamp, vrpn_TEXT_SEVERITY type=vrpn_TEXT_NORMAL, vrpn_uint32 level=0)
Sends a NULL-terminated text message from the device d_sender_id.
vrpn_HidAcceptor * _acceptor
This is the HidAcceptor we use when reconnecting.
vrpn_Analog_5dtUSB_Glove5Right(const char *name, vrpn_Connection *c=0)
#define vrpn_gettimeofday
Definition: vrpn_Shared.h:89
virtual void update()
Polls the device buffers and causes on_data_received callbacks if appropriate You NEED to call this f...
void report_changes(vrpn_uint32 class_of_service=vrpn_CONNECTION_LOW_LATENCY)
Send report iff changed.
virtual bool connected() const
Returns true iff the last device I/O succeeded.
struct timeval timestamp
Definition: vrpn_Analog.h:41
vrpn_float64 last[vrpn_CHANNEL_MAX]
Definition: vrpn_Analog.h:39
vrpn_Analog_5dtUSB(vrpn_HidAcceptor *filter, int num_sensors, bool isLeftHand, const char *name, vrpn_Connection *c=0)
Protected constructor: use a subclass to specify the glove variant to use.