Separating Gyro values, X, Y and Z from RTimuLIB

Hi All,

I am working on a headtracking unit utilizing MPU9250 sensor with the RTimuLIB library. I did managed
to pin point the Serial.Print and the RTMath.h file to the display the sensor reading.

"RTMath::displayRollPitchYaw("GyroPos:", (RTVector3&)fusion.getFusionPose()); // fused output"

on serial display

ArduinoIMU starting using device MPU-9250
Using compass calibration
GyroPos: rollX:1.07 pitchY:1.17 yawZ:99.01
GyroPos: rollX:1.12 pitchY:1.18 yawZ:99.35

RTMath.h file

void RTMath::displayRollPitchYaw(const char *label, RTVector3& vec)
{
Serial.print(label);
Serial.print(" rollX:"); Serial.print(vec.x() * RTMATH_RAD_TO_DEGREE);
Serial.print(" pitchY:"); Serial.print(vec.y() * RTMATH_RAD_TO_DEGREE);
Serial.print(" yawZ:"); Serial.print(vec.z() * RTMATH_RAD_TO_DEGREE);
}

My question are, where/how do I print just the X value alone?
Is the X value, 1.07 or 1.12 came from "Serial.print(vec.x() * RTMATH_RAD_TO_DEGREE);"

I got I compile error when trying to print "Serial.print(vec.x() * RTMATH_RAD_TO_DEGREE);"
in the IDE. Help.

I needed the Roll, Pitch and Yaw values along.

Post the code, using code tags, and the error message.

See the "How to use this forum" post.

Hi jremington

I am trying to print the X, Y and Z values based upon my very basic understanding of coding skill (guessing).

From both libraries, the RTMath.cpp and RTFusionRTQF.cpp

RTMath::displayRollPitchYaw("GyroPos:", (RTVector3&)fusion.getFusionPose());                                                  // Copied from two line 110

Serial.print(vec.x() * RTMATH_RAD_TO_DEGREE);

I got following error,

Arduino: 1.8.4 (Windows 7), TD: 1.39, Board: "Teensy 2.0, Serial + Keyboard + Mouse + Joystick, 16 MHz, US English"

ArduinoIMU: In function 'void loop()':
ArduinoIMU:114: error: 'vec' was not declared in this scope
Serial.print(vec.x() * RTMATH_RAD_TO_DEGREE);

^

'vec' was not declared in this scope

As for the "fusion.getFusionPose" portion. I am cracking my head trying to crack the coding.

Basic I am trying to get the X, Y and Z values so I can plugin with Hatire, Since I couldn't figure out how to the Joystick Windows device (HID) the recognize the IMU axis.

https://sourceforge.net/projects/hatire/files/ARDUINO/MPU6050/

ArduinoIMU.ino (4.72 KB)

Maybe this will work.

void displayRollPitchYaw(RTVector3& vec)
{
    Serial.print(vec.x() * RTMATH_RAD_TO_DEGREE);
    Serial.print(' ');
    Serial.print(vec.y() * RTMATH_RAD_TO_DEGREE);
    Serial.print(' ');
    Serial.println(vec.z() * RTMATH_RAD_TO_DEGREE);
}

...

displayRollPitchYaw((RTVector3&)fusion.getFusionPose());

OP's code, properly posted below.

////////////////////////////////////////////////////////////////////////////
//
//  This file is part of RTIMULib-Arduino
//
//  Copyright (c) 2014-2015, richards-tech
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy of 
//  this software and associated documentation files (the "Software"), to deal in 
//  the Software without restriction, including without limitation the rights to use, 
//  copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the 
//  Software, and to permit persons to whom the Software is furnished to do so, 
//  subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in all 
//  copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 
//  INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 
//  PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 
//  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 
//  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 
//  SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

#include <Wire.h>
#include "I2Cdev.h"
#include "RTIMUSettings.h"
#include "RTIMU.h"
#include "RTFusionRTQF.h" 
#include "CalLib.h"
#include <EEPROM.h>

