Success with IMU data!

I know there has been a lot of interest in getting IMU data out of the reach. After working through the different info on this site and RTIMULib2, through a lot of experimentation and a bit of luck, I’ve been able to get what appears to be good, calibrated data out of the IMU!

I was able to make this work on both of my reach units, so it’s not pure luck, but I will admit that I don’t have all the steps (or more importantly the order) well defined.

The important bits are cloning RTIMULib2, installing cmake, making the appropriate bits, modifying the .ini file and calibrating the unit.

Here’s a github page I started to try and capture the details of the steps and (hopefully) to capture code bits as I work on ways to send the data out of the reach and trying to integrate or fuse the GPS and IMU data onboard within the Edison.

The fused roll, pitch and heading data output from example:

And some images of data from some early testing vs a BNO055 and analog inclination sensor. I wrote a simple UDP socket script into the program.


@feepyj Thank for the write up!

I have however a question about magnetometer data. Does this work well? How did you calibrate it? I am using the device at longitude 59. I have tried magnetometer calibration from RTIMULib2 (the min/max calibration). This didn’t change much. Haven’t tried ellipsoid calibration as this requires octave.
I have also tried some other calibration scripts.

I would like to use RTK module to get the heading. But it seems I have some trouble getting magnetometer working correctly. May-be you have had success with this?


I have had decent success with heading, but it is not perfect. Using the magnometer calibration only, the heading seems repeatable and angle changes are accurate. I don’t have firm numbers, but my estimate on the absolute accuracy is about +/-2-3 deg. I’ve seen places claiming down to 2 deg accuracy with low cost MEMS, but there are limits to what can be expected.

In the RTIMULib.ini file, there is a place to enter the magnetic deviation for your location to correct the magnetic north reading to true north. (value needs to be entered in radians).

I would like to figure out the ellipsoid and see if that helps, just not sure how to do that with the Edison and octave. I know when I keep heading constant, but apply pitch or roll to the Reach, I’ll see 2-3 degrees of movement in the heading. I can only surmise this is cross talk in the sensors and calibration.

Last comment, I also can make the heading vary greatly (over 100 deg change) by moving the reach close to my computer speakers OR close to the metal ground plane I made for the antenne, so it is easily affected by stray magnetic fields.


Much thanks for explaining the procedure and it works well for me.
However I am still confused about how to turn on or off IMU logging during GPS operation?
Is it possible to add it in the web app or do I have to access it every time through ssh and then start the script?
Sorry if its a stupid question but I just started to work with this and I’m a complete novice.

@feepyj Tank you for this post !
You clone in repository of richards-tech which is not available nowadays. Do you have alternative ?
I found this : Is this similar ?

I am trying to get the Gps+IMU data from Reach to my computer. I am able to run inside the Emlid Reach using SSH (My Emlid is connected to the office wifi network). But when I run your program, I always receive this error:
“Unable to connect to TCP socket for GPS data”. It seems that I am not able to connect to Emlid reach via UDP. I tried to set the GPS_IP from local host to the IP address assigned to Emlid by my router. Also I tried to make it work when Emlid is directly connected to my computer in hotspot mode. In all cases, I have received the same error. Do I need to configure something in the network of my computer or Emlid?
Thanks in advance for the help!

Where did you find this python script. Without sharing, difficult to help …

Here it is :

Please see the line number 72 where the script is trying to connect to EMLID via a TCP socket but that connection is throwing an error.

Line 24 : “Set Reachview output to server, localhost, port 5101”

Did you make it inside reach web configuration ?

Yes, I set these in ReachView app running on the web. I can see a message ( in the ReachView app below the Position output) that it connected to localhost when I run the script but the error remains :frowning
One more info: I have updated the firmware of Reach to version 2.11 few days ago.

I have 2.11 also and it seems position output buggy !
I got it working once with LLH but now position output is in waiting status …

You can isolate part of script to try :

import socket
GPS_IP = ''
GPS_PORT = 5102
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
GPS_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
GPS_address = (GPS_IP, GPS_PORT)
gpsnum = 1

     GPS_sock.connect((GPS_IP, GPS_PORT))
     GPS_Connection = True
     print("Connected to Reach")
     print("Unable to connect to TCP socket for GPS data")
     GPS_Connection = False

May be try in a clear sky. I’m near my house and have only one green bar in signal noise ratio

Edit 2 : command send

and answer which means it’s working but not all the time. Need to test in clear sky !

Ok Thanks for your feedback. I guess It is working for me now but I had to make chnages in other sections of the code. Because I had done exactly the same settings and yielded the same error.
Here I try to explain my solution:
There are two problems:

  1. The Script is always throwing an error of Unable to connect. I don’t know why. I see the connection is established in ReachViewer. Moreover, when I try to print the stringdata1 (Line 134), I can see the incoming buffer. So I am not worried for this error anymore.
  2. The Second problem is then why the PAOGI message is not received on my computer:
    When I run the ncat command on my computer : ncat Emlid’s IP <5102>, It displays the NMEA message coming from Emlid in the terminal. In the script (Lines 81-83), GPSsentence is defined as $GPGGA, It is trying to find these sentences in the function decode_NMEA (Line 160). However, Emlid is sending $GNGGA and so on for other sentences. The script is never able to find the correct sentences so it never sets the GPS_Update flag to true to send the PAOGI message. So Setting Line 81-83 to correct names of GPS sentences (in my case $GNGGA and so) will solve the problem.

