-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathBB_IMU.cpp
204 lines (175 loc) · 5.78 KB
/
BB_IMU.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
/************************************************************************/ /**
*@file
*@brief Contains the POV class functions.
***************************************************************************/
#include "BB_IMU.h"
/** ***************************************************************************
* @par Description:
* Constructor for the bb_imu class. This constructor basically sets the
* the initial arrays to zero and assigns conversions to the relevant
* sensor structors.
*
* @returns none.
*****************************************************************************/
bb_imu::bb_imu()
{
int i;
for (i = 0; i < num_input; ++i)
{
GYRO_vals[i] = 0;
AVG_gyro_vals[i] = 0;
}
gyro_z.conversion = &gyro_to_rad;
}
/** ***************************************************************************
* @par Description:
* Initialises the class by calibrating the sensors and testing if the IMU
* could be initialized.
*
* @returns true if successful and false otherwise.
*****************************************************************************/
bool bb_imu::init()
{
int i = 0;
int j;
//test if the imu has started successfully
if (!IMU.begin())
return false;
//average 100 values from the from the IMU to use for calibration
while (i < 100)
{
if (IMU.gyroscopeAvailable())
{
IMU.readGyroscope(GYRO_vals[0], GYRO_vals[1], GYRO_vals[2]);
for (j = 0; j < num_input; ++j)
{
//sum all measurements
AVG_gyro_vals[j] = AVG_gyro_vals[j] + GYRO_vals[j];
}
++i;
}
}
//divide by the total number of measurements
for (i = 0; i < num_input; ++i)
{
AVG_gyro_vals[i] = AVG_gyro_vals[i] / 100;
}
return true;
}
/** ***************************************************************************
* @par Description:
* Get the raw values for the IMU adjusted by their average error.
*
* @returns true if an update was available and false otherwise.
*****************************************************************************/
bool bb_imu::Get_raw()
{
int i;
//if the gyroscope is ready, take the new values and subtract the
//average static error.
if (IMU.gyroscopeAvailable())
{
IMU.readGyroscope(GYRO_vals[0], GYRO_vals[1], GYRO_vals[2]);
for (i = 0; i < 3; ++i)
{
GYRO_vals[i] = GYRO_vals[i] - AVG_gyro_vals[i];
}
//imu was ready
return true;
}
//imu was not ready
return false;
}
/** ***************************************************************************
* @par Description:
* Performs simpsons 1/3 integration on the last three data points without
* multiplying by delta t. The function doesn't return useful values until
* the first three values are passed in and you must pass in at least three
* new values to completely clear the function.
*
* @param [in] new_val : the newest value to be used in the estimation.
* @param [in/out] data : a structure that contains all relevant data for
* the estimation.
*
* @returns float - the estamie of the integral value not multiplied by
* delta t from the last three values passed in.
*****************************************************************************/
float bb_imu::integrate(integrate_struct &data, float new_val)
{
//based off of simpsons 1/3 to find the approximate integral
//scan through the array to add the new value
if (data.mid > 2)
{
data.mid = 0;
data.vals[2] = new_val;
}
else if (data.mid == 0)
{
data.vals[0] = new_val;
}
else
{
data.vals[1] = new_val;
}
//update the new mid of the array
++data.mid;
//compute simpsons 1/3 for the past three values without multiplying by delta t
return ((data.vals[0] + data.vals[1] + data.vals[2] + 3 * data.vals[data.mid - 1]) / 3);
}
/** ***************************************************************************
* @par Description:
* Update the estimation for the BB orientation.
*
* @returns true of a major change was made based on new values and
* false otherwise.
*****************************************************************************/
bool bb_imu::update()
{
//get new raw values
bool new_vals = Get_raw();
//if there are new raw values then recalculate the speed
if (new_vals)
{
gyro_z.speed = integrate(gyro_z, GYRO_vals[2]);
}
//update time since last update
delta_t = float(micros() - loop_start_time) / 1000000;
//recalculate the integral
gyro_z.integral = gyro_z.integral + gyro_z.speed * delta_t;
//update the last time an update occurred
loop_start_time = micros();
return new_vals;
}
/** ***************************************************************************
* @par Description:
* Convert from the generic integral value to 2pi radians.
*
* @param [in/out] data : a structure that contains all relevant data for
* the estimation.
*
* @returns float of the estimated bb angle.
*****************************************************************************/
float bb_imu::make2pi(integrate_struct &data)
{
//**********integral to rad**********
if (data.integral > *(data.conversion))
{
data.integral -= *(data.conversion);
}
else if ((data.conversion + *(data.conversion)) < 0)
{
data.integral += *(data.conversion);
}
//convert the integral to radians
return (PI * 2) / *(data.conversion) * data.integral;
}
/** ***************************************************************************
* @par Description:
* Return a float of the estimated bb angle.
*
* @returns float of the estimated bb angle.
*****************************************************************************/
float bb_imu::Get_val()
{
return make2pi(gyro_z);
}