Traction control: How do I tune a PID controller with variable gain?

Hi, We are still programming and we are really just getting started on traction control. I understand the traction control scheme that team 121 is using, however I’m not sure how to tune the PI controller that they say they are using. They say that they have a proportional gain that is proportional to the slip ratio. Does anyone have any experience with tuning such a PI controller? If so, what do you suggest I do?

thanks

hmmmm of course you have to work with what sensor feedback you have in your design…but here’s one approach out of many. We have not tried this, but here goes:

Let’s say you can calculate slip ratio.

  1. Pick the ratio you want as the “set point”
  2. find the slip ratio you currently have.
  3. the difference is your error
  4. pick a multiplier (Kp, the proportional gain in controllese)

Kperror becomes the input to you motors, but limit it to -1.<0.<1.
or…Kp
error could be a delta to the last pass motor pwm (better? worse? dunno)

So, the choice of Kp is critical! too big and you get wildly big swings in pwm (unstable control system) and too small and you get no effect. As a swag, I’d guess that an error of twice the slip would need 100% drive…something like 1./slip_ratio_set_point…just guessing

As for the integral term, (the I in PI) keep a running sum of the error and choose a Ki, the term becomes Ki*(sum_error). Add it to Kp*error for your overall output

Output_to_motor = Kperror + Ki(sum_error)

The integral part is tricky. It is good for trimming out long-term biases, but you need to limit how big you want the sum_error to grow or you will experience “integrator wind-up” - really big Integral terms in your output that can adversely effect you controller. Add the fact that this is not a continuously running process - you will be starting and stopping, and and you can guess how wind-up could mess with your driver’s head!

My recommendation would be to try only the P part first and add the I if you really have to. Also, Google PID controller…there’s a wealth of better descriptions out there.

This approach will always drive you to some slip… interesting…even when you want to stop?!?

Eric
PS heh - our programming is never done 'til our last match at the Championship :slight_smile:

Are you using LabVIEW? If so, this would be an excellent opportunity to use some controls and indicators on the front panel of your VI when running in debug mode to allow real-time tweaking of gains to determine effect.

In general (very general), you’ll always want to set Kp as high as possible (typically until the noise becomes unbearable) and then increase Ki until things go unstable. But I stress VERY GENERAL guidelines.

Russ

I worked on tuning a PID control right before we shipped the robot. I didn’t have time to tune it properly, so it’s just a P (proportional) control. However, this produces very satisfying results, so try setting just the P gain and see what you get.

If you’re using LabVIEW, it comes with a PID.vi, take a look at the help for how to use it. Good luck!

Hello,

While I am no expert on our system, I can offer a few pieces of quick advice that will hopefully help you out. First, the advice on tunig PI given above is excellent.

I have two items to add:

First: Be sure that your slip ratio is being calculated correctly. You need to normalize the encoder counts that you get from your drive wheel to be the same that you get from your follower wheel. Often the follower wheel is much smaller than the drive wheel, so you may get more encoder counts per linear distance traveled from the follower that you get out of your drive wheel. (I hope you are using a follower wheel, if you are using an accelerometer you may have problems with noise from vibrations).

Second: Be sure to tune the control gains in a controlled practice environment. If the system is improperly tuned it can hurt your driving performance badly, making the machine tough for your driver to operate. Tunig the gains is a trail and error intensive process where you want to be able to make small changes and then test, lather, rinse and repeat. If you are making changes in your pit between matches then you will likely get unprdictable performance in your matches. Your best bet would be to try and block out some time on the practice field, or maybe somewhere in the pit where you can set up a few sheets fo the floor material to test driving on.

Good luck, I hope your system works well for you!

We were using a similar setup to 121 for version 1 of our traction control code. The only sensory was 4 encoders (2 on driven wheels, 2 on “follower” wheels). I am pretty sure some of the more controllable systems have logic to throttle on current spikes, but I digress… The logic was basically to hold slip to 0 on each wheel when the robot is stopped, allow a little slip on launch, and allow a bunch of slip on turns.

Before you get into tuning the controller, I would analyze your feedback. If the resolution isn’t good enough, you will end up with some noise in slip ratio between cycles. This effect will be made even worse if you are taking percent slip (Vw-Vf/Vw), as you are pushing something big (encoder velocity) into something small (dividing by a velocity), then blowing it up (multiplying by Kp). The end result of this will be uncontrollable “bucking” by your drive wheels. Some nested filters (one on slip ratio, one on motor output) should be able to fix this, but this will involve just another level of tuning.

The method we used to tune our controller was to take off from a stop, and adjust the P gain until acceleration was optimized. We used a set length and timers to do this. We didn’t have enough time to optimize I, but I would probably drive the robot into a large weight and adjust the I gain enough so it can slow down the wheels enough to push it, without overshooting or “bucking”. The I term in this controller, as I understand it, exists for situations just like these where an unexpected external force is applied to the base. Your I gain should be very small in comparison to the P gain. (I want to say about 10^3ish smaller, but I could be wrong)

Good luck.

Good advice. There are some numerical issues with trying to maintain a constant slip ratio. Anytime you are dividing by a sensor reading, I get queasy. As a result, a % slip ratio is unbounded. It could easily be 0 or infinity. You can detect these cases, but like Tom said, expect a very jittery drive as a result. And that’s before trying to solve the problem of turning…

