vrpn 07.35
Virtual Reality Peripheral Network
 
Loading...
Searching...
No Matches
vrpn_Analog_5dtUSB.C
Go to the documentation of this file.
1
13
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
27static const vrpn_uint16 vrpn_5DT_VENDOR = 0x5d70;
28
29static const vrpn_uint16 vrpn_5DT_LEFT_MASK = 0x0001;
30static const vrpn_uint16 vrpn_5DT_RIGHT = 0x0000;
31static const vrpn_uint16 vrpn_5DT_LEFT = 0x0001;
32static const vrpn_uint16 vrpn_5DT_WIRELESS_PORTA_MASK = 0x0002;
33static const vrpn_uint16 vrpn_5DT_WIRELESS_PORTB_MASK = 0x0006;
34static const vrpn_uint16 vrpn_5DT_DATAGLOVE5_MASK = 0x0010;
35static const vrpn_uint16 vrpn_5DT_DATAGLOVE5 = 0x0010;
36static 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),
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 try {
79 delete m_acceptor;
80 } catch (...) {
81 fprintf(stderr, "vrpn_Analog_5dtUSB::~vrpn_Analog_5dtUSB(): delete failed\n");
82 return;
83 }
84}
86 std::ostringstream ss;
87 if (product() & vrpn_5DT_LEFT_MASK) {
88 ss << "left";
89 } else {
90 ss << "right";
91 }
92
93 ss << " hand, ";
94 if (product() & vrpn_5DT_DATAGLOVE5_MASK) {
95 ss << "5";
96 } else {
97 ss << "14";
98 }
99
100 ss << " sensors, ";
101 if (product() & vrpn_5DT_WIRELESS_PORTA_MASK) {
102 ss << "wireless port A";
103 } else if (product() & vrpn_5DT_WIRELESS_PORTB_MASK) {
104 ss << "wireless port B";
105 } else {
106 ss << "wired USB";
107 }
108 return ss.str();
109}
110
111void vrpn_Analog_5dtUSB::on_data_received(size_t bytes, vrpn_uint8 *buffer) {
112 if (bytes != 64) {
113 std::ostringstream ss;
114 ss << "Received a too-short report: " << bytes;
115 struct timeval ts;
116 vrpn_gettimeofday(&ts, NULL);
117 send_text_message(ss.str().c_str(), ts, vrpn_TEXT_WARNING);
118 return;
119 }
120
121 // Decode all full reports.
122 const float scale = 1.0f / 4096.0f;
123 vrpn_uint8 * bufptr = buffer;
124 for (size_t i = 0; i < 16; i++) {
125 _rawVals[i] = vrpn_unbuffer<vrpn_int16>(bufptr) * scale;
126 }
127
128 switch (vrpn_Analog::num_channel) {
129 case 5:
130 for (size_t i = 0; i < 5; ++i) {
131 channel[i] = _rawVals[i * 3];
132 // Report this event before parsing the next.
134 }
135 break;
136
137 case 14:
138 for (size_t i = 0; i < 14; ++i) {
139 channel[i] = _rawVals[i];
140 // Report this event before parsing the next.
142 }
143 break;
144 default:
145 std::cerr << "Internal error - should not happen: Unrecognized number of channels!" << std::endl;
146 }
147}
148
151
152 update();
153
154 if (connected() && !_wasConnected) {
155 std::ostringstream ss;
156 ss << "Successfully connected to 5DT glove, " << get_description();
158 }
160
162}
163
164void vrpn_Analog_5dtUSB::report_changes(vrpn_uint32 class_of_service) {
166
167 vrpn_Analog::report_changes(class_of_service);
168}
169
170void vrpn_Analog_5dtUSB::report(vrpn_uint32 class_of_service) {
172
173 vrpn_Analog::report(class_of_service);
174}
175
176
178 vrpn_Analog_5dtUSB(new vrpn_HidProductMaskAcceptor(vrpn_5DT_VENDOR, vrpn_5DT_LEFT_MASK | vrpn_5DT_DATAGLOVE5_MASK, vrpn_5DT_LEFT | vrpn_5DT_DATAGLOVE5),
179 5,
180 true,
181 name,
182 c) { }
183
185 vrpn_Analog_5dtUSB(new vrpn_HidProductMaskAcceptor(vrpn_5DT_VENDOR, vrpn_5DT_LEFT_MASK | vrpn_5DT_DATAGLOVE5_MASK, vrpn_5DT_RIGHT | vrpn_5DT_DATAGLOVE5),
186 5,
187 false,
188 name,
189 c) { }
190
192 vrpn_Analog_5dtUSB(new vrpn_HidProductMaskAcceptor(vrpn_5DT_VENDOR, vrpn_5DT_LEFT_MASK | vrpn_5DT_DATAGLOVE5_MASK, vrpn_5DT_LEFT | vrpn_5DT_DATAGLOVE14),
193 14,
194 true,
195 name,
196 c) { }
197
199 vrpn_Analog_5dtUSB(new vrpn_HidProductMaskAcceptor(vrpn_5DT_VENDOR, vrpn_5DT_LEFT_MASK | vrpn_5DT_DATAGLOVE5_MASK, vrpn_5DT_RIGHT | vrpn_5DT_DATAGLOVE14),
200 14,
201 false,
202 name,
203 c) { }
204
205#endif
206
vrpn_Analog_5dtUSB_Glove14Left(const char *name, vrpn_Connection *c=0)
vrpn_Analog_5dtUSB_Glove14Right(const char *name, vrpn_Connection *c=0)
vrpn_Analog_5dtUSB_Glove5Left(const char *name, vrpn_Connection *c=0)
vrpn_Analog_5dtUSB_Glove5Right(const char *name, vrpn_Connection *c=0)
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.
void report_changes(vrpn_uint32 class_of_service=vrpn_CONNECTION_LOW_LATENCY)
Send report iff changed.
bool _wasConnected
Flag indicating whether we were connected last time through the mainloop. Used to send a "normal"-sev...
struct timeval _timestamp
Timestamp updated during mainloop()
std::string get_description() const
Returns a string description of the device we've connected to. Used internally, but also possibly use...
void report(vrpn_uint32 class_of_service=vrpn_CONNECTION_LOW_LATENCY)
Send report whether or not changed.
void on_data_received(size_t bytes, vrpn_uint8 *buffer)
Extracts the sensor values from each report.
bool isLeftHand() const
Accessor to know if this is a left hand glove.
double _rawVals[16]
The raw values extracted from the report: which ones we use to set analog channels varies based on th...
bool _isLeftHand
Flag for left handedness.
virtual void mainloop()
Standard VRPN mainloop method.
virtual ~vrpn_Analog_5dtUSB()
Destructor.
vrpn_float64 last[vrpn_CHANNEL_MAX]
Definition vrpn_Analog.h:39
vrpn_float64 channel[vrpn_CHANNEL_MAX]
Definition vrpn_Analog.h:38
vrpn_Analog(const char *name, vrpn_Connection *c=NULL)
Definition vrpn_Analog.C:14
struct timeval timestamp
Definition vrpn_Analog.h:41
vrpn_int32 num_channel
Definition vrpn_Analog.h:40
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
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
void server_mainloop(void)
Handles functions that all servers should provide in their mainloop() (ping/pong, for example) Should...
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.
Generic connection class not specific to the transport mechanism.
vrpn_uint16 product() const
Returns USB product ID of connected device May not contain valid if an already-open device was provid...
vrpn_HidInterface(vrpn_HidAcceptor *acceptor, vrpn_uint16 vendor=0, vrpn_uint16 product=0, hid_device *device=NULL)
Constructor If we already have a HID device from some other source, it can be passed and we'll take o...
vrpn_HidAcceptor * m_acceptor
This is the HidAcceptor we use when reconnecting.
virtual void update()
Polls the device buffers and causes on_data_received callbacks if appropriate You NEED to call this f...
virtual bool connected() const
Returns true iff the last device I/O succeeded.
HID acceptor subclass used by vrpn_Analog_5dtUSB since the bits of the product ID for these devices d...
header for 5DT USB (HID) dataglove driver
All types of client/server/peer objects in VRPN should be derived from the vrpn_BaseClass type descri...
@ vrpn_TEXT_NORMAL
@ vrpn_TEXT_WARNING
#define VRPN_SUPPRESS_EMPTY_OBJECT_WARNING()
VRPN_API int vrpn_unbuffer(const char **buffer, timeval *t)
Utility routine for taking a struct timeval from a buffer that was sent as a message.
#define vrpn_gettimeofday
Definition vrpn_Shared.h:99