I've looking to build an Arduino based cruise control for a home built piece of farm equipment. I have a large servo installed to control the throttle and tapped into the transmission for its output speed signal. There will be varying load as we drive across the field and varying set points. What kind of control system would you recommend?
I've been playing with the PID library by Brett Beauregard, inputting the speed signal as frequency and outputting to my servo. I can get a decent tune at a particular speed/load but if either of those change then I get oscillations. I am by no means an expert but I'm wondering if a pid controller is the correct system to use because it's not a very predictable plant/system.
Yes, it is the correct thing to use. So long as you don't have gigantic changes, such as attempting to control speed between 1kph and 100kph. Most cars won't engage the cruise control below 40kph because the system is tuned to work best at 60-100.
If you can control the tractor at 5kph then it should be OK at other speeds close to that. If not, you need to do more work on the system.
Do You know the way PID works?
P stands for Proportional, the difference between wanted speed and actual speed. It is multiplied by a koefficient.
I stands for Integration. It collects a long time difference of P. Also multiplied by another koefficient.
D stands for the Derivate, the speed of the P difference. Also multiplied by a third koefficient.
Pk1 + Ik2 -D*k3......
The PID has to be tuned. Perhaps the PIDAutotuneLibrary would help.
https://playground.arduino.cc/Code/PIDAutotuneLibrary
A heavy piece of machinery (especially if it is pulling a very resistive load) will react very quickly to obstacles and will take a considerable time to recover its speed. A human driver will be able to see forthcoming problems (such as hills or soft ground) and make anticipatory corrections to the controls. No Arduino PID system will have that ability.
If it can be done safely (perhaps with an assistant) you may learn a lot from controlling the machine's throttle yourself with your eyes closed.
...R
Robin2:
A heavy piece of machinery (especially if it is pulling a very resistive load) will react very quickly to obstacles and will take a considerable time to recover its speed.
That is important. Accelerating takes much more movement of the gas pedal than decelerating at the same rate.
In other words, your system is asymmetrical. If the actual value is lower than the setpoint (tractor too slow), your need aggressive( big) PI values.
If the actual value is bigger than the setpoint (tractor too fast), you need gentle (small) PI values.
Another point:
The system behaves differently, depending on which gear you are using. While in low gear, little changes of the gas pedal produce big changes in acceleration -> small PI values needed
While in high gear, you need to press the pedal much more, in order to change speed at the same rate. -> high PI values needed.
Also you can reduce oscillations by allowing a certain tolerance, say +- 1 km/h. Within this tolerance, the output (gaspedal) would stay the same.
pseudo-code:
if ( abs(error) < 1 km/h) // within tolerance
error = 0; // an error of 0 will leave the output unchanged.
Thomas
Thanks for the suggestions. Sounds like I'll have to setup an interpolation of sorts for different tuning parameters depending on the speed, load & above/below target.
In other words, your system is asymmetrical. If the actual value is lower than the setpoint (tractor too slow), your need aggressive( big) PI values.
If the actual value is bigger than the setpoint (tractor too fast), you need gentle (small) PI values.
Just to add: this is something you can set in code on the fly.
Based on the gear and whether your speed is higher or lower than the setpoint you can make changes to the P, I and D settings of your PID.
Yours is definitely the correct approach, but properly tuning a PID can be really tricky and take some trial and error.
Railroader:
Pk1 + Ik2 -D*k3......
The last sign should be positive, right? This assuming k1, k2 and k3 are not negative values, and 'P' is the 'time domain error signal', 'I' is the integral of the time domain error signal, and 'D' is the derivative of the time domain error signal.