Code Monkey home page Code Monkey logo

ahrs's People

Contributors

dependabot[bot] avatar psiphi75 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

Watchers

 avatar  avatar  avatar

ahrs's Issues

Get user heading

Hi @psiphi75, thanks for your great package! It looks very promising.

I'm working on a smartphone-based pedestrian dead reckoning system and for that i need the heading direction of the user. The literature often states that a Madgwick and Mahony filter could help with obtaining the user's heading.

Sadly i'm not quite sure how to interpret the values obtained from madgwick.getEulerAngles().

madgwick.update(gyr.x, gyr.y, gyr.z, acc.x, acc.y, acc.z, mag.x, mag.y, mag.z);
const { heading } = madgwick.getEulerAngles()

console.log(heading * (180/Math.PI))

I'd like to draw conclusions like 'the user turned 45 degrees to the left'. Do you think it's possible with this package?

Inaccurate heading when using iOS sensors and Madgwick

First of all I tried this library with Madgwick and iOS uncalibrated sensors. Using raw gyro data from motion manager from which the apple docs don't state the unit - but microsoft docs stating them in radians per seconds. Which is the required unit. Using raw acceleration from which is in g that apple docs also states. And raw magnetometer data of which is of unknown unit - but should probably be in μT. (What is the "unitless unit" the compass parameters of this library is taken into the constructor?

When I am getting the heading I convert it to [0, 360]:

let heading = madgwick.getEulerAnglesDegrees().heading;
heading %= 360;
if (heading < 0) {
    heading += 360;
}
return heading;

When having the iPhone laying on a table and pointing it north I get a heading of 90°. Rotating the phone 360° clockwise back into the same position I get a heading of 265°. Doing it again I get 86°. Then I get 259°. What might cause this?

Sorry, I have a low-level problem. I don't understand how to use it in a browser. I tried to use it this way, but the result was incorrect

import AHRS from "ahrs";
import { Vector3 } from "three";
const rad2deg = 180.0 / Math.PI;
const deg2rad = Math.PI / 180.0;


const madgwick = new AHRS({
  /*
   * The sample interval, in Hz.
   *
   * Default: 20
   */
  sampleInterval: 20,

  /*
   * Choose from the `Madgwick` or `Mahony` filter.
   *
   * Default: 'Madgwick'
   */
  algorithm: 'Madgwick',

  /*
   * The filter noise value, smaller values have
   * smoother estimates, but have higher latency.
   * This only works for the `Madgwick` filter.
   *
   * Default: 0.4
   */
  beta: 0.4,

  /*
   * The filter noise values for the `Mahony` filter.
   */
  kp: 0.5, // Default: 0.5
  ki: 0, // Default: 0.0

  /*
   * When the AHRS algorithm runs for the first time and this value is
   * set to true, then initialisation is done.
   *
   * Default: false
   */
  doInitialisation: false,
});
let gyro = new Vector3()
let acceleration = new Vector3()
let compass = new Vector3()


window.addEventListener('deviceorientation', (event) => {
  const alpha = event.webkitCompassHeading != null ? event.webkitCompassHeading : 360 - event.alpha;
  compass.x = alpha
  compass.y = event.beta
  compass.z = event.gamma
})
window.addEventListener('devicemotion', (event) => {
  gyro.x = event.rotationRate.alpha * deg2rad
  gyro.y = event.rotationRate.beta * deg2rad
  gyro.z = event.rotationRate.gamma * deg2rad

  acceleration.x = event.acceleration.x
  acceleration.y = event.acceleration.y
  acceleration.z = event.acceleration.z
  update()
})

function update() {
  madgwick.update(
    gyro.x,
    gyro.y,
    gyro.z,
    acceleration.x,
    acceleration.y,
    acceleration.z,
    compass.x,
    compass.y,
    compass.z,
  );

  console.log(madgwick.getEulerAnglesDegrees());
}

Using an offset to overcome hinder with pitch in Euler angles?

In vertical - as if a photo is taken on an iPhone in portrait - pitch is near -90 degrees. And 0 deg when laying on a table. This is when using the setup:

const rotatedAccel = {
    x: accel.y,
    y: -accel.x,
    z: accel.z
}

In my current app I am developing where I am displaying AR objects onto to a camera view - these drastically change in position badly when pitch extends the vertical position (as if looking upwards with the mobile camera).
Heading is flipped -so that a north heading with [0, 360] suddenly becomes 180 degrees.
Roll is going wild around the vertical position.

Due to the fact pitch is [90, -90] I can't detect wether the user is looking upwards, and adjust the AR objects.
-77 deg could either be looking upwards or downwards.

So I thought I might be throwing this out here in case anyone might be stumbling into a similar issue.
Maybe there is someway of turning axises so that instead of [0, 0, 0] being --- flat on table it could be /?

Make require algorithm names static

The way you're including the algorithms dynamically breaks other platforms that rely on static analysis or don't allow dynamic requires, for example, React Native. Are you able to make the requires static, for example:

