vrpn  07.33
Virtual Reality Peripheral Network
vrpn_WiiMote.h
Go to the documentation of this file.
1 // vrpn_WiiMote.h: Drive for the WiiMote, based on the WiiUse library.
2 // Tested on Windows. Is supposed to also run on Linux.
3 //
4 // Russ Taylor, revised December 2008
5 
6 #ifndef VRPN_WIIMOTE_H
7 #define VRPN_WIIMOTE_H
8 
9 #include "vrpn_Configure.h" // IWYU pragma: keep
10 
11 #if defined(VRPN_USE_WIIUSE)
12 
13 #include "vrpn_Analog.h"
14 #include "vrpn_Analog_Output.h"
15 #include "vrpn_Button.h"
16 #include "vrpn_Connection.h"
17 #include "vrpn_Shared.h"
18 
19 // maximum number of wiimotes connected to the system
20 #define VRPN_WIIUSE_MAX_WIIMOTES 4
21 
22 // Opaque class to keep us from having to include wiiuse.h in user files.
23 // This is defined in vrpn_WiiMote.C.
24 class vrpn_Wiimote_Device;
25 struct wiimote_t;
26 #ifdef vrpn_THREADS_AVAILABLE
27 struct vrpn_WiiMote_SharedData;
28 #endif
29 
30 // The buttons are as read from the bit-fields of the primary controller (bits 0-15)
31 // and then a second set for any extended controller (nunchuck bits 16-31),
32 // (classic controller bits 32-47), (guitar hero 3 bits 48-63).
33 //
34 // If you enable "reorderButtons" by setting it to 1, the buttons on the Wiimote
35 // itself are re-ordered to be reported as follows:
36 // button[0] = Home
37 // button[1] = "1"
38 // button[2] = "2"
39 // button[3] = "A"
40 // button[4] = "B"
41 // button[5] = "-"
42 // button[6] = "+"
43 // button[7] = direction pad: left
44 // button[8] = direction pad: right
45 // button[9] = direction pad: down
46 // button[10] = direction pad: up
47 // button[11] = WIIMOTE_BUTTON_ZACCEL_BIT4
48 // button[12] = WIIMOTE_BUTTON_ZACCEL_BIT5
49 // button[13] = WIIMOTE_BUTTON_ZACCEL_BIT6
50 // button[14] = WIIMOTE_BUTTON_ZACCEL_BIT7
51 // button[15] = WIIMOTE_BUTTON_UNKNOWN
52 //
53 // The Analogs are in an even more random order, both from the primary controller:
54 // channel[0] = battery level (0-1)
55 // channel[1] = gravity X vector calculation (1 = Earth gravity)
56 // channel[2] = gravity Y vector calculation (1 = Earth gravity)
57 // channel[3] = gravity Z vector calculation (1 = Earth gravity)
58 // channel[4] = X of first sensor spot (0-1023, -1 if not seen)
59 // channel[5] = Y of first sensor spot (0-767, -1 if not seen)
60 // channel[6] = size of first sensor spot (0-15, -1 if not seen)
61 // channel[7] = X of second sensor spot (0-1023, -1 if not seen)
62 // channel[9] = Y of second sensor spot (0-767, -1 if not seen)
63 // channel[9] = size of second sensor spot (0-15, -1 if not seen)
64 // channel[10] = X of third sensor spot (0-1023, -1 if not seen)
65 // channel[11] = Y of third sensor spot (0-767, -1 if not seen)
66 // channel[12] = size of third sensor spot (0-15, -1 if not seen)
67 // channel[13] = X of fourth sensor spot (0-1023, -1 if not seen)
68 // channel[14] = Y of fourth sensor spot (0-767, -1 if not seen)
69 // channel[15] = size of fourth sensor spot (0-15, -1 if not seen)
70 // and on the secondary controllers (skipping values to leave room for expansion)
71 // (with the joystick x and y values only available with WiiUse 0.14.2 or newer)
72 // channel[16] = nunchuck gravity X vector
73 // channel[17] = nunchuck gravity Y vector
74 // channel[18] = nunchuck gravity Z vector
75 // channel[19] = nunchuck joystick angle
76 // channel[20] = nunchuck joystick magnitude
77 // channel[21] = nunchuck joystick X
78 // channel[22] = nunchuck joystick Y
79 //
80 // channel[32] = classic L button
81 // channel[33] = classic R button
82 // channel[34] = classic L joystick angle
83 // channel[35] = classic L joystick magnitude
84 // channel[36] = classic R joystick angle
85 // channel[37] = classic R joystick magnitude
86 // channel[38] = classic L joystick X
87 // channel[39] = classic L joystick Y
88 // channel[40] = classic R joystick X
89 // channel[41] = classic R joystick Y
90 //
91 // channel[48] = guitar hero whammy bar
92 // channel[49] = guitar hero joystick angle
93 // channel[50] = guitar hero joystick magnitude
94 // channel[51] = guitar hero joystick X
95 // channel[52] = guitar hero joystick Y
96 //
97 // Balance board data: (requires WiiUse 0.13 or newer, preferably 0.14 or newer)
98 // channel[64] = Balance board: top-left sensor, kg
99 // channel[65] = Balance board: top-right sensor, kg
100 // channel[66] = Balance board: bottom-left sensor, kg
101 // channel[67] = Balance board: bottom-right sensor, kg
102 // channel[68] = Balance board: total mass, kg
103 // channel[69] = Balance board: center of gravity x, in [-1, 1]
104 // channel[70] = Balance board: center of gravity y, in [-1, 1]
105 //
106 // The Analog_Output 0 is a hack to enable control over the rumble, inherited from
107 // the RumblePack driver. This should eventually move to a binary output of
108 // some kind (and so should the lights). For now, if you set output 0 to a
109 // value greater than or equal to 0.5, it will turn on the rumble; if less, then
110 // it will disable it.
111 // Channel 1 sets the IR sensitivity: accepts 1, 2, 3, 4, 5 (clipping to this
112 // range if given other values), same as the Wii system's sensitivity settings.
113 
114 // XXX It would be great to use the IR and accelerometer data along with
115 // a description of the size of the official Wii sensor bar to compute
116 // a pose and report this as a tracker report. This could be done as
117 // a second device that reads the values or (better) as a built-in that
118 // exports a vrpn_Tracker report. Best would be a Kalman filter that
119 // takes all of these as inputs and produces an optimal estimate. This
120 // needs to report in meters and we'll have to define an origin (middle
121 // of the bar?) and a coordinate system (X along bar's most-horizontal
122 // axis, Y vertical to gravity, Z perpendicular to these?).
123 
124 // XXX It would be great to have a vrpn_Sound device that could play through
125 // the speaker on the WiiMote.
126 
128  public:
129  // If there is more than one WiiMote on the machine, the zero-indexed 'which'
130  // parameter tells which one we want to open.
131  vrpn_WiiMote(const char *name, vrpn_Connection *c = NULL, unsigned which = 0
132  , unsigned useMS = 1, unsigned useIR = 1, unsigned reorderButtons = 0,
133  const char *bdaddr = NULL);
134  ~vrpn_WiiMote();
135 
136  virtual void mainloop();
137 
138  bool isValid() const;
139 
140  protected:
141  // Handle the rumble-magnitude setting (channel 0).
142  static int VRPN_CALLBACK handle_request_message(void *userdata,
144  static int VRPN_CALLBACK handle_request_channels_message(void* userdata,
146  static int VRPN_CALLBACK handle_last_connection_dropped(void *selfPtr, vrpn_HANDLERPARAM data);
147 
148  private:
153  void acquireMessageLock();
154  void releaseMessageLock();
156 #ifdef vrpn_THREADS_AVAILABLE
157  static void connectThreadFunc(vrpn_ThreadData &threadData);
160  bool waitingForConnection;
162  vrpn_WiiMote_SharedData *sharedData;
164  vrpn_Thread *connectThread;
165 #else
166  struct timeval last_reconnect_attempt
167 #endif
169  vrpn_Wiimote_Device *wiimote;
171  wiimote_t **available_wiimotes;
172 
174  inline void FAIL(const char *msg) {
175  struct timeval now;
176  vrpn_gettimeofday(&now, NULL);
178  d_connection = NULL;
179  }
180 
186  void report_changes(vrpn_uint32 class_of_service = vrpn_CONNECTION_LOW_LATENCY);
192  void report(vrpn_uint32 class_of_service = vrpn_CONNECTION_LOW_LATENCY);
193 
195  struct timeval _timestamp;
196 
198  void initialize_wiimote_state(void);
199 
201  void handle_event(void);
202 
204  void connect_wiimote(int timeout);
205 
207  unsigned map_button(unsigned btn);
208 };
209 
210 #endif // VRPN_USE_WIIUSE
211 
212 #endif // VRPN_WIIMOTE_H
vrpn_Thread
Definition: vrpn_Shared.h:558
vrpn_Analog_Output.h
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
Definition: vrpn_Analog.h:28
vrpn_Analog_Output
Definition: vrpn_Analog_Output.h:26
vrpn_CONNECTION_LOW_LATENCY
const vrpn_uint32 vrpn_CONNECTION_LOW_LATENCY
Definition: vrpn_Connection.h:122
vrpn_WiiMote
Definition: vrpn_WiiMote.h:127
vrpn_TEXT_ERROR
Definition: vrpn_BaseClass.h:103
vrpn_ThreadData
Definition: vrpn_Shared.h:548
vrpn_HANDLERPARAM
This structure is what is passed to a vrpn_Connection message callback.
Definition: vrpn_Connection.h:44
vrpn_Shared.h
vrpn_Button.h
vrpn_BaseClass::mainloop
virtual void mainloop()=0
Called once through each main loop iteration to handle updates. Remote object mainloop() should call ...
vrpn_Connection
Generic connection class not specific to the transport mechanism.
Definition: vrpn_Connection.h:510
vrpn_Connection.h
vrpn_gettimeofday
#define vrpn_gettimeofday
Definition: vrpn_Shared.h:89
vrpn_Analog.h
VRPN_CALLBACK
#define VRPN_CALLBACK
Definition: vrpn_Configure.h:647
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_Configure.h
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_API
#define VRPN_API
Definition: vrpn_Configure.h:646
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