2 * \brief Wiimote handling implementation
3 * \author Aurelien Morelle <aurelien.morelle@parrot.com>
15 #include <generated_custom.h>
17 #if defined(WIIMOTE_SUPPORT)
18 //#warning Wiimote support enabled
19 #include <bluetooth/bluetooth.h>
22 //#warning Wiimote support disabled
27 input_device_t wiimote_device = {
35 #if !defined(WIIMOTE_SUPPORT)
36 //#warning Wiimote compilation disabled
37 C_RESULT open_wiimote(void)
42 C_RESULT update_wiimote(void)
47 C_RESULT close_wiimote(void)
52 #else // ! WIIMOTE_SUPPORT
53 #warning Wiimote compilation enabled
55 #include <VP_Os/vp_os_print.h>
57 static bdaddr_t bdaddr = {0};
58 static cwiid_wiimote_t *wiimote = NULL;
60 static struct acc_cal wm_cal;
62 C_RESULT open_wiimote(void)
66 printf("\nSearching for Wiimote - press both '1' and '2' on your Wiimote !!\n");
68 if(cwiid_find_wiimote(&bdaddr, WIIMOTE_FIND_TIMEOUT) == 0)
70 if( ! (wiimote = cwiid_open(&bdaddr, 0)) )
71 PRINT("Unable to connect to wiimote\n");
77 if(cwiid_set_rpt_mode(wiimote, CWIID_RPT_BTN|CWIID_RPT_ACC))
81 if (cwiid_get_acc_cal(wiimote, CWIID_EXT_NONE, &wm_cal))
84 cwiid_set_led(wiimote,1);
86 printf(" ... Wiimote found.\n");
91 void print_state(struct cwiid_state *state)
93 printf("Battery: %d%%\n", (int)(100.0 * state->battery / CWIID_BATTERY_MAX));
94 printf("Buttons: %X\n", state->buttons);
95 printf("Acc: x=%d y=%d z=%d\n", state->acc[CWIID_X], state->acc[CWIID_Y], state->acc[CWIID_Z]);
98 //extern void api_set_iphone_acceleros(bool_t enable, float32_t fax, float32_t fay, float32_t faz);
100 #define NEW_AMOUNT 0.1
101 #define OLD_AMOUNT (1.0-NEW_AMOUNT)
112 static void rumble(int flag)
114 static int localflag=0;
115 if (flag!=localflag){
117 cwiid_set_rumble(wiimote,flag);
121 static void leds(int flags)
123 static int localflags=0;
124 if (flags!=localflags){
126 cwiid_set_led(wiimote,flags);
130 C_RESULT update_wiimote(void)
133 static struct cwiid_state state,previous_state;
135 static int control_mode = 1;
136 static int valid_domain = 0;
142 static vec3 a={0,0,0},s={0,0,0};
143 static vec3sph r={0,0,0},pr={0,0,0},rref={0,0,0};
145 static float pitch=0.0f,roll=0.0f,gaz=0.0f,yaw=0.0f;
152 if (cwiid_get_state(wiimote, &state))
154 fprintf(stderr, "Error getting state\n");
159 #define SWITCHING(X) ((state.buttons&X) && !(previous_state.buttons&X))
160 #define RELEASING(X) ((!state.buttons&X) && (previous_state.buttons&X))
161 #define PRESSED(X) ((state.buttons&X))
162 static int flag_rumble=0;
163 #define RUMBLE_ON { if (!flag_rumble) {flag_rumble=1; } }
164 /* Sets how to use the wiimote */
166 if (SWITCHING(CWIID_BTN_MINUS)) {
168 if (control_mode<1) control_mode=MAXMODE;
169 leds(1<<(control_mode-1));
171 if (SWITCHING(CWIID_BTN_PLUS)) {
173 if (control_mode>MAXMODE) control_mode=1;
174 leds(1<<(control_mode-1));
177 /* Gets gravitation G projection on x,y,z axis */
178 a.x = - (float32_t) ((((double)state.acc[CWIID_X] - wm_cal.zero[CWIID_X]) /
179 (wm_cal.one[CWIID_X] - wm_cal.zero[CWIID_X])));
180 a.y = - (float32_t) ((((double)state.acc[CWIID_Y] - wm_cal.zero[CWIID_Y]) /
181 (wm_cal.one[CWIID_Y] - wm_cal.zero[CWIID_Y])));
182 a.z = + (float32_t) ((((double)state.acc[CWIID_Z] - wm_cal.zero[CWIID_Z]) /
183 (wm_cal.one[CWIID_Z] - wm_cal.zero[CWIID_Z])));
185 s.x = (a.x<0.0f)?(1.0f):(-1.0f);
186 s.y = (a.y<0.0f)?(1.0f):(-1.0f);
187 s.z = (a.z<0.0f)?(1.0f):(-1.0f);
193 r.r = sqrtf((ax2+ay2)+az2);
200 if (r.r==0.0f) { r.p=r.t=0.0f; } else {
201 // Angle gauche/droite
202 r.p = asin(a.y); if (isnan(r.p)) r.p=0.0f;
204 // Sur plan vertical radial
205 r.t = acos(a.z/(sqrtf(az2+ax2))); if (isnan(r.t)) r.t=0.0f;
213 if (r.r==0.0f) { r.p=r.t=0.0f; } else {
214 // Angle entre le projete de G sur le plan vertical longitudinal (yz) et l'axe z
215 r.p = acos(a.z/(sqrtf(az2+ay2))); if (isnan(r.p)) r.p=0.0f;
216 /* If wiimote faces the ground */
217 //if (a.z<0.0f) r.p= M_PI-r.p;
219 // Idem sur le plan vertical radial
220 r.t = acos(a.z/(sqrtf(az2+ax2))); if (isnan(r.t)) r.t=0.0f;
226 r.r = (r.r+pr.r)/2.0f;
227 r.t = (r.t+pr.t)/2.0f;
228 r.p = (r.p+pr.p)/2.0f;
237 /* Wiimote is handled horizontally.
238 * '2' button under left thumb
239 * directionnal cross under right thumb
243 /* 0 -> buttons facing sky */
245 if ((SWITCHING(CWIID_BTN_1)||SWITCHING(CWIID_BTN_2)||SWITCHING(CWIID_BTN_B))){ rref=r; }
247 if (PRESSED(CWIID_BTN_1)||PRESSED(CWIID_BTN_2)||PRESSED(CWIID_BTN_B))
249 /* If wiimote facing ground */
257 leds(1<<(control_mode-1));
258 pitch = (r.t-rref.t)*1.0f; if (pitch<-1.0f) pitch=-1.0f; if (pitch>1.0f) pitch=1.0f;
259 roll = -(r.p-rref.p)*0.75f; if (roll<-1.0f) roll=-1.0f; if (roll>1.0f) roll=1.0f;
267 leds(1<<(control_mode-1));
272 gaz = (PRESSED(CWIID_BTN_LEFT))? 1.0f: (PRESSED(CWIID_BTN_RIGHT)) ? -1.0f : 0.0f;
273 yaw = (PRESSED(CWIID_BTN_DOWN))? -1.0f: (PRESSED(CWIID_BTN_UP)) ? 1.0f : (control_mode==2) ? (-pitch*roll) : 0.0f;
281 if (PRESSED(CWIID_BTN_B))
290 leds(1<<(control_mode-1));
291 pitch = -(r.p-rref.p)*1.5f; if (pitch<-1.0f) pitch=-1.0f; if (pitch>1.0f) pitch=1.0f;
292 roll = (r.t-rref.t)*1.5f; if (roll<-1.0f) roll=-1.0f; if (roll>1.0f) roll=1.0f;
299 leds(1<<(control_mode-1));
305 if (SWITCHING(CWIID_BTN_B)) { rref = r; }
307 gaz = (PRESSED(CWIID_BTN_DOWN))? -1.0f: (PRESSED(CWIID_BTN_UP)) ? +1.0f : 0.0f;
308 yaw = (PRESSED(CWIID_BTN_LEFT))? -1.0f: (PRESSED(CWIID_BTN_RIGHT)) ? 1.0f : (control_mode==4) ? (-pitch*roll) : 0.0f;
311 /* Buttons common to all modes */
312 if (SWITCHING(CWIID_BTN_A)) { start^=1; ardrone_tool_set_ui_pad_start(start); }
313 if (SWITCHING(CWIID_BTN_HOME)) {
315 ardrone_tool_set_ui_pad_select(select);
316 ardrone_tool_set_ui_pad_start(0);
321 //printf("Wiimote mode 2 [ax %f][ay %f][az %f]\n\033[1A", a.x,a.y,a.z);
322 printf("Wiimode %i [rr %3.2f][rp %3.2f][rt %3.2f]\n", control_mode,r.r,r.p,r.t);
323 printf("[Fly %i][Ptc %3.2f][Rl %3.2f][Yw %3.2f][Gz %3.2f][Strt. %i][Sel. %i]\n\033[2A", fly,pitch,roll,yaw,gaz,start,select);
324 ardrone_at_set_progress_cmd( fly,/*roll*/roll,/*pitch*/pitch,/*gaz*/gaz,/*yaw*/yaw);
326 /*api_set_iphone_acceleros(
327 (state.buttons&CWIID_BTN_2 ? 1 : 0)|(state.buttons&CWIID_BTN_A ? 2 : 0),
330 previous_state = state;
336 C_RESULT close_wiimote(void)
338 cwiid_close(wiimote);
343 #endif // ! WIIMOTE_SUPPORT