PROS inertial sensor position tracking

I am trying to write a position tracking code in PROS with the v5 imu. So far I am using:

x_pos += ((inertial.get_accel().x - 0.92) / 2);
pros::delay(50);

in a loop. x_pos is supposed to be in meters, but the value is both incorrect and drifts horribly! Any ideas?

The vex IMU is not capable of being used to track the position of the robot as a standalone sensor. The IMU lacks a 3 axis magnetic field sensor. It would be possible (with very high error and low repeatability) to track with an absolute orientation sensor so I would suggest using the IMEs and the IMU for turning.

What is IME and IMU
20 characters

IME = Internal/Integrated Motor Encoder, i.e. the encoders that are part of V5 motors.
IMU = Inertial Measurement Unit, i.e. the new inertial sensor from VEX.

2 Likes

So I’d like to start by asking how you came up with this formula, then we can start discussing why it doesn’t work. Why is it the structure that it is? Where did the values 0.92 and 2 come from? Etc.

2 Likes

Inertial Sensor Returning Incorrect Values for Accleration

tl;dr don’t do what you are doing because we don’t have sensors that accurate yet. Use the sensors in the motors or mount encoders on your wheels because they are accurate and precise

The ideas not bad but the inertial sensor is not good enough for what u want. Ideally you would use 3 separate encoders in order to create odometers but if that’s not viable you could make it work with the built in v5 motor encoders and an inertial sensor. I had something similar created a while ago and it worked fairly well. The only issue you would have is that the inertial sensors value varies quite a bit which creates a lot of error in your coordinates. What you would have to do is find a way to lower the variance and then you would have a very well working Odom.

I’ll respond again just to try to get this in before the thread gets forgotten.

There are a few issues with your code:

  • I’m not sure what you’re expecting subtracting 0.92 and dividing by 2 to do, but that’s not how you convert acceleration to change in position. What you’re actually looking for is integrating using Riemann sums twice (once to get the velocity, and then again to get the position); you can find plenty of online examples of this. Also in general, a way to sanity-check the math that you’re putting in is dimensional analysis. Right now, you’re saying that acceleration values, divided by 2, are position values - this does not work. You need to multiply by time twice somewhere along the line, which is what happens with the integration approach.
  • The X-axis of the IMU is not the X-axis of the coordinate system which you are trying to use for tracking. In particular, if the robot rotates, then the IMU’s coordinate system rotates with it; you probably don’t want this to happen. So, you need to take into account the robot’s orientation information (which you can also get from the IMU), to reverse this effect so that you’re integrating acceleration values that have consistent coordinate systems. There’s plenty of online math available about rotating vectors.
  • Finally, sorry to burst your bubble, but this simply won’t work. The V5 IMU, as with any IMU that’s not worth a couple thousand dollars, is nowhere near accurate enough to give you useful position data from acceleration; it will very quickly start to drift. The reason is that any inaccuracy in the acceleration data—which there will be, we don’t have infinite accuracy nor precision—will accumulate, causing a persistent error in the velocity data (the output of the first stage, and input to the second stage, of integration). If you persistently think that the velocity is slightly different than in actually is, then over time it will accumulate more and more error in position, even if the IMU’s acceleration data is now fine.

With these things established, my advice would be to use the IMU only for its orientation data; that should be consistent enough for most VEX usage. To track the linear motion of the robot, you can use the encoders in your drive motors, though those are susceptible to inaccuracy caused by wheel slippage and related issues. The best solution there is to use separate, unpowered encoder wheels (aka “tracking wheels”) with external encoders on them. This mitigates all the problems you’ll run into with your current situation.

That being said, do go ahead and try to get it working with the IMU. That’ll be a valuable experience in working with IMU data, and will give you a good intuition for what it can and cannot be used for.

9 Likes

Just as a minor note. I agree with everything else you said.
Their xpos += is acting as one layer of integration.

So if

1.they never rotated
2.the Imu was very accurate
3.their 0.92 was some bias term tuned reasonably.
4. They stopped dividing by 2 (which I imagine is them trying to do the equation x=(a/2)*t^2 which is flawed in several ways.
5.multiplied by dt

xpos would be the velocity of the robot.

2 Likes

This isn’t the full code, it is just one that returns the position along the x-axis if the IMU was not turned in any way. As for the strange formula:

The 2 is because it should return in m/s and the loop runs every 50ms, meaning this would have to be 20, but for some reason the scaling factor make it return 1 if accelerating at 10m/s^2 so I divided it by 10. The 0.92 is the approximate value that the sensor returns when motionless!

Thank you for the point about the unreliability of the IMU for position tracking, I will stick to IME’s for now!

This logic doesn’t make sense. Firstly, it’s not m/s, it’s m/s^2. Secondly, I’d really suggest not trying to come up with the correct formula empirically (i.e. by looking at the raw data and trying to figure out what it means and what numbers you need), as you already know what the values mean. You yourself already pointed out at least 2 reasons why your formula doesn’t make sense—that should be a red flag as to why it probably won’t work.

2 Likes

I meant that the value I am trying to get should be in m, not m/s. The IMU measures in m/s^2 but I am trying to get a distance value. Anyway, thanks for the help, I’m not going to use it for position tracking now.

well for starters you need to have a variable tracking the velocity, add the time integral of the acceleration to that, and then add the time integral of that to the position.

Is that not what I’m doing already? Or did I misunderstand you?

Okay so lets do some math together. Assuming the accel as some constant bias term but is scaled correctly. (some IMUs prefer to give units in Gs instead of m/s^2 and docs from cursory glance don’t specify)

//setup
velX = poseX = 0
dt = 0.050 // 50 ms
bias = calculateBias()

//in loop
velX += (getAccelX()-bias)*dt
poseX += velX*dt
sleep(dt)

In theory does what you want. In general if you want people to understand your math at all I would suggest naming and documenting intermediate steps. For example @nickmertin can read my math above and at the very least understand what I think I am doing. He could quickly tell me if I made a mistake.

Also for anyone learning calculus this is just a left Riemann sum approximation of integration. Making the code above do a trapezoid sum is left as an exercise for the reader.

4 Likes