root/branches/dev/wminput/plugins/acc/acc.c

Revision 118, 5.6 kB (checked in by dsmith, 2 years ago)

Create dev branch (currently contains experimental python plugins)

Line 
1 /* Copyright (C) 2007 L. Donnie Smith <cwiid@abstrakraft.org>
2  *
3  *  This program is free software; you can redistribute it and/or modify
4  *  it under the terms of the GNU General Public License as published by
5  *  the Free Software Foundation; either version 2 of the License, or
6  *  (at your option) any later version.
7  *
8  *  This program is distributed in the hope that it will be useful,
9  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  *  GNU General Public License for more details.
12  *
13  *  You should have received a copy of the GNU General Public License
14  *  along with this program; if not, write to the Free Software
15  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
16  *
17  *  ChangeLog:
18  *  2007-06-01 L. Donnie Smith <cwiid@abstrakraft.org>
19  *  * updated for wmplugin_exec prototype change (&mesg->mesg)
20  *  * updated for param interface change (pass pointers)
21  *
22  *  2007-05-14 L. Donnie Smith <cwiid@abstrakraft.org>
23  *  * use cwiid_get_acc_cal to get acc calibration values
24  *
25  *  2007-04-24 L. Donnie Smith <cwiid@abstrakraft.org>
26  *  * updated for API overhaul
27  *
28  *  2007-04-09 L. Donnie Smith <cwiid@abstrakraft.org>
29  *  * updated for libcwiid rename
30  *
31  *  2007-04-08 L. Donnie Smith <cwiid@abstrakraft.org>
32  *  * initialized params
33  *  * added Scale params
34  *
35  *  2007-04-08 Arthur Peters <amp@singingwizard.org>
36  *  * added low-pass filter
37  *
38  *  2007-03-04 L. Donnie Smith <cwiid@abstrakraft.org>
39  *  * type audit (stdint, const, char booleans)
40  *
41  *  2007-03-01 L. Donnie Smith <cwiid@abstrakraft.org>
42  *  * Initial ChangeLog
43  *  * made global variables static
44  */
45
46 #include <math.h>
47
48 #include "wmplugin.h"
49
50 #define PI      3.14159265358979323
51
52 static unsigned char info_init = 0;
53 static struct wmplugin_info info;
54 static struct wmplugin_data data;
55
56 static struct acc_cal acc_cal;
57
58 static int plugin_id;
59
60 wmplugin_info_t wmplugin_info;
61 wmplugin_init_t wmplugin_init;
62 wmplugin_exec_t wmplugin_exec;
63 static void process_acc(struct cwiid_acc_mesg *mesg);
64
65 static float Roll_Scale = 1.0;
66 static float Pitch_Scale = 1.0;
67 static float X_Scale = 1.0;
68 static float Y_Scale = 1.0;
69
70 struct wmplugin_info *wmplugin_info() {
71         if (!info_init) {
72                 info.button_count = 0;
73                 info.axis_count = 4;
74                 info.axis_info[0].name = "Roll";
75                 info.axis_info[0].type = WMPLUGIN_ABS;
76                 info.axis_info[0].max  =  3141;
77                 info.axis_info[0].min  = -3141;
78                 info.axis_info[0].fuzz = 0;
79                 info.axis_info[0].flat = 0;
80                 info.axis_info[1].name = "Pitch";
81                 info.axis_info[1].type = WMPLUGIN_ABS;
82                 info.axis_info[1].max  =  1570;
83                 info.axis_info[1].min  = -1570;
84                 info.axis_info[1].fuzz = 0;
85                 info.axis_info[1].flat = 0;
86                 info.axis_info[2].name = "X";
87                 info.axis_info[2].type = WMPLUGIN_ABS | WMPLUGIN_REL;
88                 info.axis_info[2].max  =  16;
89                 info.axis_info[2].min  = -16;
90                 info.axis_info[2].fuzz = 0;
91                 info.axis_info[2].flat = 0;
92                 info.axis_info[3].name = "Y";
93                 info.axis_info[3].type = WMPLUGIN_ABS | WMPLUGIN_REL;
94                 info.axis_info[3].max  =  16;
95                 info.axis_info[3].min  = -16;
96                 info.axis_info[3].fuzz = 0;
97                 info.axis_info[3].flat = 0;
98                 info.param_count = 4;
99                 info.param_info[0].name = "Roll_Scale";
100                 info.param_info[0].type = WMPLUGIN_PARAM_FLOAT;
101                 info.param_info[0].ptr = &Roll_Scale;
102                 info.param_info[1].name = "Pitch_Scale";
103                 info.param_info[1].type = WMPLUGIN_PARAM_FLOAT;
104                 info.param_info[1].ptr = &Pitch_Scale;
105                 info.param_info[2].name = "X_Scale";
106                 info.param_info[2].type = WMPLUGIN_PARAM_FLOAT;
107                 info.param_info[2].ptr = &X_Scale;
108                 info.param_info[3].name = "Y_Scale";
109                 info.param_info[3].type = WMPLUGIN_PARAM_FLOAT;
110                 info.param_info[3].ptr = &Y_Scale;
111                 info_init = 1;
112         }
113         return &info;
114 }
115
116 int wmplugin_init(int id, cwiid_wiimote_t *wiimote)
117 {
118         plugin_id = id;
119
120         data.buttons = 0;
121         data.axes[0].valid = 1;
122         data.axes[1].valid = 1;
123         if (wmplugin_set_rpt_mode(id, CWIID_RPT_ACC)) {
124                 return -1;
125         }
126
127         if (cwiid_get_acc_cal(wiimote, CWIID_EXT_NONE, &acc_cal)) {
128                 wmplugin_err(id, "calibration error");
129                 return -1;
130         }
131
132         return 0;
133 }
134
135 struct wmplugin_data *wmplugin_exec(int mesg_count, union cwiid_mesg mesg[])
136 {
137         int i;
138         struct wmplugin_data *ret = NULL;
139
140         for (i=0; i < mesg_count; i++) {
141                 switch (mesg[i].type) {
142                 case CWIID_MESG_ACC:
143                         process_acc(&mesg[i].acc_mesg);
144                         ret = &data;
145                         break;
146                 default:
147                         break;
148                 }
149         }
150
151         return ret;
152 }
153
154 #define NEW_AMOUNT 0.1
155 #define OLD_AMOUNT (1.0-NEW_AMOUNT)
156 double a_x = 0, a_y = 0, a_z = 0;
157
158 static void process_acc(struct cwiid_acc_mesg *mesg)
159 {
160         double a;
161         double roll, pitch;
162
163         a_x = (((double)mesg->acc[CWIID_X] - acc_cal.zero[CWIID_X]) /
164               (acc_cal.one[CWIID_X] - acc_cal.zero[CWIID_X]))*NEW_AMOUNT +
165               a_x*OLD_AMOUNT;
166         a_y = (((double)mesg->acc[CWIID_Y] - acc_cal.zero[CWIID_Y]) /
167               (acc_cal.one[CWIID_Y] - acc_cal.zero[CWIID_Y]))*NEW_AMOUNT +
168               a_y*OLD_AMOUNT;
169         a_z = (((double)mesg->acc[CWIID_Z] - acc_cal.zero[CWIID_Z]) /
170               (acc_cal.one[CWIID_Z] - acc_cal.zero[CWIID_Z]))*NEW_AMOUNT +
171               a_z*OLD_AMOUNT;
172
173         a = sqrt(pow(a_x,2)+pow(a_y,2)+pow(a_z,2));
174         roll = atan(a_x/a_z);
175         if (a_z <= 0.0) {
176                 roll += PI * ((a_x > 0.0) ? 1 : -1);
177         }
178
179         pitch = atan(a_y/a_z*cos(roll));
180
181         data.axes[0].value = roll  * 1000 * Roll_Scale;
182         data.axes[1].value = pitch * 1000 * Pitch_Scale;
183
184         if ((a > 0.85) && (a < 1.15)) {
185                 if ((fabs(roll)*(180/PI) > 10) && (fabs(pitch)*(180/PI) < 80)) {
186                         data.axes[2].valid = 1;
187                         data.axes[2].value = roll * 5 * X_Scale;
188                 }
189                 else {
190                         data.axes[2].valid = 0;
191                 }
192                 if (fabs(pitch)*(180/PI) > 10) {
193                         data.axes[3].valid = 1;
194                         data.axes[3].value = pitch * 10 * Y_Scale;
195                 }
196                 else {
197                         data.axes[3].valid = 0;
198                 }
199         }
200         else {
201                 data.axes[2].valid = 0;
202                 data.axes[3].valid = 0;
203         }
204 }
205
Note: See TracBrowser for help on using the browser.