Inertial Sensor reading is slow

Hello everybody,

I have been having problems with the brain inertial heading sensor. It is slow to deliver accurate heading readings.

I am using it for an accurate autonomous turn program where the robot keeps turning and checking the sensor until it reaches the required heading. It always overshoots. When I started to fine-tune it, I thought it was the inertia of the heavy robot. But then, I added debugging and noticed that the real problem is that the sensor is slow to report accurate readings.

For example, when you want to turn 45 degrees, the robot will turn actually 55 degrees, but the display (rotation) reports 45 degrees. But then if you add a wait( 1 second) it now shows the correct 55 degrees. It needs 1-1.5 seconds to report an accurate heading.

Does anybody else experience this or is my Gen 2 robot brain defective?

Thanks, A.T

perhaps post the code showing how/when you ask for inertial sensor heading and display it. There should be no significant delay in receiving values from that sensor.

2 Likes

Here it is

void turn(double heading) {
//turns so many degrees  
  double d = heading - BrainInertial.rotation(degrees);
  double approx_degree = 2; //close enough, stop turning
  double slow_speed = 7; //percent
  double fast_speed = 40; //percent
  double timeout = 3; //seconds
  double heading_error = 27; //degrees
  

  Brain.Timer.reset();
  BrainInertial.setRotation(0, degrees);

  while (abs(d) > heading_error && Brain.Timer.value() < timeout) {
    d = heading - BrainInertial.rotation(degrees);
    Drivetrain.setTurnVelocity(fast_speed, percent);
    if (d > 0) 
      Drivetrain.turn(right);
    else 
      Drivetrain.turn(left);
  }
  Drivetrain.stop();
  wait(0.5,seconds);//because heading reading is slow, need to wait to get accurate reading
  heading_error = heading - Drivetrain.heading(degrees);
  
  //precise run, correcting for slow heading reading, at slower speed
  Brain.Timer.reset();
  d = heading_error; 
  while (abs(d) > approx_degree && Brain.Timer.value() < timeout) {
    d = heading - BrainInertial.rotation(degrees);
    Drivetrain.setTurnVelocity(slow_speed, percent);
    if (d > 0) 
      Drivetrain.turn(right);
    else 
      Drivetrain.turn(left);
  }
  Drivetrain.stop();
}

void turn_to(double heading){
  double d = BrainInertial.heading(degrees);   //turn to a compass specific heading
  if (d > 180){
    d = d-360;
  }
  d = heading - d;
  turn(d);
}

I think our guys have found that turn overshoot is pretty normal. You can adjust your code to stop the turn several degrees before reaching the desired heading so that the result is close to what you need. There are several YouTubes that discuss such code as well as related code to drive straight.

Yes, but that is a very inconsistent method of solving the problem, but do you also experience delays in the brain inertial readings or is the Gen 2 brain of my robot defective?

thank you, A.T.

Part of the problem is that even with instantaneous reads of the sensor, the robot cannot actually stop instantaneously. The robot has inertia, the heavier the robot the heavier the inertia.

Unless you’re doing things to slow the robot as it gets closer (PID-like behavior), the robot will by definition overshoot. Or, account for the overshoot at a given velocity and subtract that off your desired turn.

2 Likes

Well, I’m not sure ā€œvery inconsistentā€ is true but the turns certainly are not perfect. There are a number of variables including battery charge levels, motor performance over time, wheel friction, and so forth. The code our guys use provides for parameters to adjust the value to allow compensation for a certain amount of inertia at a particular turn speed. That, plus a bunch of trial and adjustment, will get close.

Our guys also use a proportional control to have the robot drive straight which does a pretty good job of keeping the robot on a particular heading. In most instances, this drive straight code executes after a turn so the combination of the turn code and the drive straight code does a pretty good job of getting the robot to a desired heading.

Again, this sort of code is pretty well described in various sources.

I see you are forcing the robot to wait half a second every loop iteration:

wait(0.5,seconds); //because heading reading is slow, need to wait to get accurate reading
void turn_to(double heading){
  double d = BrainInertial.heading(degrees);   //turn to a compass specific heading
  if (d > 180){
    d = d-360;
  }
  d = heading - d;
  turn(d);
}

The heading reading is ā€˜slow’ because you are making it slow. It will help a lot if you replaced this delay with something much more reasonable… like… wait(20, msec);.

Perhaps, if you can implement a PID as EngineerMike mentions, your overshooting problem will be much less significant.

I can promise you the problem isn’t the sensor:

1 Like

Also, I forgot to mention… nice job on your code! Compared to some other code I have seen (and personally wrote… :laughing: ) your code is pretty clean. And thank you for commenting your code; without comments, helping debug code is near to impossible.

Good luck with your programming. :+1:

2 Likes

I am slowing down the robot as it’s getting closer to the target, and a constant speed test program I tried confirmed that the sensor isn’t the problem, the inertia of the robot is because at higher speeds there is a higher average error from the heading.

So unfortunately, even with the slow down and all the fancy algorithms, the program is still not 1000% accurate unless it takes 30 seconds to complete. Thank you!

thanks, A.T

Try adding a 20ms delay to your inner loop. You won’t get faster updates from the gyro anyway and you’d at least free up CPU resources for other aspects of the OS.

1 Like

:point_up_2:
This is actually a really important thing to try. I missed that on my first look-through, good catch @nenik !

1 Like

Man, I wish we could still edit posts…
I just realized I made a mistake in my post.
Oh well…

1 Like

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.