Skip to content

Commit 3367de6

Browse files
committed
Add the logic for selecting what sensors to use.
1 parent 0dcd8a4 commit 3367de6

File tree

8 files changed

+301
-74
lines changed

8 files changed

+301
-74
lines changed

imu.h

+7-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@
55
class imu
66
{
77
public:
8+
virtual void read_acc_raw() = 0;
9+
virtual void read_mag_raw() = 0;
10+
virtual void read_gyro_raw() = 0;
11+
812
// Scaled readings
913
virtual vector read_mag() = 0; // In body coords, scaled to -1..1 range
1014
virtual vector read_acc() = 0; // In body coords, with units = g
@@ -18,5 +22,7 @@ class imu
1822
vector gyro_offset;
1923
int_vector mag_min, mag_max;
2024

21-
int_vector raw_m, raw_a, raw_g;
25+
int32_t m[3];
26+
int32_t a[3];
27+
int32_t g[3];
2228
};

l3g.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ namespace l3g
6565
void open(const comm_config &);
6666

6767
// gyro angular velocity readings
68-
int g[3]; // TODO: use int16_t, right?
68+
int32_t g[3];
6969

7070
void enable();
7171

lsm303.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -177,8 +177,8 @@ namespace lsm303
177177
public:
178178
void open(const comm_config &);
179179

180-
int a[3]; // accelerometer readings
181-
int m[3]; // magnetometer readings
180+
int32_t a[3]; // accelerometer readings
181+
int32_t m[3]; // magnetometer readings
182182

183183
void enable();
184184

minimu9-ahrs.cpp

+29-4
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,9 @@ void stream_raw_values(imu & imu)
7676
{
7777
imu.read();
7878
printf("%7d %7d %7d %7d %7d %7d %7d %7d %7d\n",
79-
imu.raw_m[0], imu.raw_m[1], imu.raw_m[2],
80-
imu.raw_a[0], imu.raw_a[1], imu.raw_a[2],
81-
imu.raw_g[0], imu.raw_g[1], imu.raw_g[2]
79+
imu.m[0], imu.m[1], imu.m[2],
80+
imu.a[0], imu.a[1], imu.a[2],
81+
imu.g[0], imu.g[1], imu.g[2]
8282
);
8383
usleep(20*1000);
8484
}
@@ -234,7 +234,32 @@ int main_with_exceptions(int argc, char **argv)
234234
return 0;
235235
}
236236

237-
auto config = minimu9::auto_detect(i2c_bus_name);
237+
// Decide what sensors we want to use.
238+
sensor_set set;
239+
set.mag = set.acc = set.gyro = true;
240+
241+
minimu9::comm_config config = minimu9::auto_detect(i2c_bus_name);
242+
243+
sensor_set missing = set - minimu9::config_sensor_set(config);
244+
if (missing)
245+
{
246+
if (missing.mag)
247+
{
248+
std::cerr << "Error: No magnetometer found." << std::endl;
249+
}
250+
if (missing.acc)
251+
{
252+
std::cerr << "Error: No accelerometer found." << std::endl;
253+
}
254+
if (missing.gyro)
255+
{
256+
std::cerr << "Error: No gyro found." << std::endl;
257+
}
258+
std::cerr << "Error: Needed sensors are missing." << std::endl;
259+
return 1;
260+
}
261+
262+
config = minimu9::disable_redundant_sensors(config, set);
238263

239264
minimu9::handle imu;
240265
imu.open(config);

minimu9.cpp

+217-55
Original file line numberDiff line numberDiff line change
@@ -144,89 +144,251 @@ minimu9::comm_config minimu9::auto_detect(const std::string & i2c_bus_name)
144144
return config;
145145
}
146146