Thank you very much for your help!

I think I got through this but had to cross compile on my RasPi. Migrating over to the Reach unit for testing…

Will have more to share.


A quick warning for everybody who is using IMU data in their project. Emlid has decided to stop providing root access to M+ and other devices

This is already the case in the current dev build

It doesn’t seem to be possible to access the SPI device and the IMU with the new configuration.

I advise you to update to the new version carefully if this is a concern for you. The last working version AFAIK is 2.18.1 .

1 Like

Do you have any links/hints on how to cross-compile for the reach-devices?

Anybody managed to get some useful data from the IMU inside the Reach RS2 ?
The included ‘imu_test’-application says ‘passed’, but I’ve no clue what exactly this program is testing.

I managed to cross-compile py-spidev as well as RTIMULibCal.
But both are reporting that WHO_AM_I-register returns 0x40 (64) instead of the expected 0x71.

So now I am wondering:
-Does the RS2 still contain the MPU9250 or is there another sensor inside?
-Is the sensor still accessible over the SPI-bus on 0.0 ?

1 Like

Here comes an update for interested people:
-Emlid confirmed the IMU inside ReachRS2 is no longer the MPU9250 but it is replaced with the ICM20948
-Basic read/write over SPI with the IMU was successful.
-As an initial step, I’m trying to implement a ICM20948-driver for RTIMULib (accel/gyro seem to work already)
-after everthing is working with RTIMULib, I’ll try not to use it :slight_smile:. But attempt to use the DMP embedded in the ICM20948 to reduce the load on reach itself.


Some results & status update of progress:

  • I currently gave up on the RTIMULib driver (it’s communicating and working, but I cannot get stable results, the driver is receiving all the data, but I think someting is still wrong in coordinate-frame orientation or scaling of the data. The problem is, it is hard to find documentation what is the expected coordinate frame, should it be compensated in the .ini, or directly in the drivers, how/when are the funtions getting called …) Anyway device-communication is done (altough at the moment I won’t guarantee there are no bugs, but passing the results into the core of the library needs some fixes.
  • Since the last commit on RTIMULib was looong ago, and the readme stated it is there ‘just for consultation/historical reasons’, I decided to try another fusion library. The one I found/used is the GPL-licensed Fusion.
  • I created some small ‘ICM20948’-class which enables to communicate/experiment with the device independant of any fusion library.
  • I also created some small application combining using the fusion library and my other class to test some results.
  • I succeeded in getting a fused result, but I there are still some issues.
  1. pitch seems to go twice between [-90,90] degrees instead of the full 360 degrees.
  2. yaw is not that accurate
  3. pitch doesn’t go above 80-85°
  • maybe some issues could be solved by proper calibration (was uncalibrated acc and compass). All axes of the compass seem to give other readings when the axis is rotated into the same position. (Ranges of min/max seem to be similar, but the values are shifted quite a bit…, going from -50uT up to 200uT). Also the accelerometer in rest seems to stay just below 1g.

Video of first run with fusion
My sourcecode playground

Still on my wishlist:

  • implement the sensor-selftests to see if that can help with calibration/accuracy, and will be usefull in case of problems in the future.
  • use the onchip DMP, only working sample I found online was based on the Dev-Kit, but that are quite some sources (which probably have a not so friendly distribution license), and are a real challenge to learn from. But that’s probably the first step when I go down this road.
  • Most important: Find an easy way get the code running on the device, without producing additional load and without root-access.
  • Sidenote / work: I need to change the Makefiles, it was the first time I created them from scratch, and apparently I’m not that good at it ;-), so I made some hacks in them to get my tests going. So this definitely needs to be fixed. in the meantime be carefull when rebuilding/linking…

All help/advise/fixes/contributions/feedback will be highly appreciated :slight_smile:

1 Like

Calibration of magnetometer and accelerometers is crucial.
Might find some tips from rtimulib2

Thanks, didn’t find this project before, it’s a neat setup for auto start/stop. Too bad it won’t work anymore on latest firmware (not enough priviliges).

Because I saw lot’s of people using RTIMULib, I gave it another shot and got it working. After some fixes & re-calibration.

Because I couldn’t find the expected orientation for measurements to IMULib, I tried to deduce it from the MPU9250 implementation and it’s datasheet. and feed them in the same way.
Then I also discovered the conversion from raw bytes to uT of the MPU9250 is probably wrong, it multiplies the raw data by 0.6, but the datasheet clearly states 1LSB==0.15uT. Anyway, that’s probably why calibration is important :wink: