Shop OBEX P1 Docs P2 Docs Learn Events
MEMS gyroscopes help — Parallax Forums

MEMS gyroscopes help

I am using a MEMS gyroscopes and I dont understand how to implement it.

The data is in degrees / second and in my case 2000 deg /sec. I can see the rate of change using prop serial terminal.

So what is this good for? I can tell how fast the IC rotates in deg/sec but I am confused? I guess ultimately my brain cant see it. My goal, what I am trying to do is balance a robot on two wheels. I totally understand the acceleration part and can calculate the angle no problem but the moment I start thinking about MEMS gyroscopes I loose it and this is in part because a real gyroscope resist change in movement. If I spin a bike tire it resist me when I try to move it.

Please someone try and lay down some knowledge so that my head sees it.... :)

JasonD I owe you a thanks but I still cant see the value of the Gyro. I understand integration, I understand complementary filter I just cant see why Gyro is needed.

Comments

  • JasonDorieJasonDorie Posts: 1,930
    edited 2017-03-01 23:21
    Well, if you can't see why the gyro is needed then you don't quite get the complimentary filter. :)

    The gyro tells you how fast you're rotating - that's it. It's a simple measurement device that uses gyroscopic effects (like you describe with the bike tire) to figure out how fast it's being rotated, and in which direction. It doesn't give you an actual orientation, just a rotational speed. The faster you try to move that spinning bike tire, the stronger the resisting force - this is what the MEMS gyro measures.

    The reason it's useful is this: if you know what your old orientation was, and how fast you were rotating in degrees/sec for the last 1/10th of a second, you could compute what your new orientation is.

    For example, if I start upright (0 degrees), and my gyro measures a rate of 50 deg/sec for 0.5 seconds, I've changed orientation by 25 degrees. In reality, you're going to be taking gyro measurements probably 100 times / second (or you should be), and adding up all of those little fragments of gyro rates to get the estimated current orientation.

    Your code will eventually look like this:
    angle := readAccel()   'use the accel to get an initial angle value, as a float in degrees, 0 == upright
    
    repeat
      gyroAngle := readGyro()    'assumes the result is in float degrees / sec
      accelAngle := readAccel()  'assumes the result is in float degrees, 0 == upright
    
      'integrate the gyro reading to get a new angle estimate
      angle += gyroAngle / updateRate   'update rate is how many times/sec this loop runs
    
      'complimentary filter - mix in a little accel angle to improve the estimate
      angle := (angle * 0.95) + (accelAngle * 0.05)
    

    The big reason for the gyro is that it is dramatically less affected by noise & vibration. The accelerometer angle is very close to useless when the sensor is being moved around, but averaged over time, they're pretty accurate. On the other hand, the gyro gives you a very clean result in the near term, but over time it'll drift off the true angle because of imprecision. The complimentary filter uses the long-term average accel reading to correct the gyro drift. That's pretty much it.
  • Zap-oZap-o Posts: 452
    edited 2017-03-01 23:41
    Okay

    I think that example you listed hits home now. I continued to think that Gyro was a different unit (deg/sec) and I did not like adding different units but now I see how you make it an angle. I can add angles together.
  • JasonDorieJasonDorie Posts: 1,930
    edited 2017-03-01 23:53
    The important bit for the gyro is just this:
     angle += readGyroAngle() / updateRate
    

    It technically doesn't matter what units you work in (radians, degrees, 65536ths of a circle...) as long as the accel angle and the gyro angle are using the same units. The accel angle is an absolute reading, and the gyro angle is a rate - that's really the only difference.

    It'd be the same as trying to figure out how far you've traveled by integrating your speed over time. If you know your speed in miles/hour, you can multiply that by the number of hours since your last reading to figure out how many miles you moved. By multiplying by elapsed time, you get a relative number in the correct units. In my example above, I'm dividing by updateRate, which is the same as multiplying by elapsed seconds.

    elapsedSeconds := 1.0 / UpdateRate
  • Heater.Heater. Posts: 21,230
    I think you got it.

    It's just like the speedometer in your car. If your car had no odometer you would not know how many miles down the road you have moved. But if you have your speedometer and a clock, then you know that is the speedo reads 40mph for an hour you have traveled 40 miles. For example.

    The gyro is the same. Except instead of speed (rate of change of distance) it is measuring rate of change of angle. So if you know what your rate of change of angle is and you know how long it's been like that then you know the angle that you have rotated by in that time.

    What is your accelerometer?

    I would expect an accelerometer to read -1g in the vertical direction (scaled to whatever range of numbers it uses) and 0g in the horizontal directions.

    Turn it upside down and that -1 should change to +1.

    Lay it on it's side and that +1 becomes zero and some other axis becomes +/-1

    As noted above, these readings will be static if your bot is not moving. If it were to accelerate forward it would register a sideways acceleration and your estimate of vertical would be ruined.

    With a gyro you would be able to tell that the bot did not actually rotate and that it was only accelerating sideways.

    Mixing these measurements together to get accurate measurements of actual orientation, acceleration etc is what things like the Kalman filter are all about.

    A black art that I am only now trying to get my head around. See here:




  • Zap-oZap-o Posts: 452
    edited 2017-03-02 00:12
    Real quickly what values can I expect as a final answer?

    Here is my code
    
    Pub Calc_gaxl   
    
      gyroAngle := Lsm_Data[1] 'gyro x                          
      acclAngle := F32.atan2(Lsm_Data[5],Lsm_Data[4]) 'accel y,z     
      angle := F32.Fdiv(gyroAngle,10.0) '10 = ms  
      angle := F32.Fadd(F32.Fmul(angle,0.95),F32.Fmul(acclAngle,0.05))
    
    
  • Short version, probably the wrong answer. :)

    It's important that you work in consistent units. Since F32.Atan() is probably returning radians, you'll need to make sure your gyroAngle value is translated into radians / sec before the code you posted gets to it, and then the / 10.0ms will need to be converted to / 100 (update rate), or * 0.01 (scaled to seconds)

    You're also overwriting the current angle value with the gyro value, and you need to add to it, like this:
    angle := F32.Fadd( angle, F32.Fdiv(gyroAngle, 100.0 )) '100 updates/sec
    
    angle is a running total of all the little fragments of rotation rate being accumulated to get a result. Then you correct it by mixing in a little of the computed accel angle.
Sign In or Register to comment.