hitechnic Gyro sensor (NGY1044) noise

Discussion specific to the intelligent brick, sensors, motors, and more.
timpattinson
Posts: 224
Joined: 30 Oct 2010, 04:10
Location: 127.0.0.1
Contact:

Re: hitechnic Gyro sensor (NGY1044) noise

Post by timpattinson »

Code: Select all

float FindOffset()
{
     float tot = 0;
    repeat (1000)
    {
        tot += SensorHTGyro(S1, 0); //tot var is 1000 gyro readings
    }
    PlayTone(440,500);
    return tot / 1000;   // returns avg
}
Last edited by timpattinson on 07 Jul 2011, 10:18, edited 1 time in total.
Commit to Lego Mindstorms StackExchange Q&A http://area51.stackexchange.com/proposals/4105
Minboards IRC Channel #mindboards on Freenode
My blog: http://timpattinson.wordpress.com/
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: hitechnic Gyro sensor (NGY1044) noise

Post by HaWe »

Thank you, I tried this just immediately, but GyroHeading is still increasing constantly although all stands still (about up to 5° per minute), just similarily as before :(
mightor
Site Admin
Posts: 1079
Joined: 25 Sep 2010, 15:02
Location: Rotterdam, Netherlands
Contact:

Re: hitechnic Gyro sensor (NGY1044) noise

Post by mightor »

Did you consider using a float instead of an int?

- Xander
| My Blog: I'd Rather Be Building Robots (http://botbench.com)
| RobotC 3rd Party Driver Suite: (http://rdpartyrobotcdr.sourceforge.net)
| Some people, when confronted with a problem, think, "I know, I'll use threads,"
| and then two they hav erpoblesms. (@nedbat)
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: hitechnic Gyro sensor (NGY1044) noise

Post by HaWe »

surely, but SensorHTGyro needs an integer for GyroOffset to get passed to, I guess that's why.
To my observation the Offset should be somewhere between 4.0..5.0
But
GyroValue=SensorHTGyro(port, 5) is too high => increasing integral
GyroValue=SensorHTGyro(port, 4) is too low => decreasing integral

Or do I miss anything?
mightor
Site Admin
Posts: 1079
Joined: 25 Sep 2010, 15:02
Location: Rotterdam, Netherlands
Contact:

Re: hitechnic Gyro sensor (NGY1044) noise

Post by mightor »

Make your own function that grabs the analogue value from the gyro and subtract the float average. If you are integrating this may make all the difference between a 1 and 5 degree/minute drift.

- Xander
| My Blog: I'd Rather Be Building Robots (http://botbench.com)
| RobotC 3rd Party Driver Suite: (http://rdpartyrobotcdr.sourceforge.net)
| Some people, when confronted with a problem, think, "I know, I'll use threads,"
| and then two they hav erpoblesms. (@nedbat)
linusa
Posts: 228
Joined: 16 Oct 2010, 11:44
Location: Aachen, Germany
Contact:

Re: hitechnic Gyro sensor (NGY1044) noise

Post by linusa »

The gyro offsets are all different for each production unit (their offsets probably follow some statistical distribution). We had problems with gyro drift as well, sometimes it stabilizes after a minute, sometimes it doesn't. I think environmental temperature was one of the influences.

The best approach is to take a lot of samples, but not too rapidly. I.e. maybe 200 samples from 20 seconds, during which the sensor must be at full rest. Calc mean and standard deviation and use the mean as offset. Repeat this process after one minute and see if mean and standard dev. changed. The sensor might stabilize after some minutes of use...
RWTH - Mindstorms NXT Toolbox for MATLAB
state of the art in nxt remote control programming
http://www.mindstorms.rwth-aachen.de
MotorControl now also in Python, .net, and Mathematica
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: hitechnic Gyro sensor (NGY1044) noise

Post by HaWe »

Xander, my friend, you nailed it! ^^
Now I finally understood what's all about the offset that has to be passed to SensorHTGyro reading (I always was curious about that).
Now it's fixed! :big_thumb:

(edit: improved version, bug fixed)

Code: Select all

//--------------------------------------------------
// IO functions, sensors
//--------------------------------------------------

#define Menc(a) MotorRotationCount(a)

#define Beep(f,d) PlayTone(f,d)

#define printf1( _x, _y, _format1, _value1) { \
  string sval1 = FormatNum(_format1, _value1); \
  TextOut(_x, _y, sval1); \
}

const char LCDline[]={56,48,40,32,24,16,8,0};

const string clrln="                 ";

inline bool btnhit(){
   return ( ButtonPressed(BTN1, false) || ButtonPressed(BTN2, false)
         || ButtonPressed(BTN3, false) || ButtonPressed(BTN4, false));
}


void PressToContinue(char Button) {
   string msg;
   if (Button==BTNCENTER)   msg="press BtnCntr...";
   else
   if (Button==BTNEXIT)     msg="press BtnExit...";
   else
   if (Button==BTNRIGHT)    msg="press BtnRight...";
   else
   if (Button==BTNLEFT)     msg="press BtnLeft...";

   printf1(0,LCDline[7],"%s", msg);
   while (!ButtonPressed(Button, false)); while (btnhit());
}

//--------------------------------------------------
// math
//--------------------------------------------------

#define min(a,b) (a<b?a:b)

#define max(a,b) (a>b?a:b)


inline long round(float f)
{
  if (f>=0) return (f + 0.5);
  else  return (f - 0.5);
}

inline float ArrayMedianF(float src[], int len)
{
  float ftemp[];

  ArraySort(ftemp, src, NA, NA)
  return ftemp[(len-1)/2];
}


inline void ArrayPushF(float &src[], float _new, int len)
{
  for (int i=len; i>0; --i) {src[i]=src[i-1];} // shift up
  src[0]=_new;
}


//--------------------------------------------------
// sensors
//--------------------------------------------------

#define GYRO    S2
#define COMPASS S3

long  GyroHeading,
      CompHeading, CompOffset,
      MencHeading ;
float GyroOffset=0.0,  GyroValue, GyroIntegral;


//--------------------------------------------------
// sensor calibration
//--------------------------------------------------

void FindGyroOffset()
{
    float tot = 0;
    for (int i=0; i<500; ++i)
    {
       tot += SensorHTGyro(GYRO, 0); // tot var is 500 gyro readings
       if (!(i%100)) Beep(1760,10);
       Wait(5);                     // Wait 5 ms (analog sensor)
    }
    PlayTone(440,100);
    GyroOffset= (tot/500);           //  avg
}


//------------------------------------------------------------------------------


task GetRotation(){

  long  GyroCalib=10500, temp;
  float gyrodata[5];
  
  CompHeading=CompOffset=SensorHTCompass(COMPASS);

  FindGyroOffset();           // approximation of Gyro Offset

  temp=0;
  GyroIntegral=0;

  while(1) {
     GyroValue=SensorHTGyro(GYRO,0)-GyroOffset;
     ArrayPushF(gyrodata, GyroValue, 5);
     GyroValue= (ArrayMean(gyrodata, 0, 5));

     GyroIntegral+=GyroValue;

     GyroHdg=round(GyroIntegral*(360.0/GyroCalib));

     if (ButtonPressed(BTNLEFT, false)) {   // press  BTNLEFT:
        GyroIntegral=0;                     // reset GyroIntegral
        while (btnhit()); Beep(1000,10);
                                            // now turn robot 360°
     }                                      // then press BTNRIGHT:
     if (ButtonPressed(BTNRIGHT, false)) {  // reset GyroCalib after 360° turn
        GyroCalib=abs(GyroIntegral);
        while (btnhit());  Beep(1000,10);
     }

     while (GyroHdg>=360) GyroHdg-=360;
     while (GyroHdg<  0)  GyroHdg+=360;
     
     CompHeading=SensorHTCompass(COMPASS);
     
     Wait(20);
  }
}

task DisplayValues() {
  while (1) {
     printf1(0, 56, "mot_B%6d", Menc(OUT_B));
     printf1(0, 48, "mot_C%6d", Menc(OUT_C));

     printf1(0, 40, "GValu%6.1f", GyroValue);
     printf1(0, 32, "GIntg%6.1f", GyroIntegral);
     printf1(0, 24, "GOffs%6.1f", GyroOffset);

     printf1(0, 16, "MotoH%6d", MencHeading);
     printf1(0,  8, "CompH%6d", CompHeading);
     printf1(0,  0, "GyroH%6d", GyroHeading);
     Wait(10);
  }
}

task main(){

  SetSensorHTGyro(GYRO);
  SetSensorLowspeed(COMPASS);

  start DisplayValues;
  start GetRotation;

  while(1);
}


Last edited by HaWe on 08 Jul 2011, 14:59, edited 3 times in total.
mightor
Site Admin
Posts: 1079
Joined: 25 Sep 2010, 15:02
Location: Rotterdam, Netherlands
Contact:

Re: hitechnic Gyro sensor (NGY1044) noise

Post by mightor »

Glad I was able to help :)

- Xander
| My Blog: I'd Rather Be Building Robots (http://botbench.com)
| RobotC 3rd Party Driver Suite: (http://rdpartyrobotcdr.sourceforge.net)
| Some people, when confronted with a problem, think, "I know, I'll use threads,"
| and then two they hav erpoblesms. (@nedbat)
afanofosc
Site Admin
Posts: 1256
Joined: 26 Sep 2010, 19:36
Location: Nashville, TN
Contact:

Re: hitechnic Gyro sensor (NGY1044) noise

Post by afanofosc »

BTW, the Gyro sensor is an analog device - so your comment about waiting 20 ms in FindGyroOffset doesn't make sense.

John Hansen
Multi-platform LEGO MINDSTORMS programming
http://bricxcc.sourceforge.net/
mattallen37
Posts: 1818
Joined: 02 Oct 2010, 02:19
Location: Michigan USA
Contact:

Re: hitechnic Gyro sensor (NGY1044) noise

Post by mattallen37 »

You should also note, that some "drift" is actually very correct. The earth rotates 360*/24 hours (once a day). That means that you should see a "drift" of 1 degree every 4 minutes. However, if the axis of the gyro is perfectly parallel to the axis of the earth, you should see no "drift".

In the case of the HT Gyro, and most other hobby gyros, this would be of almost no consequence. Almost all micro gyros (IC gyros) are based on relative position (rate of rotation), and not absolute position. Just about any filter should discard this small effect as an error.
Matt
http://mattallen37.wordpress.com/

I'm all for gun control... that's why I use both hands when shooting ;)
Post Reply

Who is online

Users browsing this forum: No registered users and 3 guests