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_HidInterface::connected
virtual bool connected() const
Returns true iff the last device I/O succeeded.
Definition: vrpn_HumanInterface.C:23
vrpn_HidProductMaskAcceptor
HID acceptor subclass used by vrpn_Analog_5dtUSB since the bits of the product ID for these devices d...
Definition: vrpn_Analog_5dtUSB.h:129
vrpn_BaseClass.h
vrpn_Analog::channel
vrpn_float64 channel[vrpn_CHANNEL_MAX]
Definition: vrpn_Analog.h:38
vrpn_Analog_5dtUSB::report
void report(vrpn_uint32 class_of_service=vrpn_CONNECTION_LOW_LATENCY)
Send report whether or not changed.
Definition: vrpn_Analog_5dtUSB.C:165
vrpn_Analog_5dtUSB.h
header for 5DT USB (HID) dataglove driver
vrpn_HidInterface
Definition: vrpn_HumanInterface.h:68
vrpn_Analog_5dtUSB_Glove5Left::vrpn_Analog_5dtUSB_Glove5Left
vrpn_Analog_5dtUSB_Glove5Left(const char *name, vrpn_Connection *c=0)
Definition: vrpn_Analog_5dtUSB.C:172
vrpn_Analog_5dtUSB::report_changes
void report_changes(vrpn_uint32 class_of_service=vrpn_CONNECTION_LOW_LATENCY)
Send report iff changed.
Definition: vrpn_Analog_5dtUSB.C:159
vrpn_Analog::report
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
vrpn_Analog_5dtUSB::on_data_received
void on_data_received(size_t bytes, vrpn_uint8 *buffer)
Extracts the sensor values from each report.
Definition: vrpn_Analog_5dtUSB.C:106
vrpn_Analog
Definition: vrpn_Analog.h:28
vrpn_Analog_5dtUSB::~vrpn_Analog_5dtUSB
virtual ~vrpn_Analog_5dtUSB()
Destructor.
Definition: vrpn_Analog_5dtUSB.C:77
vrpn_Analog::timestamp
struct timeval timestamp
Definition: vrpn_Analog.h:41
vrpn_HidInterface::update
virtual void update()
Polls the device buffers and causes on_data_received callbacks if appropriate You NEED to call this f...
Definition: vrpn_HumanInterface.C:140
vrpn_HidAcceptor
Definition: vrpn_HumanInterface.h:54
vrpn_Analog_5dtUSB_Glove14Left::vrpn_Analog_5dtUSB_Glove14Left
vrpn_Analog_5dtUSB_Glove14Left(const char *name, vrpn_Connection *c=0)
Definition: vrpn_Analog_5dtUSB.C:186
vrpn_HidInterface::product
vrpn_uint16 product() const
Returns USB product ID of connected device.
Definition: vrpn_HumanInterface.C:17
vrpn_Analog_5dtUSB::mainloop
virtual void mainloop()
Standard VRPN mainloop method.
Definition: vrpn_Analog_5dtUSB.C:144
vrpn_Analog_5dtUSB::get_description
std::string get_description() const
Returns a string description of the device we've connected to. Used internally, but also possibly use...
Definition: vrpn_Analog_5dtUSB.C:80
vrpn_TEXT_WARNING
Definition: vrpn_BaseClass.h:102
vrpn_Analog_5dtUSB::vrpn_Analog_5dtUSB
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.
Definition: vrpn_Analog_5dtUSB.C:53
vrpn_Connection
Generic connection class not specific to the transport mechanism.
Definition: vrpn_Connection.h:510
vrpn_Analog_5dtUSB_Glove5Right::vrpn_Analog_5dtUSB_Glove5Right
vrpn_Analog_5dtUSB_Glove5Right(const char *name, vrpn_Connection *c=0)
Definition: vrpn_Analog_5dtUSB.C:179
vrpn_Analog::num_channel
vrpn_int32 num_channel
Definition: vrpn_Analog.h:40
vrpn_Analog_5dtUSB::_wasConnected
bool _wasConnected
Flag indicating whether we were connected last time through the mainloop. Used to send a "normal"-sev...
Definition: vrpn_Analog_5dtUSB.h:89
vrpn_gettimeofday
#define vrpn_gettimeofday
Definition: vrpn_Shared.h:89
vrpn_Analog_5dtUSB::_rawVals
double _rawVals[16]
The raw values extracted from the report: which ones we use to set analog channels varies based on th...
Definition: vrpn_Analog_5dtUSB.h:81
vrpn_Analog_5dtUSB::_timestamp
struct timeval _timestamp
Timestamp updated during mainloop()
Definition: vrpn_Analog_5dtUSB.h:77
vrpn_Analog::last
vrpn_float64 last[vrpn_CHANNEL_MAX]
Definition: vrpn_Analog.h:39
vrpn_TEXT_NORMAL
Definition: vrpn_BaseClass.h:101
vrpn_Analog_5dtUSB_Glove14Right::vrpn_Analog_5dtUSB_Glove14Right
vrpn_Analog_5dtUSB_Glove14Right(const char *name, vrpn_Connection *c=0)
Definition: vrpn_Analog_5dtUSB.C:193
vrpn_BaseClassUnique::send_text_message
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.
Definition: vrpn_BaseClass.C:568
vrpn_Analog_5dtUSB
5th Dimension Technologies (5dt) "Ultra" USB data glove driver
Definition: vrpn_Analog_5dtUSB.h:51
vrpn_Analog::report_changes
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
VRPN_SUPPRESS_EMPTY_OBJECT_WARNING
#define VRPN_SUPPRESS_EMPTY_OBJECT_WARNING()
Definition: vrpn_Configure.h:495
vrpn_HidInterface::_acceptor
vrpn_HidAcceptor * _acceptor
This is the HidAcceptor we use when reconnecting.
Definition: vrpn_HumanInterface.h:127
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