Code Monkey home page Code Monkey logo

minimu9-ahrs's Introduction

minimu9-ahrs

minimu9-ahrs is a program for reading sensor data from the Pololu MinIMU-9 and similar boards over I²C. It supports the following sensor chips:

  • LSM6DS33 accelerometer and gyro
  • LSM6DSO accelerometer and gyro
  • LIS3MDL magnetometer
  • LSM303D magnetometer and accelerometer
  • LSM303DLHC magnetometer and accelerometer
  • LSM303DLM magnetometer and accelerometer
  • LSM303DLH magnetometer and accelerometer
  • L3GD20H gyro
  • L3GD20 gyro
  • L3G4200D gyro

This program works with any board that has a magnetometer, acceleromter, and a gyro from the list above. This includes the following Pololu products:

The program can output the raw sensor data from the magnetometor, accelerometer, and gyro or it can use that raw data to compute the orientation of the IMU. This program was designed and tested on the Raspberry Pi, but it will probably work on any embedded Linux board that supports I²C.

Getting started

Enabling I²C

First, you need to make sure your system supports I²C. Try typing ls /dev/i2c*: if you don't see a device there named something like /dev/i2c-1 then your I²C is not enabled properly.

On a Raspberry Pi running Raspbian, you should run sudo raspi-config and browse its menus to find the option to enable I²C.

Here are some other related resources that might be useful for you when figuring out how to enable I²C:

Managing device permissions

After enabling the I²C devices, you should set them up so that your user has permission to access them. That way, you won't have to run sudo.

First, run groups to see what groups your user belongs to. If i2c is on the list, then that is good. If you are not on the i2c group, then you should add yourself to it by running sudo usermod -a -G i2c $(whoami), logging out, and then logging in again. If your system does not have an i2c group, you can create one or use a different group like plugdev.

Next, run ls -l /dev/i2c* to make sure that your I²C devices have their group set to i2c. The group name is shown in the fourth column, and will usually be root or i2c. If the devices are not in the i2c group, then you should fix that by making a file called /etc/udev.d/rules.d/i2c.rules with the following line in it:

SUBSYSTEM=="i2c-dev" GROUP="i2c"

After making this file, you can make it take effect by running sudo udevadm trigger (or rebooting).

If you get an error about permission being denied, double check that you have done these steps correctly.

Soldering

The MinIMU-9 and AltIMU-9 boards come with male header pins, and you will need to solder these into the board in order to make a solid connection.

Wiring

You will need to power your IMU board and connect it to the I²C bus of your embedded computer board. The correct connections for the Raspberry Pi and a MinIMU-9 are listed below:

Raspberry Pi pin MinIMU-9 pin
GND GND
3V3 Power VDD
GPIO 2 (SDA) SDA
GPIO 3 (SCL) SCL

Below is a picture with a MinIMU-9 v2 showing how to make those connections.

You will need four female-female jumper wires designed for 0.1"-spaced pins. Pololu's Female-Female Premium Jumper Wires work well.

Determining which bus to use

The default I²C bus used by this program is /dev/i2c-1. On most Raspberry Pi boards, this bus is accessible on the GPIO connector.

If you want to use a different bus, you should make a configuration file in your home directory named ~/.minimu9-ahrs with a single line of the form i2c-bus=BUSNAME, where BUSNAME is the full path to the bus you want to use.

For example, to use /dev/i2c-0 by default, the config file should read:

i2c-bus=/dev/i2c-0

If you are not sure which bus to use, you could try running i2cdetect on each available bus as described below.

Checking your setup

After you have enabled I²C, given yourself the proper permissions, soldered the MinIMU-9, and connected it to the Raspberry Pi, you should check your setup by running i2cdetect. Try running i2cdetect -y N, where N is the number of the I²C bus you want to use (typically 1 or 0). The output should look similar to this:

$ i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- 1d -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- 6b -- -- -- --
70: -- -- -- -- -- -- -- --

The exact output will depend on the type of IMU you are using, but the important thing is that the body of the printed table should contain a few hex numbers representing the addresses of I²C devices that were detected on the bus.

If the i2cdetect command is not recognized, you should install the i2c-tools package. On Raspbian, you can run sudo apt-get install i2c-tools to install it.

If you do not see a few hex numbers in the body of the table, then make sure your soldering and wiring are correct and try selecting a different bus by changing the bus number argument N.

If you get a permission denied error, make sure you have configured the device permissions properly as described above.

If you get a "No such file or directory" error referring to your I²C device, make sure that you have properly enabled I²C as described above.

Building from source

To build minimu9-ahrs, you first need to install some libraries that it depends on. On Raspbian, you can install these dependencies by running:

sudo apt-get install libi2c-dev libeigen3-dev libboost-program-options-dev

Then, to build minimu9-ahrs, navigate to the top-level directory of the source code and then run this command:

make

Finally, to install minimu9-ahrs onto your system, run:

sudo make install

Looking at raw values

As a first test, you should look at the raw readings from the sensors on your IMU to make sure it is OK. Run minimu9-ahrs --mode raw. The output should look something like this:

  -1318   -3106   -1801     1896    1219    3679        5      18       3
  -1318   -3106   -1801     1898    1200    3681        0      24      -1
  -1318   -3106   -1801     1899    1200    3688       15      17       2
  -1309   -3105   -1799     1874    1201    3671       17      20      -1
  -1309   -3105   -1799     1898    1214    3663       11      15      -2

Yes, there will be noise in all the readings, even if your IMU is not moving at all. That is totally normal.

This output consists of three vectors. From left to right they are the raw magnetometer reading, the raw accelerometer reading, and the raw gyro reading. Each vector consists of three integers, in X-Y-Z order. You should turn the device and make sure that the raw readings change correspondingly. For example, when the X axis of the board is pointing straight up, the accelerometer's X reading (the 4th number on each line) should be positive and the other two components of the acceleration should be close to zero.

