kirkpthompson wrote:Hi Temp. No, I don't have an example of a line follower implementation using PIDController. Maybe you could provide some specifics on what you are trying to accomplish and we could go from there?

Hi Kirk,

I wanted to make a bot following the black line with the full speed on the map that is included in the Lego NXT 2.0 set. But I can't tune the variables properly.

How to use it:* Deploy PIDLineFollow on the NXT* Start PIDTuner on PC** Now we can read and write variables on the NXT ie.: "read setpoint" or "write kp 11.0" etc.*** Following variables are available: setpoint, deadband, kp, ki, kd, limithigh, limitlow, integrallimitlow, integrallimithigh, integral, lightvalue, travelspeed, rotatespeed, interval** After variable configuration, we can start and stop the lego with "start" or "stop"** After "stop" we can configure variables again** If "exit" called, the NXT is shutdown.

Your PIDController implementation looks semantically correct. I agree, tuning PID loops is tricky. Wikipedia has some good basic info and some common methods and links to other resources and I recommend you have a look at that. http://en.wikipedia.org/wiki/PID_controller#Loop_tuning

I did notice you have a fairly large intial Kp (P) value. Have you tried to start out with a small value (0.1f) and observe behavior during loop execution? Increase the value until you observe oscillation/instability and back it off some. That is a starting point.

Also, you may be adding time to dt by virtue of listening for BT data (I didn't examine that code) and PID loops are time-dependent by definition.

I have been working on a PID tuner class that uses the NXT keys and LCD to provide a tuning interface and like the idea of wireless tuning (in case the brick is swinging around, etc. which makes it hard to read and press keys). It actively runs the PID loop while tuning with manual incremental parameter adjustments which gives immediate feedback during the tuning process. It has low overhead time and CPU-wise so the tuning for parameters doesn't change too drastically when tuning is complete and the tuner reference is removed.

Here is a graph that shows PID control loop instability. Output = MV, actual_position=PV. Notice the excessive proportional response to process disturbance (PV) between 4000 ms and 5200 ms. Try to get the process to respond (it might be a slow response) without oscillation/overshoot and tune the Ki from there. (generally, Ki provides how fast an error is stabilized, Kp provides the "magnitude" or proportional response to error). You can play around with output ramping which will attenuate the response but try to get things fairly stable before you add too many "cooks in the kitchen".

kirkpthompson wrote:...I did notice you have a fairly large intial Kp (P) value. Have you tried to start out with a small value (0.1f) and observe behavior during loop execution? Increase the value until you observe oscillation/instability and back it off some. That is a starting point....

Hallo Kirk,

I have started first with only the KP variable. If I choose the KP < 3.0, the nxt couldn't follow the line (is it called overshoot?). If I choose the KP > 4.0, the nxt oscillated too much. So 3.5 was the middle value. Then I started to set the KI variable according to the Ziegler-Nichols method. But then the integral grows too much. So I must set integral limits. But what are the optimal integral limits? How they are computed?

Hi,A possible problem here is that you may not have a sufficient input range to make the PID control work smoothly. Basically all you have is on line/off line with a very small on the edge section. It may help to scan the sensor over the line using an extra motor, to gather extra data points. In effect by scanning the sensor you create a set of data points rather like the purpose built line leader from Mindsensors.

Hi All. Hope it is not an issue to revive an old thread but is is applicable to the context.

There is now PID Tuning functionality in the SVN snapshot if anyone feels brave enough to test it.

It is one implementation of a new messaging architecture I have been building into NXT Charting Logger (http://bit.ly/IKorbq) and lejos.util.NXTDataLogger that will enable 2-way communication between the PC and NXT via the NXTDataLogger protocol as a tunneled message. This is done simultaneously while the NXTDataLogger/NXJChartingLogger are gathering, sending, logging and charting data.

The vision is when the programmer/user "plugs-in" a type handler in the code (i.e. a PIDtuner instance), the NXJChartingLogger will automatically display the appropriate GUI JPanel in a new tab in the lower tabbed pane on connection. This user interface is then used to get user input and pass it to the NXTDataLogger via a COMMAND_PASSTHROUGH message which then routes it through a message handler singleton which then parses it and routes it to the appropriate MessageTypeHandler (i.e. PIDTuner again). the NXT-to-PC routing basically works the same.

Client (NXT) code example that shows all that is needed to set up a PID tuner for lejos.util.PIDController:

So, I assume you used the snapshot files and ran the NXT Charting Logger tool to see the PID parameters used in your code? I would be interested in seeing the graph that was generated when trying to tune your line follower. As described in previous posts, using PID control for that task may not work well.

It's interesting how using getRawLightValue() from the color sensor as PV works in this case. Very interesting... And, the link you provided is good information. Thanks!

The plot looks right given your tuning params: 1:1 inverse proportional response to error. FYI, an example of using an accelerometer sensor with PID control can be found at http://www.youtube.com/watch?v=qGxGO5YicE4.