if (algorithmName === 'Mahony') {
    algorithmFn = new (require('./Mahony'))(sampleInterval, options);
} else if (algorithmName === 'Madgwick') {
    algorithmFn = new (require('./Madgwick'))(sampleInterval, options);
}

Axis rotation

Hello dear friend,
i was playing around with this module since I wanted to get quaternion then rotation matrix and then acceleration in world frame and I keep getting strange results. I then came back and saw that my axis are wrong, if I understood you correctly this is axis layout:

4-Roll-pitch-yaw-heave-sway-surge-of-a-ship

And i want to use this to calculate from data on smartphone, my smartphone has these axis:

Figure1

I am not sure if these axis has some sort of marking like XYZ or YXZ and I am having difficulties to understand how can axis from smartphone can be rotated into axis for this algorithm. I would really appreciate if you can just point me where to look for. Thanks :)

a question about the package

sorry to bother you with such a stupid question.
is this package reads the sensors values ( accelerometer, gyroscope) then calculates the orientation? or just takes those values as an input and then calculates the orientation ? because when I tried to run the code, I get an error " gyro is not defined "
thank you :)

Update Issues

Hello.
I'm having some trouble with this library when I update the values of the madgwick AHRS filter.
My application is a web app and i'm using Cordova to get it into Android. To get the acceleration I use that plugin which gives me a vector 3 in m/s² and that plugin to get the gyroscope. But when I get the euler angles after having the filter updated, the values are set to NaN.

So here's my question, what are the units of what you need to put into your update function ?
Am I using this library correctly ?

Fast initialization

Thanks for this module, it works very well once my magnetometer input has stabilized. I noticed the TODO in the readme, I'm curious if you already had an approach in mind?

Not working

I tried to use AHRS but the data what i got in return is not right.
I have an LSM9DS1 chip and i get data every 10Hz. But if i try to use getEulerAngles or getQuaternion() it returns not any correct data.

with the quaternion its from 2 to -2 to 0 and that goes on forever.

    const accel_x = array['accel_x_mg']/9.8, //raw data
        accel_y = array['accel_z_mg']/9.8,
        accel_z = array['accel_y_mg']/9.8,
        gyro_x = array['gyro_x_dps']*0.07,
        gyro_y = array['gyro_z_dps']*0.07,
        gyro_z = array['gyro_y_dps']*0.07,

This is the data (also raw magnetometer)

Tilt Correction when it comes to heading?

I am going to try to provide as much information as possible for some assistance. I've been playing around with this library for a few weeks and am pretty satisfied so far, but I have finally come across a bit of weirdness that I can't seem to solve. It involves the heading of each individual axis while the device is tilted.

Here is my basic setup:

const AHRS = require('ahrs');
    this.ahrs = new AHRS({
        sampleInterval: 26,
        algorithm: 'Mahony',
        doInitialisation: true,
        kp: 15.0, // Default: 0.5
        ki: 0.1,  // Default 0.0
    });
};

After initializing the AHRS, The data is processed this way:

BoxTest.prototype.filterGyroData = function() {
    this.dt = this.imu.data.dt; //Calculated each time data is received from the device
    this.gyro.copy(this.imu.data.gyro); // Vector3 being created from gyro data
    this.gyro.sub(this.state.gyroBias); // Subtract bias
    this.acc.copy(this.imu.data.acc); // Vector3 being created from accelerometer data
    this.acc.sub(this.state.accBias); // Subtract Bias

    this.gyro.mulScalar(70).divScalar(1000).mulScalar(pc.math.DEG_TO_RAD); // Divide by 13.7 (from hardware docs) to be in line with units in degrees and then convert to radians
    this.acc.divScalar(8192); // Divide by 8192 (from hardware docs) to make G's

    if(this.imu.data.mag) {
        // Only send magnetometer data if there has been a update from the chip
        this.mag.copy(this.imu.data.mag); // Vector3 being created from magnetometer data
        this.mag.sub(this.state.magBias); // Subtract Bias
        this.ahrs.update(this.gyro.x, this.gyro.y, this.gyro.z, this.acc.x, this.acc.y, this.acc.z, this.mag.y, -this.mag.x, this.mag.z, this.dt);
    }

    else {
        this.ahrs.update(this.gyro.x, this.gyro.y, this.gyro.z, this.acc.x, this.acc.y, this.acc.z, 0, 0, 0, this.dt);
    }

    this.state.quat.copy(this.ahrs.getQuaternion()); // Update existing Quaternion from AHRS output
    this.flipQuaternion(this.state.quat); // Flip Quaternion axes to match coordinate system
    this.state.quat.mul(this.forward); // Rotate 90 degrees to point Z north instead of west

};

BoxTest.prototype.flipQuaternion = function(quat) {

    let tempX = quat.y;
    let tempY = -quat.z;
    let tempZ = quat.x;
    let tempW = -quat.w;

    this.state.quat.set(tempX, tempY, tempZ, tempW);

};