RTIMU *imu;                                           // the IMU object
RTFusionRTQF fusion;                                  // the fusion object
RTIMUSettings settings;                               // the settings object

//  DISPLAY_INTERVAL sets the rate at which results are displayed

#define DISPLAY_INTERVAL  300                         // interval between pose displays

//  SERIAL_PORT_SPEED defines the speed to use for the debug serial port

#define  SERIAL_PORT_SPEED  115200

unsigned long lastDisplay;
unsigned long lastRate;
int sampleCount;

void setup()
{
    int errcode;
  
    Serial.begin(SERIAL_PORT_SPEED);
    Wire.begin();
    imu = RTIMU::createIMU(&settings);                        // create the imu object
  
    Serial.print("ArduinoIMU starting using device "); Serial.println(imu->IMUName());
    if ((errcode = imu->IMUInit()) < 0) {
        Serial.print("Failed to init IMU: "); Serial.println(errcode);
    }
  
    if (imu->getCalibrationValid())
        Serial.println("Using compass calibration");
    else
        Serial.println("No valid compass calibration data");

    lastDisplay = lastRate = millis();
    sampleCount = 0;

    // Slerp power controls the fusion and can be between 0 and 1
    // 0 means that only gyros are used, 1 means that only accels/compass are used
    // In-between gives the fusion mix.
    
    fusion.setSlerpPower(0.02);
    
    // use of sensors in the fusion algorithm can be controlled here
    // change any of these to false to disable that sensor
    
    fusion.setGyroEnable(true);
    fusion.setAccelEnable(true);
    fusion.setCompassEnable(true);
}

void loop()
{  
    unsigned long now = millis();
    unsigned long delta;
    int loopCount = 1;
  
    while (imu->IMURead()) {                                // get the latest data if ready yet
        // this flushes remaining data in case we are falling behind
        if (++loopCount >= 10)
            continue;
        fusion.newIMUData(imu->getGyro(), imu->getAccel(), imu->getCompass(), imu->getTimestamp());
        sampleCount++;
        if ((delta = now - lastRate) >= 100) {
            //Serial.print("Sample rate: "); Serial.print(sampleCount);
            if (imu->IMUGyroBiasValid())
                //Serial.println(", gyro bias valid");
            //else
                //Serial.println(", calculating gyro bias");
        
            sampleCount = 0;
            lastRate = now;
        }
        if ((now - lastDisplay) >= DISPLAY_INTERVAL) {
            lastDisplay = now;
//          RTMath::display("Gyro:", (RTVector3&)imu->getGyro());                        // gyro data
//          RTMath::display("Accel:", (RTVector3&)imu->getAccel());                      // accel data
//          RTMath::display("Mag:", (RTVector3&)imu->getCompass());                      // compass data
            RTMath::displayRollPitchYaw("GyroPos:", (RTVector3&)fusion.getFusionPose()); // fused output             
            Serial.println();
            
            RTMath::displayRollPitchYaw("GyroPos:", (RTVector3&)fusion.getFusionPose()); // Copied from two line 110
            Serial.print(vec.x() * RTMATH_RAD_TO_DEGREE);
//            
//          Reading RTFuisionRTQF portion
//          RTFusionRTQF::RTFusionRTQF(RTVector3&)fusion.Gyro(x);
//          Serial.print(m_measuredQPose.setX(-m_measuredQPose.x());

            
           
        }
    }
}

Nowhere in your Arduino program do you declare the variable "vec" or put anything in it to print.

Change your added Serial.print() statement to

            ...
            RTVector3 vec = fusion.getFusionPose();
            Serial.print(vec.x() * RTMATH_RAD_TO_DEGREE);
            ...

Note that these are not the "Gyro values", FusionPose is the estimated absolute orientation of the sensor.

Hi jremington

Your code works.

Here is my modified lines for Hatire plugin with either OpenTrack or FaceTracknoIR,