Calibrating

The magnetometer will need to be calibrated to create a mapping from the ellipsoid shape of the raw readings to the unit sphere shape that we want the scaled readings to have. The calibration feature for the minimu9-ahrs assumes that the shape of the raw readings will be an ellipsoid that is offset from the origin and stretched along the X, Y, and Z axes. It cannot handle a rotated ellipsoid. It can be informative to run minimu9-ahrs --mode raw > output.tsv while moving the magnetometer and then make some scatter plots of the raw magnetometer readings in a spreadsheet program to see what shape the readings have.

To calibrate the magnetometer, run minimu9-ahrs-calibrate and follow the on-screen instructions when they tell you to start rotating the IMU through as many different orientations as possible. Once the script has collected enough data, it saves the data to ~/.minimu9-ahrs-cal-data and then runs a separate Python script (minimu9-ahrs-calibrator) to create a calibration.

The Python script previously had a complicated algorithm powered by SciPy that would take about 20 minutes to run and was not reliable. Currently, the script just uses a very simple algorithm that finds the minimum and maximum values of each axis of the magnetometer and uses those as the calibration values. This is probably not the best way to calibrate your magnetometer; there are more advanced ways that might work better.

The minimu9-ahrs-calibrate script saves the calibration file to ~/.minimu9-ahrs-cal. The calibration file is simply a one-line file with 6 numbers separated by spaces: minimum x, maximum x, minimum y, maximum y, minimum z, maximum z. These numbers specify the linear mapping from the raw ellipsoid to the unit sphere. For example, if "minimum x" is -414, it means that a magnetometer reading of -414 on the X axis will get mapped to -1.0 when the readings are scaled.

Looking at Euler angles

Run minimu9-ahrs --output euler. It will print a stream of floating-point numbers, nine per line. The first three numbers are the yaw, pitch, and roll angles of the board in degrees. All three Euler angles should be close zero when the board is oriented with the Z axis facing down and the X axis facing towards magnetic north. From that starting point:

  • A positive yaw corresponds to a rotation about the Z axis that is clockwise when viewed from above.
  • A positive pitch correspond to a rotation about the Y axis that would cause the X axis to aim higher into the sky.
  • A positive roll would correspond to a counter-clockwise rotation about the X axis.

The way you should think about it is that board starts in the neutral position, then the yaw rotation is applied, then the pitch rotation is applied, and then the roll rotation is applied to get the board to its final position.

Look at the Euler angle output as you turn the board and make sure that it looks good.

Man page

For more information about minimu9-ahrs, including all the options it supports and a precise description of its output format, view the man page by running man minimu9-ahrs.

Related projects

  • ahrs-visualizer - another program by me that provides a 3D display of the orientation output from minimu9-ahrs.
  • Pololu MinIMU-9 Step-by-Step - an alternative tutorial by Mike Kim that explains how to use minimu9-ahrs and ahrs-visualizer.
  • RTIMULib2 - another project that works with the MinIMU-9 and the Raspberry Pi.

Version history

  • 4.0.0 (2023-07-11):
    • Added support for the MinIMU-9 v6 (LSM6DSO and LIS3MDL).
    • Changed the default I²C bus to /dev/i2c-1 to better serve Raspberry Pi users.
    • Updated the minimu9-ahrs-calibrator script to use Python 3.
  • 3.0.0 (2017-04-15):
    • Added support for the MinIMU-9 v5 (LSM6DS33 and LIS3MDL).
    • Added support for a configuration file at ~/.minimu9-ahrs.
    • Fixed a bug that resulted in corrections from the accelerometer always being applied even if the acceleration magnitude was not close to 1 g (thanks nxdefiant).
    • Use a Linux timerfd for more accurate timing (thanks to nxdefiant for the idea).
    • Made the minimu9-ahrs-calibrate script store the raw data in ~/.minimu9-ahrs-cal-data.
    • Changed the minimu9-ahrs-calibrator Python script to just do simple minima/maxima because the fancy optimization algorithm was not reliable.
    • Fixed the way boost_program_options is linked.
    • Expanded the README so it can replace the wiki.
  • 2.0.0 (2014-07-08):
    • Added support for the MinIMU-9 v3 (LSM303D and L3GD20H)
    • Removed the right-shifting of raw accelerometer outputs; the raw readings are now signed 16-bit numbers that can range from -32768 to 32767. Previously the readings were signed 12-bit numbers, so this new version effectively gives readings that are greater by a factor of 16.
    • Changed the minimu9-ahrs-calibrator Python script to use SciPy instead of the old optimization algorithm.
    • Changed the minimu9-ahrs-calibrator script to print a warning if there are fewer than 300 input vectors instead of exiting.
    • Changed the minimu9-ahrs-calibrator script to print a warning if the calibration looks wrong.
  • 1.1.1 (2012-10-17)
  • 1.1.0 (2012-10-15)
  • 1.0.0 (2012-10-06)

minimu9-ahrs's People

Contributors

davidegrayson avatar kc13 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

minimu9-ahrs's Issues

error while building minimu9-ahrs

Hi,
I am trying to install minimu9-ahrs on my raspberry pi3 but I find some error with "eigen" :

