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