Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/wiimote/src/external/wiicpp/wiic/dynamics.c @ 9812

Last change on this file since 9812 was 9780, checked in by georgr, 11 years ago

WiiCpp library successfully (?) added - won't work without libbluetooth-dev

  • Property svn:executable set to *
File size: 5.9 KB
Line 
1/*
2 *    dynamics.c
3 *
4 *        This file is part of WiiC, written by:
5 *              Gabriele Randelli
6 *              Email: randelli@dis.uniroma1.it
7 *
8 *    Copyright 2010
9 *             
10 *        This file is based on Wiiuse, written By:
11 *              Michael Laforest        < para >
12 *              Email: < thepara (--AT--) g m a i l [--DOT--] com >
13 *
14 *        Copyright 2006-2007
15 *
16 *    This program is free software; you can redistribute it and/or modify
17 *    it under the terms of the GNU General Public License as published by
18 *    the Free Software Foundation; either version 3 of the License, or
19 *    (at your option) any later version.
20 *
21 *    This program is distributed in the hope that it will be useful,
22 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
23 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24 *    GNU General Public License for more details.
25 *
26 *    You should have received a copy of the GNU General Public License
27 *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
28 *
29 *        $Header$
30 */
31
32/**
33 *      @file
34 *      @brief Handles the dynamics of the wiimote.
35 *
36 *      The file includes functions that handle the dynamics
37 *      of the wiimote.  Such dynamics include orientation and
38 *      motion sensing.
39 */
40
41#include <stdio.h>
42#include <stdlib.h>
43#include <math.h>
44
45
46#include "definitions.h"
47#include "wiic_internal.h"
48#include "ir.h"
49#include "dynamics.h"
50
51/**
52 *      @brief Calculate the roll, pitch, yaw.
53 *
54 *      @param ac                       An accelerometer (accel_t) structure.
55 *      @param accel            [in] Pointer to a vec3b_t structure that holds the raw acceleration data.
56 *      @param orient           [out] Pointer to a orient_t structure that will hold the orientation data.
57 *      @param rorient          [out] Pointer to a orient_t structure that will hold the non-smoothed orientation data.
58 *      @param smooth           If smoothing should be performed on the angles calculated. 1 to enable, 0 to disable.
59 *
60 *      Given the raw acceleration data from the accelerometer struct, calculate
61 *      the orientation of the device and set it in the \a orient parameter.
62 */
63void calculate_orientation(struct vec3f_t* in, struct ang3f_t* out) {
64        float x, y, z;
65
66        /*
67         *      roll    - use atan(z / x)               [ ranges from -180 to 180 ]
68         *      pitch   - use atan(z / y)               [ ranges from -180 to 180 ]
69         *      yaw             - impossible to tell without IR
70         */
71
72        /* yaw - set to 0, IR will take care of it if it's enabled */
73        out->yaw = 0.0f;
74
75        /* find out how much it actually moved and normalize to +/- 1g */
76        x = in->x;
77        y = in->y;
78        z = in->z;
79
80        /* make sure x,y,z are between -1 and 1 for the tan functions */
81        if (x < -1.0f)                  x = -1.0f;
82        else if (x > 1.0f)              x = 1.0f;
83        if (y < -1.0f)                  y = -1.0f;
84        else if (y > 1.0f)              y = 1.0f;
85        if (z < -1.0f)                  z = -1.0f;
86        else if (z > 1.0f)              z = 1.0f;
87
88        /* if it is over 1g then it is probably accelerating and the gravity vector cannot be identified */
89        if (abs(in->x) <= 1.0) {
90                /* roll */
91                x = -RAD_TO_DEGREE(atan2f(x, z));
92
93                out->roll = x;
94        }
95
96        if (abs(in->y) <= 1.0) {
97                /* pitch */
98                y = RAD_TO_DEGREE(atan2f(y, z));
99
100                out->pitch = y;
101        }
102}
103
104
105/**
106 *      @brief Calculate the gravity forces on each axis.
107 *
108 *      @param ac                       An accelerometer (accel_t) structure.
109 *      @param accel            [in] Pointer to a vec3b_t structure that holds the raw acceleration data.
110 *      @param gforce           [out] Pointer to a gforce_t structure that will hold the gravity force data.
111 */
112void calculate_gforce(struct accel_t* ac, struct vec3b_t* accel, struct gforce_t* gforce, int smooth) {
113        float xg, yg, zg;
114
115        /* find out how much it has to move to be 1g */
116        xg = (int)ac->cal_g.x;
117        yg = (int)ac->cal_g.y;
118        zg = (int)ac->cal_g.z;
119
120        /* find out how much it actually moved and normalize to +/- 1g */
121        gforce->a_vec.x = ((int)accel->x - (int)ac->cal_zero.x) / xg;
122        gforce->a_vec.y = ((int)accel->y - (int)ac->cal_zero.y) / yg;
123        gforce->a_vec.z = ((int)accel->z - (int)ac->cal_zero.z) / zg;
124       
125        if(smooth) {
126                apply_smoothing(gforce, ac->st_alpha);
127        }
128        else {
129                gforce->vec.x = gforce->a_vec.x;
130                gforce->vec.y = gforce->a_vec.y;
131                gforce->vec.z = gforce->a_vec.z;               
132        }
133}
134
135
136/**
137 *      @brief Calculate the angle and magnitude of a joystick.
138 *
139 *      @param js       [out] Pointer to a joystick_t structure.
140 *      @param x        The raw x-axis value.
141 *      @param y        The raw y-axis value.
142 */
143void calc_joystick_state(struct joystick_t* js, float x, float y) {
144        float rx, ry, ang;
145
146        /*
147         *      Since the joystick center may not be exactly:
148         *              (min + max) / 2
149         *      Then the range from the min to the center and the center to the max
150         *      may be different.
151         *      Because of this, depending on if the current x or y value is greater
152         *      or less than the assoicated axis center value, it needs to be interpolated
153         *      between the center and the minimum or maxmimum rather than between
154         *      the minimum and maximum.
155         *
156         *      So we have something like this:
157         *              (x min) [-1] ---------*------ [0] (x center) [0] -------- [1] (x max)
158         *      Where the * is the current x value.
159         *      The range is therefore -1 to 1, 0 being the exact center rather than
160         *      the middle of min and max.
161         */
162        if (x == js->center.x)
163                rx = 0;
164        else if (x >= js->center.x)
165                rx = ((float)(x - js->center.x) / (float)(js->max.x - js->center.x));
166        else
167                rx = ((float)(x - js->min.x) / (float)(js->center.x - js->min.x)) - 1.0f;
168
169        if (y == js->center.y)
170                ry = 0;
171        else if (y >= js->center.y)
172                ry = ((float)(y - js->center.y) / (float)(js->max.y - js->center.y));
173        else
174                ry = ((float)(y - js->min.y) / (float)(js->center.y - js->min.y)) - 1.0f;
175
176        /* calculate the joystick angle and magnitude */
177        ang = RAD_TO_DEGREE(atanf(ry / rx));
178        ang -= 90.0f;
179        if (rx < 0.0f)
180                ang -= 180.0f;
181        js->ang = absf(ang);
182        js->mag = (float) sqrt((rx * rx) + (ry * ry));
183}
184
185/**
186 *
187 * @brief Apply a smooth factor to accelerometer angles.
188 *
189 * @param accel         Last acceleration measured and normalized to +/-g.
190 * @param gforce        [out] gravity vector after smoothing
191 */
192void apply_smoothing(struct gforce_t* gforce, float alpha) {
193       
194        gforce->vec.x = alpha*gforce->vec.x + (1.0-alpha)*gforce->a_vec.x;
195        gforce->vec.y = alpha*gforce->vec.y + (1.0-alpha)*gforce->a_vec.y;
196        gforce->vec.z = alpha*gforce->vec.z + (1.0-alpha)*gforce->a_vec.z;
197}
Note: See TracBrowser for help on using the repository browser.