Consider a standard tank-style drivetrain with encoders mounted on each side along with a gyro. When developing a method for driving straight to a desired distance, a sensible approach would be to use the encoders to track the distance traveled and the gyro to ensure the robot maintains heading. Under this setup, is it best to use the min, max or average of the two encoder values to represent your distance? Is there another option which is better than any of these?
Here are my thoughts:
Min: This ensures that both encoders have reached the setpoint. Assuming the encoders represent very close to real world distances, this would lead to an overshoot.
Max: This likely will result in only one of the encoders reaching the setpoint (not accounting for coasting). This would likely lead to an undershoot.
Average: This ensures either both will be exactly on target OR one will be over and one will be under. I have a hard time imagining what this implies, probably depends heavily on implementation details.
You can also run them separately. When one side gets to the right distance, it stops. When the other side gets there, stop that one. Basically, run them independently.
We use the average. One issue we have had a few times is that one encoder was not functioning correctly and so we ended up going twice as far as we intended. It should be possible to detect that condition and correct for it (average of all functioning encoders?), but we haven’t coded that yet.
This is how we initially had our system configured before adding a gyro. We used two PID controllers to control the left and right side respectively. Due to slight differences in speed on the left and right side (i.e. sending a .8 on the left is equivalent to sending a .7 on the right [made up numbers but you get the idea]), we found the robot drifted a little bit before reaching its setpoint.
Thinking about this more though, shouldn’t that issue be something the PID controllers solve? If the right value is approaching the setpoint faster than the left, it should slow down sooner and the left should catch up resulting in a straight movement. You’ve got me thinking…
When both encoders worked correctly, did you find you were reaching, undershooting, or overshooting your destination? If you told the robot to drive 5 feet, were you consistently under, over, or within an acceptable tolerance of 5 feet?
The aforementioned method of controlling the left and right independently WILL guarantee that the drivetrain ends with the same heading as it started with and that it will have traveled a path that is equal to the desired distance, but it WILL NOT guarantee it maintains the heading for the duration of its movement, resulting in non-straight movement.
To get a straight movement, we would need to control the left and right sides identically (I assume this means ensure the same speeds on both sides throughout the duration of the command)
To ensure both sides move identically using just encoders seems like it might be difficult. Though I’d be interested in approaches to do this and will search around for it.
These things considered, we don’t need to only use encoders as we have a gyro to help out. Maintaining heading with a gyro is relatively easy especially when paired with the RobotDrive functions available to us. Given a function that drives straight at a speed, what is a good way to ensure it has traveled the distance you wanted to given data from two encoders?
We are able to consistently hit our target, but that has more to do with our method of controlling acceleration, I think. We gradually accelerate up to our max speed, then begin slowing down when we are at a distance proportional to the distance we traveled while accelerating. We just needed to tune that proportion constant. Before we were doing that, the amount of jerk we would get from uncontrolled acceleration and deceleration made tolerances too large.
We do find that the gyro stabilization does a good job at keeping us going straight. Even when one encoder was out, we still traveled mostly straight despite speed control not really working for one side.
This is all still pretty primitive and we continue to investigate various motion profiling techniques, but our simple methods are getting the job done.
This happened to us at Georgian College. One of our encoders was broken and returning intermittent values - the left side would report two feet of travel while the right side would report 0.3 feet.
Our “drive straight” code uses the gyro to lock in a heading and an average of the gyro readings for distance, so the broken gyro manifested as the robot mysteriously travelling too far. Sometimes in dramatic fashion, as we learned during one of our events when the robot, instead of going to the airship, decided to take a scenic detour into the neutral zone. Luckily it decided to crash into the side wall rather than venture into the opponent launchpad, which would have been a large penalty.
I think this encoder failure was gradual as the internal ring started to slip more and more, so we probably didn’t notice until it was dramatically wrong. The problem is that we would have coded around the problem. “Oh, we must have miscalculated the airship distance. Reprogram it to go 8 inches less.” and then “Oh, red side must be slightly different than blue side. Change it again to go a few inches more.” And finally “Wait, how can that be right? The same code is doing different things.” It took a couple of failures on the field before we realized it wasn’t software or measuring error.
So to summarize:
We like to take the average of the two
Taking the average can mask individual sensor errors, so be careful
We plan to set up some tests to run in the pits at each event to test and validate encoder values. Maybe run them both for a known time, or roll by hand for a known distance, and verify that both encoders seem roughly equal.
Yup…since we had that failure, running each side of the drive independently and checking for appropriate feedback via the Smart Dashboard has been added to our pit crew’s system check punch list. Smart of you to include verifying the distance.
“guarantee” is perhaps not the right word here, especially when dealing with a skidsteer vehicle in the real world. slight differences between the left and right sides (alignment, tread wear, etc etc etc) are not included in the math model shown in that post.
it WILL NOT guarantee it maintains the heading for the duration of its movement, resulting in non-straight movement.
Right.
To ensure both sides move identically using just encoders seems like it might be difficult. Though I’d be interested in approaches to do this
Use two separate closed-loop controllers as follows:
control the distance traveled using the average of left and right encoders as your process variable.
control the heading using the difference between the left and right encoders as your process variable.
These things considered, we don’t need to only use encoders as we have a gyro to help out. Maintaining heading with a gyro is relatively easy especially when paired with the RobotDrive functions available to us. Given a function that drives straight at a speed, what is a good way to ensure it has traveled the distance you wanted to given data from two encoders?
Use two separate closed-loop controllers:
control the distance traveled using the average of left and right encoders as your process variable.
control the heading using the gyro as your process variable.
This is the exact problem we ran into and solved it by simply putting a check on the Average distance. Average is 2 added together but we only divide by 2 if both are above 10. This means distance isn’t what you think for the first 10 ticks but there are over 50 in an inch so not an issue at all.
We just average it. This works pretty well, and we are accurate to within about ± 2 inches.
There are obvious reasons not to use the maximum or minimum distances.
If you need to be more accurate than about 2 inches, you can lower the speed that you drive, and that will tighten up your grouping. This may be a problem, however, if you want to give your pilots time to, for example, pull up a gear.
If you really need to have precise and fast control over longer distances, you should implement a motion profile from a trajectory, such that the two sides of the drive train operate independently to follow a path.
(Just realized in my message above I used “gyro” a few too many times when I really meant “encoder”).
The way our students found this was by duct taping two parallel lines in our pit, a known distance away, I believe 2 feet was about all we could get away with in the confines of our pit. Line up the robot with one line, push it till it hits the other line, see what both encoders say.
I have suggested to our students that we could code up a quick auto mode to test in the practice field or at home – have the robot drive forward using one encoder, then backward using the other one. If the robot ends up exactly back where it started, then all is good. If not, then something’s wrong, and the position of the robot will immediately tell us where.