Instead of % slip, trying to limit absolute slip (ex: I want my wheels to go no faster than 1 foot/sec more than my follower wheels) leads to much simpler code that is almost as effective. Or, come up with a “hybrid” approach that uses absolute slip up to a certain point, then percent slip beyond that. This helps you avoid the nastiness of one or both of your encoders giving you a 0 speed.

The main purpose of the I term is for changing the system type and in turn changing the steady state error of the system.

Thank you so much for your responses! Here is more information of our setup.

We are using 4 encoders: 2 on the gearboxes and another 2 on follower wheels. We are also using Labview and its PID libraries.

My approach is to allow a certain amount of slip upon launch by letting the driver command the motors directly, then if the slip ratio goes higher than a specific value the traction control will activate and motor commands will come from the traction control part of the code to bring the slip ratio down under that margin. Once it is under that margin, then the driver can control the motors directly again.

When the robot is at a stop (gearbox velocity=slip ratio=0) the traction control is forced to be off.

Anyways, how does this approach sound? Am I on the right track? I would like to keep my code as simple as possible so that I can arrive at a traction control solution the fastest.

I attached a screenshot of my code.

FYI: PS=port side, SB=starboard. The traction control enable controls a select with the joystick feed in the false case and the traction control feed in the true case.





I’m curious… Will the system shuck as you hand control back and forth between your traction control mode and and driver direct mode?

Your slip will be out of the threshold most of the time with the current algorithm. Unless the joystick values are ramped or rate change limited, you will experience jitter as the slip passes in and out the threshold. This will happen very often. (The slip will drop, wheels will spin out, rinse, repeat.)

I would run the joystick through something like this http://www.chiefdelphi.com/forums/showpost.php?p=833755&postcount=3 before pumping them into your algorithm.

You can overshoot on the ramp gain a bit to allow for a bit of slip in launch, and the slip threshold should catch exceptions when you run into stuff on the field.

Having helped program a bot who’s traction control system works by just reacting to slip, I would disagree. It is better if you have some code to try to prevent slipping by ramping up the output power, but it is not necessary. You can add the ramping code in after you get the basic algorithm working and decide that you want more.

You have no setpoint?

Ya, I realized that after I was testing the code. Thanks! I am testing the code now and will post the revision for your feedback probably in several hours.

Hi, Well I’ve done some testing of the code and for some reason, the values from the PID controllers aren’t being passed into the TeleOp Execute loop to add to the joystick values. I submitted another question to the Labview forum about this

I decided to modify my correction method from a few posts ago to having the PID output always modify the joystick output sent to the controller based on the slip ratio calculated. I attached a pdf of my code so that you can see what I mean.

  1. How does this sound? Is there a better way?

  2. I noticed that the slip ratio goes to infinity a lot, how do you guys deal with the infinity case since it will drive the PID crazy?

    traction_control2.pdf (135 KB)


    traction_control2.pdf (135 KB)

Simply add 1 to the denominator of your ratio before dividing by it. This will elimate your infinity case.

Is pushing the joystick forward negative or positive? I can’t remember.

I only ask because assuming you’re accelerating, you’re adding a positive value to your joystick. I’m curious if you should be adding that positive number, or subtracting it to decrease acceleration.

Forward is negative, so said the HID designer who must have flown planes or been thinking of a flight simulator or something.

Greg McKaskle

Thanks Greg! It wasn’t too intuitive to me as to why forward would be negative so I decided to multiply the getaxis outputs by a -1. This way I could add the traction control PID correction to this value and then submit that value to the motor controller.

On another note, we were able to get our traction control to work for the most part. I will summarize our method and will then outline some problems and ask questions.

Here is a summary for our traction control:
-calculate the slip ratio (driven wheel velocity-follower wheel velocity)/max_velocity. max_velocity=100in/s (for us).
-submit this slip ratio to the process variable of a PID controller.
-P=3 (for us), I=0,D=0
-add the PID output value to the current driver command to correct for slip if needed.

note: the max_velocity used in the slip ratio is defined as the maximum linear velocity of the wheels when the robot is off the ground.

Problems:
1)I am using the slip ratio of 0% instead of the optimum 20%. With my algorithm, there will be always be an error if the robot isn’t moving because slip ratio would be zero in that case.
2)when I floor the joystick forward, traction control works pretty well. Then if I let the joystick go and fly back to center, I get some jerking in the driven wheels. If i were to bring the joystick back slowly, the jerking doesn’t occur.

What am I asking?:

  1. I’m not using sending a variable gain to the PID controller as discussed by team 121. The variable gain would be calculated as K*slip ratio. Is this a good idea? This method would seem to allow me to use a slip ratio setpoint of 20% and not cause an error greater than 0 when the robot isn’t moving.
  2. Should I filter my slip ratio and motor commands somehow? If so should I use a lowpass filter or something similar? Or a rate limiter? I would like to remain simple and effective.
    3)With my current algorithm, if I floor it forward and then floor it backwards, the wheels lockup. This makes sense (PID limits: -1 to 1 and full reverse = -1 command = motor command of 0). I would like the wheels to speed up in the direction the bot is moving and pull the robots speed down. I’m thinking that the variable gain PID method would do this for me. What do you think?

I have a pdf of my code attached if any of you want to dive into the code.

traction_ctrl3.pdf (181 KB)


traction_ctrl3.pdf (181 KB)