{
      RTVector3 vec = fusion.getFusionPose();
      hat.gyro[0] = (vec.x() * RTMATH_RAD_TO_DEGREE);
      hat.gyro[1] = (vec.y() * RTMATH_RAD_TO_DEGREE);
      hat.gyro[2] = (vec.z() * RTMATH_RAD_TO_DEGREE);

      //Send Trame to HATIRE PC
      Serial.write((byte*)&hat,30);

      // inc frame cpt
      hat.Cpt++;
      if (hat.Cpt>1000) {
      hat.Cpt=0;;
      }
      delay(10);
      }

Just curious, there shouldn't be any drift with an MPU that have a magnetometer built-in. I ran the Mag/Calibration sketch and noted the RTimulib library serial printed values seem to be more stable compared to other library. I think I am seeing a minor drift. It maybe a defected MPU(unbranded). I will solder and test another MPU9250 and will post the result.

Thanks you, jremington and all. 'S (Salute in flightsim communities)

Glad to help!

Gyro drift depends on temperature and other factors, so it can only be temporarily corrected. Also, the magnetometer is extremely sensitive to stray magnetic fields, or magnetic materials in its surroundings, so no correction can be perfect.

Hi All,

I need help converting accelerometer values to 16 bit integer. My current accelerometer values are as follow,
and I think it is in Vector.

Accel: x:0.04 y:0.02 z:0.92Pose: roll:1.37 pitch:-2.46 yaw:94.40
Accel: x:0.04 y:0.02 z:0.92Pose: roll:1.37 pitch:-2.46 yaw:94.40
Accel: x:0.04 y:0.02 z:0.92Pose: roll:1.37 pitch:-2.47 yaw:94.41
Accel: x:0.04 y:0.02 z:0.92Pose: roll:1.37 pitch:-2.47 yaw:94.40
Accel: x:0.04 y:0.02 z:0.92Pose: roll:1.37 pitch:-2.46 yaw:94.37

And if I moved the IMU either to the right and rest or vice versa and rest. I got the following values

Accel: x:-0.13 y:0.09 z:0.93Pose: roll:1.58 pitch:-2.25 yaw:93.65
Accel: x:0.03 y:0.01 z:0.90Pose: roll:1.63 pitch:-2.10 yaw:91.90
Accel: x:0.30 y:0.03 z:0.93Pose: roll:1.63 pitch:-2.15 yaw:89.22

The rest value/position return to zero once stop moving. I not trying to calculate displacement.
I trying to simulate a temporary displacement value for short period interval. Let say 1.5 to 2 seconds.

Read the accelerometer values directly from the sensor. Those will be integers.

Any help in getting only the roll pitch and yaw? I'm stuck on how to get those values and store them on other variables

Any help in getting only the roll pitch and yaw?

The answer is in the rest of the thread that you hijacked.

Please read it.

Pardon for lately reply.

Kindly see the following link for additional reference.
https://theairtacticalassaultgroup.com/forum/showthread.php?t=28730

Just an FYI. the IMU with GD20H+M303D had been discontinued by Pololu.
You can still purchase it from offshore retailer (China).
Its work great.

//#define GD20HM303D_6a // GD20H + M303D at address 0x6a
//#define GD20HM303D_6b // GD20H + M303D at address 0x6b

The MPU9250 is ok (Didn't test extensively)

I wouldn't recommended purchase the below component. Too much noise and drifting

//#define LSM9DS0_6a // LSM9DS0 at address 0x6a
//#define LSM9DS0_6b // LSM9DS0 at address 0x6b

Regards
Ki714

Here is another method.

Declare your variable,

float yAxis;

void loop()
yAxis = ((RTVector3&)fusion.getFusionPose()).y();
float Y = (yAxis * RTMATH_RAD_TO_DEGREE);
Serial.println();
Serial.print ("Y Value"), (Serial.print(Y));

Method copied