Package eigen3 was not found in the pkg-config search path. Perhaps you should add the directory containing eigen3.pc'
to the PKG_CONFIG_PATH environment variable
No package 'eigen3' found
g++ -I. -Wall --std=gnu++11 -O2 -MD -MP vector.h -o vector.h.gch
vector.h:5:10: fatal error: Eigen/Core: Aucun fichier ou dossier de ce type
#include <Eigen/Core>
^~~~~~~~~~~~
compilation terminated.
make: *** [Makefile:37: vector.h.gch] Error 1`

could you please help me resolving this problem ? thanks

minimu9-ahrs-calibrator appears to get stuck in "tune" function

Thanks for this awesome project! This is a great demo and I really appreciate your tutorial.

I just wanted to let you know that for some reason when I run minimu9-ahrs-calibrate after the message "Optimizing calibration" the program appears to get stuck for me. It appears that the cause is that the "while True" condition in "tune" of "minimu9-ahrs-calibrator" is never satisfied.

In a future rev it might be a nice idea to terminate this loop after a certain amount of time or if the calibration results are within a certain (adjustable) tolerance. Also some in line comments would be a great bonus for easier debugging.

AHRS does not compensate for centripetal force

So today I took my minimu9-ahrs-based system up for a test flight and discovered that what looks good sitting at your desk doesn't always work as you expect in the real world. It seems that we need to include some additional processing to compensate for inertial factors like centripetal force. When I turned the plane the IMU initially registered the turn but quickly "leveled out" as the turn was sustained. The accelerometer sensed "down" as being perpendicular to the wings rather than gravity.

A bit of googling indicates that this kind of compensation is required for IMU / AHRS systems in fixed-wing aircraft. Apparently the magnetometer can help by indicating the rate of turn. A GPS can provide groundspeed and change in velocity values that can further assist in the correction. There appears to be several methods for doing this. There's an outline available here: http://wiki.paparazziuav.org/wiki/Subsystem/ahrs

I'm not mathematically literate enough to make my way through the complementary quaternion algorithms. Anyone feel up to the challenge? I'm more than happy to be the test pilot.

minimu9-ahrs --mode raw

Hello, I have followed the steps of the tutorial but just when I run "minimu9-ahrs --mode raw" this output "segmentation fault (core dumped)". How do I solve this?
Also when executing "minimu9-ahrs-calibrate -b / dev / i2c-1" this other problem comes out "To calibrate the magnetometer, start rotating the IMU through
As many different orientations as possible.
Reading data ... Segmentation fault (core dumped)
 Done
Warning: Only 0 readings were provided.
Optimizing calibration ... Traceback (most recent call last):
  File "/ usr / bin / minimu9-ahrs-calibrator", line 147, in
    Run ()
  File "/ usr / bin / minimu9-ahrs-calibrator", line 95, in run
    Cal1 = guess (raw_readings)
  File "/ usr / bin / minimu9-ahrs-calibrator", line 127, in guess
    Guess.extend (percentile_to_value (values, 1, 99))
  File "/ usr / bin / minimu9-ahrs-calibrator", line 18, in percentile_to_value
    Return [list [int (p / 100.0 * (len (list) -1))] for p in percentiles]
IndexError: list index out of range "

I am using:
MinIMU-9 v3 and Raspberry Pi 3.

Thanks in advance.

Unable to compile on Ubuntu

I attempted to compile on ubuntu after install the necessary libraries as specified, but it results in a linking error:

ubuntu@arm:~/minimu9-ahrs$ make
g++  -I. -Wall --std=c++0x -O3 -Wno-psabi -MD -MP vector.h -o vector.h.gch
In file included from ./Eigen/Core:248:0,
                 from vector.h:4:
./Eigen/src/Core/util/Memory.h: In function ‘Index Eigen::internal::first_aligned(const Scalar*, Index)’:
./Eigen/src/Core/util/Memory.h:449:48: warning: typedef ‘Packet’ locally defined but not used [-Wunused-local-typedefs]
   typedef typename packet_traits<Scalar>::type Packet;
                                                ^
In file included from ./Eigen/Core:324:0,
                 from vector.h:4:
./Eigen/src/Core/products/SelfadjointMatrixVector.h: In static member function ‘static void Eigen::internal::selfadjoint_matrix_vector_product<Scalar, Index, StorageOrder, UpLo, ConjugateLhs, ConjugateRhs, Version>::run(Index, const Scalar*, Index, const Scalar*, Index, Scalar*, Scalar)’:
./Eigen/src/Core/products/SelfadjointMatrixVector.h:38:44: warning: typedef ‘RealScalar’ locally defined but not used [-Wunused-local-typedefs]
   typedef typename NumTraits<Scalar>::Real RealScalar;
                                            ^
In file included from ./Eigen/QR:26:0,
                 from ./Eigen/SVD:4,
                 from ./Eigen/Geometry:8,
                 from vector.h:5:
./Eigen/src/QR/HouseholderQR.h: In function ‘void Eigen::internal::householder_qr_inplace_blocked(MatrixQR&, HCoeffs&, typename MatrixQR::Index, typename MatrixQR::Scalar*)’:
./Eigen/src/QR/HouseholderQR.h:235:41: warning: typedef ‘RealScalar’ locally defined but not used [-Wunused-local-typedefs]
   typedef typename MatrixQR::RealScalar RealScalar;
                                         ^
g++  -I. -Wall --std=c++0x -O3 -Wno-psabi -MD -MP  -c -o minimu9-ahrs.o minimu9-ahrs.cpp
g++  -I. -Wall --std=c++0x -O3 -Wno-psabi -MD -MP  -c -o I2CBus.o I2CBus.cpp
g++  -I. -Wall --std=c++0x -O3 -Wno-psabi -MD -MP  -c -o L3G.o L3G.cpp
g++  -I. -Wall --std=c++0x -O3 -Wno-psabi -MD -MP  -c -o LSM303.o LSM303.cpp
g++  -I. -Wall --std=c++0x -O3 -Wno-psabi -MD -MP  -c -o MinIMU9.o MinIMU9.cpp
g++ -lboost_program_options  minimu9-ahrs.o I2CBus.o L3G.o LSM303.o MinIMU9.o   -o minimu9-ahrs
minimu9-ahrs.o: In function `boost::program_options::typed_value<std::string, char>::xparse(boost::any&, std::vector<std::string, std::allocator<std::string> > const&) const':
minimu9-ahrs.cpp:(.text._ZNK5boost15program_options11typed_valueISscE6xparseERNS_3anyERKSt6vectorISsSaISsEE[_ZNK5boost15program_options11typed_valueISscE6xparseERNS_3anyERKSt6vectorISsSaISsEE]+0x1a): undefined reference to `boost::program_options::validate(boost::any&, std::vector<std::string, std::allocator<std::string> > const&, std::string*, int)'
minimu9-ahrs.o: In function `boost::program_options::typed_value<std::string, char>::name() const':
minimu9-ahrs.cpp:(.text._ZNK5boost15program_options11typed_valueISscE4nameEv[_ZNK5boost15program_options11typed_valueISscE4nameEv]+0xf6): undefined reference to `boost::program_options::arg'
minimu9-ahrs.cpp:(.text._ZNK5boost15program_options11typed_valueISscE4nameEv[_ZNK5boost15program_options11typed_valueISscE4nameEv]+0xfa): undefined reference to `boost::program_options::arg'
minimu9-ahrs.cpp:(.text._ZNK5boost15program_options11typed_valueISscE4nameEv[_ZNK5boost15program_options11typed_valueISscE4nameEv]+0x18e): undefined reference to `boost::program_options::arg'
minimu9-ahrs.cpp:(.text._ZNK5boost15program_options11typed_valueISscE4nameEv[_ZNK5boost15program_options11typed_valueISscE4nameEv]+0x194): undefined reference to `boost::program_options::arg'
minimu9-ahrs.o: In function `boost::program_options::basic_command_line_parser<char>::basic_command_line_parser(int, char const* const*)':
minimu9-ahrs.cpp:(.text._ZN5boost15program_options25basic_command_line_parserIcEC2EiPKPKc[_ZN5boost15program_options25basic_command_line_parserIcEC5EiPKPKc]+0x12c): undefined reference to `boost::program_options::to_internal(std::string const&)'
minimu9-ahrs.cpp:(.text._ZN5boost15program_options25basic_command_line_parserIcEC2EiPKPKc[_ZN5boost15program_options25basic_command_line_parserIcEC5EiPKPKc]+0x150): undefined reference to `boost::program_options::detail::cmdline::cmdline(std::vector<std::string, std::allocator<std::string> > const&)'
minimu9-ahrs.cpp:(.text._ZN5boost15program_options25basic_command_line_parserIcEC2EiPKPKc[_ZN5boost15program_options25basic_command_line_parserIcEC5EiPKPKc]+0x304): undefined reference to `boost::program_options::to_internal(std::string const&)'
minimu9-ahrs.o: In function `boost::program_options::basic_command_line_parser<char>::run()':
minimu9-ahrs.cpp:(.text._ZN5boost15program_options25basic_command_line_parserIcE3runEv[_ZN5boost15program_options25basic_command_line_parserIcE3runEv]+0x16): undefined reference to `boost::program_options::detail::cmdline::run()'
minimu9-ahrs.o: In function `boost::program_options::variables_map::~variables_map()':
minimu9-ahrs.cpp:(.text._ZN5boost15program_options13variables_mapD2Ev[_ZN5boost15program_options13variables_mapD5Ev]+0x2c): undefined reference to `vtable for boost::program_options::variables_map'
minimu9-ahrs.o: In function `main':
minimu9-ahrs.cpp:(.text.startup+0x22): undefined reference to `boost::program_options::options_description::m_default_line_length'
minimu9-ahrs.cpp:(.text.startup+0x26): undefined reference to `boost::program_options::options_description::m_default_line_length'
minimu9-ahrs.cpp:(.text.startup+0x34): undefined reference to `boost::program_options::options_description::options_description(std::string const&, unsigned int, unsigned int)'
minimu9-ahrs.cpp:(.text.startup+0x46): undefined reference to `boost::program_options::options_description::add_options()'
minimu9-ahrs.cpp:(.text.startup+0x5e): undefined reference to `boost::program_options::options_description_easy_init::operator()(char const*, char const*)'
minimu9-ahrs.cpp:(.text.startup+0x72): undefined reference to `boost::program_options::options_description_easy_init::operator()(char const*, char const*)'
minimu9-ahrs.cpp:(.text.startup+0xac): undefined reference to `boost::program_options::options_description_easy_init::operator()(char const*, boost::program_options::value_semantic const*, char const*)'
minimu9-ahrs.cpp:(.text.startup+0xe6): undefined reference to `boost::program_options::options_description_easy_init::operator()(char const*, boost::program_options::value_semantic const*, char const*)'
minimu9-ahrs.cpp:(.text.startup+0x120): undefined reference to `boost::program_options::options_description_easy_init::operator()(char const*, boost::program_options::value_semantic const*, char const*)'
minimu9-ahrs.cpp:(.text.startup+0x144): undefined reference to `boost::program_options::variables_map::variables_map()'
minimu9-ahrs.cpp:(.text.startup+0x156): undefined reference to `boost::program_options::detail::cmdline::set_options_description(boost::program_options::options_description const&)'
minimu9-ahrs.cpp:(.text.startup+0x16a): undefined reference to `boost::program_options::store(boost::program_options::basic_parsed_options<char> const&, boost::program_options::variables_map&, bool)'
minimu9-ahrs.cpp:(.text.startup+0x17c): undefined reference to `boost::program_options::notify(boost::program_options::variables_map&)'
minimu9-ahrs.cpp:(.text.startup+0x1b2): undefined reference to `boost::program_options::operator<<(std::ostream&, boost::program_options::options_description const&)'
minimu9-ahrs.cpp:(.text.startup+0x552): undefined reference to `boost::program_options::multiple_occurrences::get_option_name() const'
minimu9-ahrs.o: In function `boost::program_options::variables_map::~variables_map()':
minimu9-ahrs.cpp:(.text._ZN5boost15program_options13variables_mapD0Ev[_ZN5boost15program_options13variables_mapD0Ev]+0x34): undefined reference to `vtable for boost::program_options::variables_map'
minimu9-ahrs.o:(.rodata._ZTIN5boost15program_options11typed_valueISscEE[_ZTIN5boost15program_options11typed_valueISscEE]+0x10): undefined reference to `typeinfo for boost::program_options::value_semantic_codecvt_helper<char>'
minimu9-ahrs.o:(.rodata._ZTVN5boost15program_options11typed_valueISscEE[_ZTVN5boost15program_options11typed_valueISscEE]+0x1c): undefined reference to `boost::program_options::value_semantic_codecvt_helper<char>::parse(boost::any&, std::vector<std::string, std::allocator<std::string> > const&, bool) const'
collect2: error: ld returned 1 exit status
make: *** [minimu9-ahrs] Error 1

Magnetometer calibration script should be improved

The current minimu9-ahrs-calibrator script (in minimu9-ahrs version 2.0.0) takes about 18 minutes to run and sometimes produces totally invalid calibrations (along with a warning), so there is room for improvement.

The reason that it produces invalid calibrations is that the way it assigns a score to a given calibration is to see how close the scaled sample readings are to the unit sphere. The closer the points are to the unit sphere, the better the score. Sometimes the optimization routine realizes that it can make some of the calibration numbers really large, effectively squeezing all the sample readings into a very small area that is very close to the unit sphere. As it makes the numbers larger, the score of the calibration approaches the perfect score where everything is exactly on the unit sphere.

I suspect that with the current scoring, we are hoping for the optimization algorithm to find a local maximum, but sometimes it looks a little further than we would want and finds unreasonable calibrations that actually score better.

Maybe we should explore the new type of calibration routine provided by @thesummer in issue #8.

Incorrect configuration of LSM303_CTRL_REG4_A

I am stupidly settings the same register twice in a row:

writeAccReg(LSM303_CTRL_REG4_A, 0x08); // high resolution output mode
writeAccReg(LSM303_CTRL_REG4_A, 0x20); // 8 g full scale: FS = 10 on DLHC

That could explain why the raw readings were all a multiple of 4: we're not actually using high resolution output mode.

Error on Raspbian Stretch caused by including both i2c headers

The problem with including both i2c.h and i2c-dev.h as we did in pull request #36 is that on my operating system (Raspbian 9.13 stretch), both of those headers contain definitions of the i2c_msg and i2c_smbus_data structs:

$ make
g++  -I. -I/usr/include/eigen3 -Wall -std=gnu++11 -O2 -MD -MP  -c -o i2c_bus.o i2c_bus.cpp
In file included from i2c_bus.cpp:9:0:
/usr/include/linux/i2c.h:68:8: error: redefinition of ‘struct i2c_msg’
 struct i2c_msg {
        ^~~~~~~
In file included from i2c_bus.cpp:8:0:
/usr/include/linux/i2c-dev.h:37:8: error: previous definition of ‘struct i2c_msg’
 struct i2c_msg {
        ^~~~~~~
In file included from i2c_bus.cpp:9:0:
/usr/include/linux/i2c.h:131:7: error: redefinition of ‘union i2c_smbus_data’
 union i2c_smbus_data {
       ^~~~~~~~~~~~~~
In file included from i2c_bus.cpp:8:0:
/usr/include/linux/i2c-dev.h:89:7: error: previous definition of ‘union i2c_smbus_data’
 union i2c_smbus_data {
       ^~~~~~~~~~~~~~
<builtin>: recipe for target 'i2c_bus.o' failed
make: *** [i2c_bus.o] Error 1

Removing i2c.h fixes the issue but maybe it breaks the build on Raspbian Buster.

LSM6DS33 standalone mode

Hello :)

First of all thank you a lot for the work! I'm trying to use your tool with a standalone LSM6D33

`Error: No magnetometer to read.
pi@raspberrypi:~/minimu9-ahrs $ i2cdetect -y -r 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- 29 -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- 6b -- -- -- --
70: -- -- -- -- -- -- -- --

pi@raspberrypi:~/minimu9-ahrs $ ./minimu9-ahrs -b /dev/i2c-1 --mode raw --output euler
Error: No magnetometer to read.
`

Seems normal because of the LSM6D33 doesn't have magnetometer.

I can't spend too much time on that but after removing the read_mag_raw method from imu.h i'm able to get datas :)

pi@raspberrypi:~/minimu9-ahrs $ make -j4 && ./minimu9-ahrs -b /dev/i2c-1 --mode raw --output euler g++ -I. -I/usr/include/eigen3 -Wall -std=gnu++11 -O2 -MD -MP -c -o minimu9-ahrs.o minimu9-ahrs.cpp g++ -I. -I/usr/include/eigen3 -Wall -std=gnu++11 -O2 -MD -MP -c -o minimu9.o minimu9.cpp g++ minimu9-ahrs.o lsm303.o minimu9.o prog_options.o i2c_bus.o lis3mdl.o l3g.o lsm6.o -lboost_program_options -o minimu9-ahrs -1229777103 -1229783072 -1097588588 1886 -82 3691 78 -103 -67 -1229777103 -1229783072 -1097588588 2005 -79 3683 72 -91 -52 -1229777103 -1229783072 -1097588588 1988 -75 3653 67 -76 -54 -1229777103 -1229783072 -1097588588 2015 -81 3576 67 -90 -63 -1229777103 -1229783072 -1097588588 1970 -68 3619 38 -44 -43 -1229777103 -1229783072 -1097588588 1979 -80 3671 80 -109 -69 -1229777103 -1229783072 -1097588588 1979 -65 3578 68 19 -24 -1229777103 -1229783072 -1097588588 1990 -70 3628 77 -97 -60 -1229777103 -1229783072 -1097588588 1985 -61 3743 101 -129 -85 -1229777103 -1229783072 -1097588588 1953 -79 3621 21 -3 -25 -1229777103 -1229783072 -1097588588 2047 -69 3600 68 -89 -94

Of the 3rd first columns are unusable. So the question is what is simplest way to use your tool with LSM6DS33 ?

Thank you !

package architecture(armel) does not match system(armhf)

Dear Mr.David,
I am actually trying to calibrate the minimu9-ahrs with the raspberrypi. I followed the steps accordingly but when I tried to run 'dpkg -i minimu9-ahrs_VERSION_armel.deb', the output was "dpkg : error processing minimu9-ahrs_VERSION_armel.deb (--install):
package architecture(armel) does not match system(armhf)
Errors were encountered while processing :
minimu9-ahrs_VERSION_armel.deb'
p/s : I had include the latest version from the github but I don't know what went wrong.
I had also tried to use force architecture when running the dpkg but the minimu9-ahrs still cant be processed.
n not to forget, I am using raspbian wheezy.

Altimu10v5 strange readings in XY axis Euler output

Ok, so i've calibrated the device and have a strange output in euler.
sample.txt

Every axis works and shows correct values when i turn the Z axis clockwise.
But when i turn it to the lef(crossing North - 0 value) Z axis shows correct values but as you can see the other pitch and roll suddenly shows really high values around 170+ being still flat on the table.

When i switch to quaternion output the readings behave just fine and shows correct values for yaw pitch and roll however i turn the board around Z axis.

Can someone point me to the code thats responsible for that? I've looked through the main cpp file, but i dont see where it can fail like that.
Any help is appreciated
Thanks in advance!

Ps. Somehow turning the device along the Z axis counterclockwise interferes with calculating X and Y and its quite magical to me how this is happening

How to change GPIO pins?

Using a different processing board and need to solder the gyro board to different GPIO pin numbers. How can the target pins be set within the code?

ahrsd (like gpsd) anyone?

David,

Thank you very much for all the hard work that must have gone into this. I was able to set it up and make it work with Pololu's AltiMU-10 - the next generation of their sensor board that includes barometric pressure. If I can muster up enough C++ skill I will be adding the altimeter function to the ahrs (which makes it a half-baked adahrs, I suppose).

Have you given any thought to baking this into a daemon like gpsd? Exposing the data over sockets (both Unix domain and network) would be powerful. For the moment I'm faking it by piping all the data into a Redis pub/sub channel, but an actual daemon would be lighter / cleaner.

Cheers,

-S

Noob problem; don't know where to run the 'make' command

Hi there,

As a beginner I am trying to install the minimu9-ahrs for the raw data. As I am walking through the steps, I face a slight problem.

At the moment my sensor is soldered well and I get an output from i2cdetect -y 1. But I don't know how to navigate to the top-level directory and run the 'make' command. Where should I type this? How can I navigate to the good place in the terminal?

Thanks in advance

minimu9-ahrs: command not found

David,

Your software looks great, and I'm very exited to use it. However, after following your instructions on your wiki (https://github.com/DavidEGrayson/minimu9-ahrs/wiki), I still can't seem to get minimu9-ahrs to run. I installed using the command "sudo apt-get install libi2c-dev libboost-program-options-dev make" because I'm using the armhf EABI (so says the command line when I try wget). I don't see any errors, and everything seems to have worked fine, but when I try entering "minimu9-ahrs --mode raw" into the terminal I get the error "-bash: minimu9-ahrs: command not found". I'm pretty new with this, am I simply missing a step somewhere?

Using library in another project

I was wondering if it is possible to include this library as a dependency in another C++ project and programmatically pull sensor data in code?
I was able to get it working on the CLI but am not sure how to include it in my project.
I'm new to C++ so I was trying to figure out if it was possible.

Thank you!

typo?: pacer::set_period_ns ignores its nanoseconds

Thanks for this code David,

I'm still working my way through it, but I noticed that the function pacer::set_preiod_ns does not use the nanoseconds parameter when setting the spec variable. It doesn't matter since the use of this function in ahrs requests the same time, but I thought you might be interested.

Cheers,
Steve

Question about the yaw axis (magnetometer) values

David,

I've been working with the unit and the code for several days now and have noticed that:

  1. even after calibration the "north" value does not correlate with magnetic north as shown by my trusty Siva compass. It appears to be off by ~-15 degrees.

  2. if I rotate the device a perfect 180 from the perceived 0 to its opposite, the device reads not 180 but 200

  3. If I create a correction factor of 15 degrees to "true up" the north reading, then swing the device around 180 it reads 224 (!?!?)

Is the Euler value output corrected for "true" north vs. magnetic north?

I've tried moving the mounting around to several place (it's currently attached to the outside of the plastic housing that contains the Raspberry Pi) with similar results.

Any suggestions? I've re-run the calibration utility multiple times. Am I simply expecting too much from the sensor? Does it need to be attached to a dongle that is several feet from the Pi? (How long can you extend an i2c connection?)

Many thanks for your advice.

Trouble detecting sensors MinIMU-9 v5

Hi,

I'm trying to get MinIMU-9 v5 (purchase page mentions LSM6DS33 and LIS3MDL). I keep getting "no sensor detected" even though I see it when I run i2cdetect -y 1.

Am I missing something? Any help would be appreciated.

Thanks for putting up the code, this really helps!

Make Error: undefined reference to boost::program_options

When I tried to make the project, I encountered two errors with destructor scope in I2CBus.cpp and MinIMU9.cpp that were resolved by including <unistd.h>. However, I now get a new error due to undefined references to functions from boost::program_options. I suspect this is a linking issue (I have installed boost on my system), but the makefile contains the line LDFLAGS += -lboost_program_options, so I'm not sure how to proceed. A snippet of the make output is included below:

minimu9-ahrs.o: In function `boost::program_options::variables_map::~variables_map()':
minimu9-ahrs.cpp:(.text._ZN5boost15program_options13variables_mapD0Ev[_ZN5boost15program_options13variables_mapD0Ev]+0xe): undefined reference to `vtable for boost::program_options::variables_map'
minimu9-ahrs.o:(.rodata._ZTIN5boost15program_options20multiple_occurrencesE[_ZTIN5boost15program_options20multiple_occurrencesE]+0x10): undefined reference to `typeinfo for boost::program_options::error_with_option_name'
minimu9-ahrs.o:(.rodata._ZTIN5boost15program_options11typed_valueISscEE[_ZTIN5boost15program_options11typed_valueISscEE]+0x18): undefined reference to `typeinfo for boost::program_options::value_semantic_codecvt_helper<char>'
minimu9-ahrs.o:(.rodata._ZTVN5boost15program_options11typed_valueISscEE[_ZTVN5boost15program_options11typed_valueISscEE]+0x38): undefined reference to `boost::program_options::value_semantic_codecvt_helper<char>::parse(boost::any&, std::vector<std::string, std::allocator<std::string> > const&, bool) const'
collect2: error: ld returned 1 exit status
make: *** [minimu9-ahrs] Error 1

minimu-ahrs-calibrate fails

i tried to calibrate the magnetometer so i could use the visualizer (raw mode works great), but I'm getting the following Python error:

Optimizing calibration...Traceback (most recent call last):
File "/usr/bin/minimu9-ahrs-calibrator", line 147, in
run()
File "/usr/bin/minimu9-ahrs-calibrator", line 101, in run
full_output=False, disp=verbose, retall=False)
File "/usr/lib/python2.7/dist-packages/scipy/optimize/optimize.py", line 373, in fmin
res = _minimize_neldermead(func, x0, args, callback=callback, *_opts)
File "/usr/lib/python2.7/dist-packages/scipy/optimize/optimize.py", line 438, in minimize_neldermead
fsim[0] = func(x0)
File "/usr/lib/python2.7/dist-packages/scipy/optimize/optimize.py", line 281, in function_wrapper
return function(
(wrapper_args + args))
TypeError: can only concatenate tuple (not "list") to tuple

This is running ona Pi Zero, if that helps...

Feature request: column headers before start of output

I'm trying to make sense of the numbers that this program outputs, but I often have trouble with that. For example; when I run minimu9-ahrs --mode raw I get something like this:

pi@raspberrypi:~$ minimu9-ahrs --mode raw
   1552   -5487    3618    -2591    2925   -1362      249     -50     -11
   1538   -5494    3644    -2516    2940   -1407       -3     -48     -21
   1538   -5494    3644    -2529    2955   -1377       25     -88     -15
   1538   -5494    3644    -2550    2966   -1380      -15     -58       2
   1538   -5494    3644    -2566    2930   -1360       19     -58      -1
   1557   -5539    3610    -2564    2924   -1402       20     -69     248
   1557   -5539    3610    -2315    2922   -1378       32     -69     253
   1557   -5539    3610    -2580    2882   -1407      -17     -49       2

In the readme I read that it is the raw sensor data from the magnetometor, accelerometer, and gyro. But I'm unsure which numbers belong to which, and I also see 9 numbers, meaning that every one of them contains 3 numbers. To find out I'm finding myself going through the C++ sources, and since I'm not so proficient in that I'm having a hard time doing that.

The same accounts for the Euler output:

pi@raspberrypi:~$ minimu9-ahrs --output euler
   0.000    0.000   -0.000     0.038   -0.029   -0.938    -0.773   -0.089    0.833
   0.078    0.018   -0.033     0.037   -0.035   -0.934    -0.773   -0.089    0.833
   0.283    0.045   -0.156     0.047   -0.037   -0.940    -0.772   -0.066    0.825
   0.576    0.077   -0.330     0.052   -0.043   -0.973    -0.772   -0.066    0.825
   0.705   -0.172   -2.766     0.078    0.021   -1.025    -0.784   -0.091    0.816
   0.827   -0.186   -2.862     0.064   -0.002   -1.041    -0.784   -0.091    0.816
   0.708   -0.198   -3.132     0.044    0.031   -1.022    -0.765   -0.143    0.832
   0.344   -0.123   -3.034     0.031    0.104   -1.039    -0.765   -0.143    0.832
   0.118    0.213   -2.702     0.072    0.023   -1.086    -0.765   -0.143    0.832
 179.688  179.171  177.896     0.097   -0.014   -1.057    -0.765   -0.143    0.832
 178.823  178.513  178.669     0.105   -0.014   -0.902    -0.765   -0.143    0.832
 177.665  178.101  179.839     0.006    0.064   -0.968    -0.771   -0.175    0.818
 176.831  177.625 -179.274     0.151   -0.062   -1.006    -0.771   -0.175    0.818
 175.861  177.146 -179.156     0.156    0.008   -0.981    -0.771   -0.175    0.818
 174.918  176.925 -179.504     0.105    0.084   -0.912    -0.771   -0.175    0.818

The first three are compass, pitch and roll, but what are the other numbers?

It would be great if the first line of the output contains some simple column headers saying what the numbers are. In my opinion it would double the usefulness of the (for the rest awesome) library.

timing with polling vs timerfd

In minimu9-ahrs.cpp I noticed that you are polling for your timing:

        // Ensure that each iteration of the loop takes at least 20 ms.
        while(millis() - start < 20) 
        {   
            usleep(1000);
        }  

Please consider using timerfd() instead (see man 2 timerfd_create) since it will just wake the thread at the right time (well more or less since we do not have a rtos...). If requested I can do a pull request.

Also using the Fifo-scheduler should help with the timing, eg. pthread_setschedparam(pthread_self(), SCHED_FIFO, ...)

Build error on archlinux

Hi,

I'm trying to build minimu9-ahrs on archlinux.
I get the following errors while building:

i2c_bus.cpp: In member function 'void i2c_bus::write_byte_and_read(uint8_t, uint8_t, uint8_t*, size_t)':
i2c_bus.cpp:80:38: error: invalid use of incomplete type 'struct i2c_msg'
     { address, 0, 1, (typeof(i2c_msg().buf)) &command },

In file included from i2c_bus.cpp:8:0:
/usr/include/linux/i2c-dev.h:66:9: note: forward declaration of 'struct i2c_msg'
struct i2c_msg *msgs; /* pointers to i2c_msgs */

Did I make a mistake while installing the headers or is that something else?

No sensors found

Hello, thank you for helping me,
I need some help again.

So, I fellow some tutorials, all seems to be ok :

  • i2c is running on my raspberri pi3 ( /dev/i2c-1 )
  • all libraries are installed
  • sensors are detected when I run " i2cdetect -y 1 " exactly as you described in your tutorial
  • I build minimu9-ahrs as described, with " make " and " sudo make install " ( no error messages )

But now when I try to run minimu9-ahrs the response is :

  • Error : No magnetometer found
  • Error : No accelerometer found
  • Error : No gyro found
  • Error : Needed sensors are missing

Is a test to find where the mistake is ?
Thanks a lot.

Support for minimu9 v3

As stated in the wiki, currently only v1 and v2 are supported. Do you have an ETA for when v3 support will be there? I just ordered v3. How will v3 differ from v2 in terms of code? Maybe I can help.

Can't create ~./minimu9-ahrs: File exists

Hi,

Facing another small problem. I try to create a ~./minimu9-ahrs file in the home directory, but the terminal errors with ''mkdir: cannot create directory ' /home/pi/.minimu9-ahrs': File exists".

I see in the source code various different minimu9-ahrs files and I don't know where to put the 'i2c-bus=/dev/i2c-1' line. Can you help me out again?

Thanks in advance

LSM9DS1

Hello, for the above LSM9DS1 I do receive the following error:
Error: No accelerometer found.
Error: No gyro found.
Error: Needed sensors are missing.

sudo i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- 1e --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- 6b -- -- -- --
70: -- -- -- -- -- -- -- --

Is this sensor maybe not supported? I am using a SparkFun 9dof sensor stick.

Support ENU

Thanks for your excellent work on 'minimu9-ahrs'. I'm creating a ROS driver from it and it's basically working, especially if I use 'fuse_gyro_only()'. But when running with 'fuse_default()', the robot appears upside down (in the ROS rviz visualizer). Also, rotations of the robot about the x-axis sees changes in the z-axis (in the visualization).

ROS uses ENU, whereas minimu9-ahrs uses NED. So I tried changing the code like this (see "// JJ"):

/*
  doesn't work...
  we want East North Up (ENU), but existing is NED... how to convert?
*/
matrix rotation_from_compass(const vector & acceleration, const vector & magnetic_field)
{
  vector up = acceleration; // JJ - removed negation
  vector east = up.cross(magnetic_field); // actually it's magnetic east
  vector north = east.cross(up);

  east.normalize();
  north.normalize();
  up.normalize();

  matrix r;
  r.row(0) = east; // JJ - swapped these
  r.row(1) = north;
  r.row(2) = up;
  return r;
}

Could you offer some advice about how I should change the code to support ENU?

Thanks for any hints!

Downloading source code

Hi again,

Sorry for my tardiness but how can I download the source code? Is this code included in the libraries I just downloaded?

Thanks in advance

dependency issues while installing minimu9-ahrs

Hello, I am a beginner with raspberry pi and am trying to begin with the minIMU-9. I have encountered some problems along the way though. I followed all the steps David Grayson has given. Here is the error:

pi@raspberrypi ~ $ sudo dpkg --force-architecture -i minimu9-ahrs_1.1.1-1_armel.deb
dpkg: warning: overriding problem because --force enabled:
package architecture (armel) does not match system (armhf)
Selecting previously unselected package minimu9-ahrs.
(Reading database ... 68818 files and directories currently installed.)
Unpacking minimu9-ahrs (from minimu9-ahrs_1.1.1-1_armel.deb) ...
dpkg: dependency problems prevent configuration of minimu9-ahrs:
minimu9-ahrs depends on libboost-program-options1.42.0 (>= 1.42.0-1).
minimu9-ahrs depends on libc6 (>= 2.4).
minimu9-ahrs depends on libgcc1 (>= 1:4.4.0).
minimu9-ahrs depends on libstdc++6 (>= 4.4.0).

dpkg: error processing minimu9-ahrs (--install):
dependency problems - leaving unconfigured
Processing triggers for man-db ...
Errors were encountered while processing:
minimu9-ahrs

How do i fix this?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.