vrpn  07.33
Virtual Reality Peripheral Network
vrpn_Contour.C
Go to the documentation of this file.
1 // vrpn_Contour.C: VRPN driver for Contour Design devices
2 
3 #include <stdio.h> // for fprintf, stderr, NULL
4 #include <string.h> // for memset
5 #include <math.h> // for fabs
6 
7 #include "vrpn_Contour.h"
9 
10 #if defined(VRPN_USE_HID)
11 
12 static const double POLL_INTERVAL = 1e+6 / 30.0; // If we have not heard, ask.
13 
14 // USB vendor and product IDs for the models we support
15 static const vrpn_uint16 CONTOUR_VENDOR = 0x0b33;
16 static const vrpn_uint16 CONTOUR_SHUTTLEXPRESS = 0x0020;
17 
18 static void normalize_axis(const unsigned int value, const short deadzone, const vrpn_float64 scale, vrpn_float64& channel) {
19  channel = (static_cast<float>(value) - 128.0f);
20  if (fabs(channel) < deadzone)
21  {
22  channel = 0.0f;
23  }
24  else
25  {
26  channel /= 128.0f;
27  }
28  channel *= scale;
29  if (channel < -1.0) { channel = -1.0; }
30  if (channel > 1.0) { channel = 1.0; }
31 }
32 
33 static void normalize_axes(const unsigned int x, const unsigned int y, const short deadzone, const vrpn_float64 scale, vrpn_float64& channelX, vrpn_float64& channelY) {
34  normalize_axis(x, deadzone, scale, channelX);
35  normalize_axis(y, deadzone, scale, channelY);
36 }
37 
39  : vrpn_HidInterface(filter)
40  , vrpn_BaseClass(name, c)
41  , _filter(filter)
42 {
43  init_hid();
44 }
45 
47 {
48  delete _filter;
49 }
50 
52  // Get notifications when clients connect and disconnect
55 }
56 
57 void vrpn_Contour::on_data_received(size_t bytes, vrpn_uint8 *buffer)
58 {
59  decodePacket(bytes, buffer);
60 }
61 
63 {
64  vrpn_Contour *me = static_cast<vrpn_Contour *>(thisPtr);
65  return 0;
66 }
67 
69 {
70  vrpn_Contour *me = static_cast<vrpn_Contour *>(thisPtr);
71  return 0;
72 }
73 
75  : vrpn_Contour(_filter = new vrpn_HidProductAcceptor(CONTOUR_VENDOR, CONTOUR_SHUTTLEXPRESS), name, c)
76  , vrpn_Button_Filter(name, c)
77  , vrpn_Analog(name, c)
78  , vrpn_Dial(name, c)
79 {
83 
84  // Initialize the state of all the analogs, buttons, and dials
85  _lastDial = 0;
86  memset(buttons, 0, sizeof(buttons));
87  memset(lastbuttons, 0, sizeof(lastbuttons));
88  memset(channel, 0, sizeof(channel));
89  memset(last, 0, sizeof(last));
90 }
91 
93 {
94  update();
96  struct timeval current_time;
97  vrpn_gettimeofday(&current_time, NULL);
98  if (vrpn_TimevalDuration(current_time, _timestamp) > POLL_INTERVAL ) {
99  _timestamp = current_time;
100  report_changes();
101 
102  if (vrpn_Analog::num_channel > 0)
103  {
105  }
106  if (vrpn_Button::num_buttons > 0)
107  {
109  }
110  if (vrpn_Dial::num_dials > 0)
111  {
113  }
114  }
115 }
116 
117 void vrpn_Contour_ShuttleXpress::report(vrpn_uint32 class_of_service) {
118  if (vrpn_Analog::num_channel > 0)
119  {
121  }
122  if (vrpn_Button::num_buttons > 0)
123  {
125  }
126  if (vrpn_Dial::num_dials > 0)
127  {
129  }
130 
131  if (vrpn_Analog::num_channel > 0)
132  {
133  vrpn_Analog::report(class_of_service);
134  }
135  if (vrpn_Button::num_buttons > 0)
136  {
138  }
139  if (vrpn_Dial::num_dials > 0)
140  {
142  }
143 }
144 
145 void vrpn_Contour_ShuttleXpress::report_changes(vrpn_uint32 class_of_service) {
146  if (vrpn_Analog::num_channel > 0)
147  {
149  }
150  if (vrpn_Button::num_buttons > 0)
151  {
153  }
154  if (vrpn_Dial::num_dials > 0)
155  {
157  }
158 
159  if (vrpn_Analog::num_channel > 0)
160  {
161  vrpn_Analog::report(class_of_service);
162  }
163  if (vrpn_Button::num_buttons > 0)
164  {
166  }
167  if (vrpn_Dial::num_dials > 0)
168  {
170  }
171 }
172 
173 void vrpn_Contour_ShuttleXpress::decodePacket(size_t bytes, vrpn_uint8 *buffer) {
174  // Decode all full reports, each of which is 5 bytes long.
175  // Because there is only one type of report, the initial "0" report-type
176  // byte is removed by the HIDAPI driver.
177  // XXX Check to see that this works with HIDAPI, there may be two smaller reports.
178  if (bytes == 5) {
179  // analog (1st byte): 0 center, 1..7 right, -1..-7 left
180  normalize_axis((unsigned int) ((static_cast<float>(static_cast<vrpn_int8>(buffer[0])) * 128.0f / 7.0f) + 128.0f), 0, 1.0f, channel[0]);
181 
182  if (vrpn_Dial::num_dials > 0)
183  {
184  // dial (2nd byte)
185  // Do the unsigned/signed conversion at the last minute so the signed values work properly.
186  dials[0] = static_cast<vrpn_int8>(buffer[1] - _lastDial);
187  _lastDial = buffer[1];
188  }
189  else
190  {
191  // dial (2nd byte)
192  normalize_axis((unsigned int) (static_cast<float>(static_cast<vrpn_int8>(buffer[1])) + 128.0f), 0, 1.0f, channel[1]);
193  }
194 
195  vrpn_uint8 value;
196  // buttons (4th byte):
197  value = buffer[3];
198  for (int btn = 0; btn < 4; btn++) {
199  vrpn_uint8 mask = static_cast<vrpn_uint8>((1 << (btn % 8)) << 4);
200  buttons[btn] = ((value & mask) != 0);
201  }
202  // buttons (5th byte):
203  value = buffer[4];
204  for (int btn = 0; btn < 1; btn++) {
205  vrpn_uint8 mask = static_cast<vrpn_uint8>(1 << (btn % 8));
206  buttons[btn + 4] = ((value & mask) != 0);
207  }
208  } else {
209  fprintf(stderr, "vrpn_Contour_ShuttleXpress: Found a corrupted report; # total bytes = %u\n", static_cast<unsigned>(bytes));
210  }
211 }
212 
213 // End of VRPN_USE_HID
214 #endif
void server_mainloop(void)
Handles functions that all servers should provide in their mainloop() (ping/pong, for example) Should...
vrpn_HidAcceptor * _filter
Definition: vrpn_Contour.h:42
vrpn_Contour_ShuttleXpress(const char *name, vrpn_Connection *c=0)
Definition: vrpn_Contour.C:74
vrpn_int32 num_buttons
Definition: vrpn_Button.h:47
struct timeval _timestamp
Definition: vrpn_Contour.h:41
virtual void decodePacket(size_t bytes, vrpn_uint8 *buffer)=0
vrpn_float64 channel[vrpn_CHANNEL_MAX]
Definition: vrpn_Analog.h:38
Accepts any device with the given vendor and product IDs.
struct timeval timestamp
Definition: vrpn_Dial.h:28
Generic connection class not specific to the transport mechanism.
vrpn_int32 num_dials
Definition: vrpn_Dial.h:27
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
#define VRPN_SUPPRESS_EMPTY_OBJECT_WARNING()
const char * vrpn_dropped_last_connection
virtual void report_changes(void)
Definition: vrpn_Button.C:382
virtual void report_changes(void)
Definition: vrpn_Button.C:422
vrpn_int32 num_channel
Definition: vrpn_Analog.h:40
virtual void report(void)
Definition: vrpn_Dial.C:82
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.
void on_data_received(size_t bytes, vrpn_uint8 *buffer)
Derived class reimplements this callback.
Definition: vrpn_Contour.C:57
vrpn_Connection * d_connection
Connection that this object talks to.
vrpn_Contour(vrpn_HidAcceptor *filter, const char *name, vrpn_Connection *c=0)
Definition: vrpn_Contour.C:38
This structure is what is passed to a vrpn_Connection message callback.
#define POLL_INTERVAL
Definition: vrpn_IDEA.C:26
const char * vrpn_got_connection
struct timeval timestamp
Definition: vrpn_Button.h:48
void decodePacket(size_t bytes, vrpn_uint8 *buffer)
Definition: vrpn_Contour.C:173
#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...
virtual void mainloop(void)
Called once through each main loop iteration to handle updates. Remote object mainloop() should call ...
Definition: vrpn_Contour.C:92
Class from which all user-level (and other) classes that communicate with vrpn_Connections should der...
void init_hid(void)
Definition: vrpn_Contour.C:51
All button servers should derive from this class, which provides the ability to turn any of the butto...
Definition: vrpn_Button.h:65
unsigned char lastbuttons[vrpn_BUTTON_MAX_BUTTONS]
Definition: vrpn_Button.h:45
virtual ~vrpn_Contour(void)
Definition: vrpn_Contour.C:46
unsigned char buttons[vrpn_BUTTON_MAX_BUTTONS]
Definition: vrpn_Button.h:44
unsigned long vrpn_TimevalDuration(struct timeval endT, struct timeval startT)
Return number of microseconds between startT and endT.
Definition: vrpn_Shared.C:129
virtual vrpn_int32 register_message_type(const char *name)
static int VRPN_CALLBACK on_last_disconnect(void *thisPtr, vrpn_HANDLERPARAM p)
Definition: vrpn_Contour.C:62
struct timeval timestamp
Definition: vrpn_Analog.h:41
static int VRPN_CALLBACK on_connect(void *thisPtr, vrpn_HANDLERPARAM p)
Definition: vrpn_Contour.C:68
vrpn_float64 last[vrpn_CHANNEL_MAX]
Definition: vrpn_Analog.h:39
vrpn_float64 dials[vrpn_DIAL_MAX]
Definition: vrpn_Dial.h:26