147-
void minimu9::handle::open(const minimu9::comm_config & config)
147+
sensor_set minimu9::config_sensor_set(const comm_config & config)
148148
{
149-
// TODO: need to do some cool stuff here
149+
sensor_set set;
150+
150151
if (config.lsm6.use_sensor)
151152
{
152-
153+
set.acc = true;
154+
set.gyro = true;
155+
}
156+
157+
if (config.lis3mdl.use_sensor)
158+
{
159+
set.mag = true;
160+
}
161+
162+
if (config.lsm303.use_sensor)
163+
{
164+
set.mag = true;
165+
set.acc = true;
166+
}
167+
168+
if (config.l3g.use_sensor)
169+
{
170+
set.gyro = true;
171+
}
172+
173+
return set;
174+
}
175+
176+
minimu9::comm_config minimu9::disable_redundant_sensors(
177+
const comm_config & in, const sensor_set & needed)
178+
{
179+
comm_config config = in;
180+
181+
sensor_set missing = needed;
182+
183+
if (!(missing.acc || missing.gyro))
184+
{
185+
config.lsm6.use_sensor = false;
186+
}
187+
else if (config.lsm6.use_sensor)
188+
{
189+
missing.acc = false;
190+
missing.gyro = false;
191+
}
192+
193+
if (!missing.mag)
194+
{
195+
config.lis3mdl.use_sensor = false;
196+
}
197+
else if (config.lis3mdl.use_sensor)
198+
{
199+
missing.mag = false;
200+
}
201+
202+
if (!(missing.mag || missing.acc))
203+
{
204+
config.lsm303.use_sensor = false;
205+
}
206+
else if (config.lsm303.use_sensor)
207+
{
208+
missing.mag = false;
209+
missing.acc = false;
210+
}
211+
212+
if (!missing.gyro)
213+
{
214+
config.l3g.use_sensor = false;
215+
}
216+
else if (config.l3g.use_sensor)
217+
{
218+
missing.gyro = false;
219+
}
220+
221+
return config;
222+
}
223+
224+
void minimu9::handle::open(const comm_config & config)
225+
{
226+
this->config = config;
227+
228+
if (config.lsm6.use_sensor)
229+
{
230+
lsm6.open(config.lsm6);
231+
}
232+
233+
if (config.lis3mdl.use_sensor)
234+
{
235+
lis3mdl.open(config.lis3mdl);
236+
}
237+
238+
if (config.lsm303.use_sensor)
239+
{
240+
lsm303.open(config.lsm303);
241+
}
242+
243+
if (config.l3g.use_sensor)
244+
{
245+
l3g.open(config.l3g);
153246
}
154247
}
155248

156249
void minimu9::handle::enable()
157250
{
158-
compass.enable();
159-
gyro.enable();
251+
if (config.lsm6.use_sensor)
252+
{
253+
lsm6.enable();
254+
}
255+
256+
if (config.lis3mdl.use_sensor)
257+
{
258+
lis3mdl.enable();
259+
}
260+
261+
if (config.lsm303.use_sensor)
262+
{
263+
lsm303.enable();
264+
}
265+
266+
if (config.l3g.use_sensor)
267+
{
268+
l3g.enable();
269+
}
160270
}
161271

162272
void minimu9::handle::load_calibration()
163273
{
164-
wordexp_t expansion_result;
165-
wordexp("~/.minimu9-ahrs-cal", &expansion_result, 0);
274+
wordexp_t expansion_result;
275+
wordexp("~/.minimu9-ahrs-cal", &expansion_result, 0);
166276

167-
std::ifstream file(expansion_result.we_wordv[0]);
168-
if (file.fail())
169-
{
170-
throw posix_error("Failed to open calibration file ~/.minimu9-ahrs-cal");
171-
}
277+
std::ifstream file(expansion_result.we_wordv[0]);
278+
if (file.fail())
279+
{
280+
throw posix_error("Failed to open calibration file ~/.minimu9-ahrs-cal");
281+
}
172282

173-
file >> mag_min(0) >> mag_max(0) >> mag_min(1) >> mag_max(1) >> mag_min(2) >> mag_max(2);
174-
if (file.fail() || file.bad())
175-
{
176-
throw std::runtime_error("Failed to parse calibration file ~/.minimu9-ahrs-cal");
177-
}
283+
file >> mag_min(0) >> mag_max(0)
284+
>> mag_min(1) >> mag_max(1)
285+
>> mag_min(2) >> mag_max(2);
286+
if (file.fail() || file.bad())
287+
{
288+
throw std::runtime_error("Failed to parse calibration file ~/.minimu9-ahrs-cal");
289+
}
290+
}
291+
292+
void minimu9::handle::read_mag_raw()
293+
{
294+
if (config.lis3mdl.use_sensor)
295+
{
296+
lis3mdl.read();
297+
for (int i = 0; i < 3; i++) { m[i] = lis3mdl.m[i]; }
298+
}
299+
else if (config.lsm303.use_sensor)
300+
{
301+
lsm303.read_mag();
302+
for (int i = 0; i < 3; i++) { m[i] = lsm303.m[i]; }
303+
}
304+
else
305+
{
306+
throw std::runtime_error("No magnetometer to read.");
307+
}
308+
}
309+
310+
void minimu9::handle::read_acc_raw()
311+
{
312+
if (config.lsm6.use_sensor)
313+
{
314+
lsm6.read_acc();
315+
for (int i = 0; i < 3; i++) { a[i] = lsm6.a[i]; }
316+
}
317+
else if (config.lsm303.use_sensor)
318+
{
319+
lsm303.read_acc();
320+
for (int i = 0; i < 3; i++) { a[i] = lsm303.a[i]; }
321+
}
322+
else
323+
{
324+
throw std::runtime_error("No accelerometer to read.");
325+
}
326+
}
327+
328+
void minimu9::handle::read_gyro_raw()
329+
{
330+
if (config.lsm6.use_sensor)
331+
{
332+
lsm6.read_gyro();
333+
for (int i = 0; i < 3; i++) { g[i] = lsm6.g[i]; }
334+
}
335+
else if (config.l3g.use_sensor)
336+
{
337+
l3g.read();
338+
for (int i = 0; i < 3; i++) { g[i] = l3g.g[i]; }
339+
}
340+
else
341+
{
342+
throw std::runtime_error("No gyro to read.");
343+
}
178344
}
179345

180346
void minimu9::handle::measure_offsets()
181347
{
182-
// LSM303 accelerometer: 8 g sensitivity. 3.8 mg/digit; 1 g = 256.
183-
// TODO: unify this with the other place in the code where we scale accelerometer readings.
184-
gyro_offset = vector::Zero();
185-
const int sampleCount = 32;
186-
for(int i = 0; i < sampleCount; i++)
187-
{
188-
gyro.read();
189-
gyro_offset += vector_from_ints(&gyro.g);
190-
usleep(20*1000);
191-
}
192-
gyro_offset /= sampleCount;
348+
// LSM303 accelerometer: 8 g sensitivity. 3.8 mg/digit; 1 g = 256.
349+
gyro_offset = vector::Zero();
350+
const int sampleCount = 32;
351+
for(int i = 0; i < sampleCount; i++)
352+
{
353+
read_gyro_raw();
354+
gyro_offset += vector_from_ints(&g);
355+
usleep(20*1000);
356+
}
357+
gyro_offset /= sampleCount;
193358
}
194359

195360
vector minimu9::handle::read_mag()
196361
{
197-
compass.read_mag();
198-
raw_m = int_vector_from_ints(&compass.m);
199-
200-
vector v;
201-
v(0) = (float)(compass.m[0] - mag_min(0)) / (mag_max(0) - mag_min(0)) * 2 - 1;
202-
v(1) = (float)(compass.m[1] - mag_min(1)) / (mag_max(1) - mag_min(1)) * 2 - 1;
203-
v(2) = (float)(compass.m[2] - mag_min(2)) / (mag_max(2) - mag_min(2)) * 2 - 1;
204-
return v;
362+
read_mag_raw();
363+
364+
vector v;
365+
v(0) = (float)(m[0] - mag_min(0)) / (mag_max(0) - mag_min(0)) * 2 - 1;
366+
v(1) = (float)(m[1] - mag_min(1)) / (mag_max(1) - mag_min(1)) * 2 - 1;
367+
v(2) = (float)(m[2] - mag_min(2)) / (mag_max(2) - mag_min(2)) * 2 - 1;
368+
return v;
205369
}
206370

207371
vector minimu9::handle::read_acc()
208372
{
209-
// Info about linear acceleration sensitivity from datasheets:
210-
// LSM303DLM: at FS = 8 g, 3.9 mg/digit (12-bit reading)
211-
// LSM303DLHC: at FS = 8 g, 4 mg/digit (12-bit reading probably an approximation)
212-
// LSM303DLH: at FS = 8 g, 3.9 mg/digit (12-bit reading)
213-
// LSM303D: at FS = 8 g, 0.244 mg/LSB (16-bit reading)
214-
const float accel_scale = 0.000244;
215-
216-
compass.read_acc();
217-
imu::raw_a = int_vector_from_ints(&compass.a);
218-
return vector_from_ints(&compass.a) * accel_scale;
373+
// Info about linear acceleration sensitivity from datasheets:
374+
// LSM303DLM: at FS = 8 g, 3.9 mg/digit (12-bit reading)
375+
// LSM303DLHC: at FS = 8 g, 4 mg/digit (12-bit reading probably an approximation)
376+
// LSM303DLH: at FS = 8 g, 3.9 mg/digit (12-bit reading)
377+
// LSM303D: at FS = 8 g, 0.244 mg/LSB (16-bit reading)
378+
const float accel_scale = 0.000244;
379+
380+
read_acc_raw();
381+
return vector_from_ints(&a) * accel_scale;
219382
}
220383

221384
vector minimu9::handle::read_gyro()
222385
{
223-
// Info about sensitivity from datasheets:
224-
// L3G4200D: at FS = 2000 dps, 70 mdps/digit
225-
// L3GD20: at FS = 2000 dps, 70 mdps/digit
226-
// L3GD20H: at FS = 2000 dps, 70 mdps/digit
227-
const float gyro_scale = 0.07 * 3.14159265 / 180;
228-
229-
gyro.read();
230-
raw_g = int_vector_from_ints(&gyro.g);
231-
return ( vector_from_ints(&gyro.g) - gyro_offset ) * gyro_scale;
386+
// Info about sensitivity from datasheets:
387+
// L3G4200D: at FS = 2000 dps, 70 mdps/digit
388+
// L3GD20: at FS = 2000 dps, 70 mdps/digit
389+
// L3GD20H: at FS = 2000 dps, 70 mdps/digit
390+
const float gyro_scale = 0.07 * 3.14159265 / 180;
391+
392+
read_gyro_raw();
393+
return (vector_from_ints(&g) - gyro_offset) * gyro_scale;
232394
}

0 commit comments

Comments
 (0)