After this data is processed I then apply the rotation to a 3D object. Before adding the magnetometer data I was able to confirm that the basic orientation and rotation of all of the axes occurred as expected. Whenever I would point any of the axes 'down' this would be visually represented by the cube that I'm working with. Of course, the heading was wrong, and the results would drift eventually, especially after some particularly speedy rotations, but overall things were working as expected.

In flipping the Y and X axes for the magnetometer and negating X, I am now able to very consistently have my X and Z point to my virtual 'north' when they point north in the real world. This start to go wonky, however once I move the Y axis closer to horizontal. I find that the direction in which the Y axis points is only accurate when X is pointed straight up. If X is pointed straight down then the Y axis points a full 180 away from the intended direction. This behavior is gradual, so you can see it slowly reach the reversal as X get further away from 'Up'. A identical behavior is observed with pointing the X axis in a direction while the Z axis is not pointed straight down.

Writing this out has me now reconsidering that it is an issue with the mag data being provided to the AHRS system with either order or signs being the culprit, and maybe I am just tired, but I have tried all 48 possible combinations of axis order and signs with no promising results. I have also tried disabling my Quaternion flip and the final rotation of 90 degrees, which did not remove the behavior, making it only appear to happen on different axes due to the coordinate system change.

I am keeping my fingers crossed that it's just a simple mistake that I'm overlooking in my setup, and would deeply appreciate any guidance anyone can give.

test data

Excuse me, i want to ask what is the difference between test-data-pitch-move.js and test-data-random-move.js? Did you use real sensor or just use sensor data from library?

Thank you for your attention

Unexplainable drifting in output

My X degrees value is drifting despite the sensor being completely static..

degrees line is output from:

var data = new Int8Array(buffer);
var accX = (new Int16Array([data[0] | data[1] << 8]))[0];
var accY = (new Int16Array([data[2] | data[3] << 8]))[0];
var accZ = (new Int16Array([data[4] | data[5] << 8]))[0];

var gyrX = (new Int16Array([data[6] | data[7] << 8]))[0];
var gyrY = (new Int16Array([data[8] | data[9] << 8]))[0];
var gyrZ = (new Int16Array([data[10] | data[11] << 8]))[0];

accX = (accX / 32768)*8;
accY = (accY / 32768)*8;
accZ = (accZ / 32768)*8;

gyrX = (gyrX / 32768)*500;
gyrY = (gyrY / 32768)*500;
gyrZ = (gyrZ / 32768)*500;

madgwick.update(accX, accY, accZ, gyrX, gyrY, gyrZ);

var radian = madgwick.toVector();

var x = radian.x * 180 / Math.PI;
var y = radian.y * 180 / Math.PI;
var z = radian.z * 180 / Math.PI;

console.log("degrees", x, y, z)

and the second line is the input accX, accY, accZ, gyrX, gyrY, gyrZ...

...

Note the drift of 13 degrees... Any idea what I'm doing wrong?

Gyro & Acc

I'm working with Arduino nano 33 iot with an IMU sensor comprises from accelerometer & gyroscope.

My goal is to analyse human gait. I'm already have x,y,z values of 2 sensors.
I'll be glad if you could explain to me what use can I make with this library and if I can use it at all without compass output

Kp and Ki different?

I noticed here that these values are different on other libraries in other languages like here, is there a reason why? Are those values supposed to be adjustable?

Combining AHRS with gyronorm.js

Hi there, my usecase is to gather accelerometer data (x/y/z) while driving a car. I'd like to make sure the data gathered is in earth co-ordinates, which means the data should be relative to earth coordinates irrespective of how the phone is placed in the car.

GyronormJS returns the rotation and acceleration values as follows:

    // data.do.alpha	( deviceorientation event alpha value )
    // data.do.beta		( deviceorientation event beta value )
    // data.do.gamma	( deviceorientation event gamma value )
    // data.do.absolute	( deviceorientation event absolute value )

    // data.dm.x		( devicemotion event acceleration x value )
    // data.dm.y		( devicemotion event acceleration y value )
    // data.dm.z		( devicemotion event acceleration z value )

    // data.dm.gx		( devicemotion event accelerationIncludingGravity x value )
    // data.dm.gy		( devicemotion event accelerationIncludingGravity y value )
    // data.dm.gz		( devicemotion event accelerationIncludingGravity z value )

    // data.dm.alpha	( devicemotion event rotationRate alpha value )
    // data.dm.beta		( devicemotion event rotationRate beta value )
    // data.dm.gamma	( devicemotion event rotationRate gamma value )

Based on reading your documentation, would AHRS be a good fit for my goals? I plan to use gyro norm to get the data and then

madgwick.update(data.do.beta, data.do.gamma, data.do.alpha, data.dm.x, data.dm.y, data.dm.z);
console.log(madgwick.toVector());

I'll give it a shot next week, but just wanted to know if your library is meant for this.

Calculate sample interval

Forgive my igorance.

I have a sample rate of 4.93 millis from my GoPro.

How do I covert that to Hz?

Thanks

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.