Part 2:: Line following robot :: code guideline arduino using PID

Now on to finding the set point, place your bot on the dead center of the line. The position or the third column of the readings above will give you your ‘set point’. Note it down separately.
If you have time,verify the set point before your final run, more on this will come up in the tuning section.

Now we’ll build the complete PID algorithm.
We start with calculation of the sensor sum and average similar to code in the part1. Note the next few segments of code are not complete. You’ll have to finish them yourself.


sensors_average = 0;
sensors_sum = 0;
for (int i = 0; i < 5; i++){
sensors[i] = analogRead(i);

sensors_average += sensors[i] * i * 1000;     //Calculating the weighted mean of the sensor readings.
sensors_sum += int(sensors[i]); //Calculating sum of sensor readings.

}

void pid_calc(){
position = int(sensors_average / sensors_sum);
proportional = position – set_point;      // Replace set_point by your set point
integral = integral + proportional;
derivative = proportional - last_proportional;
last_proportional = proportional;

error_value = int(proportional * Kp + integral * Ki + derivative * Kd);
}

The above formula for calculation of error value is the functional definition of PID control. Notice youhave to define the values of Kp, Ki and Kd in the code somewhere. After calculating the value of error,we need to tell the motor to move such that the error is minimized.

void calc_turn(){  //Restricting the error value between +256.
if (error_value< -256){ error_value = -256;     } if (error_value> 256){
error_value = 256;
    }

// If error_value is less than zero calculate right turn speed values
if (error_value< 0){
right_speed = max_speed + error_value;
left_speed = max_speed;
    }

// Iferror_value is greater than zero calculate left turn values

else{
right_speed = max_speed;
left_speed = max_speed - error_value;
    }
}

The above code snippet assumes you’re using the differential drive system, where you execute a left turn if you reduce the speed of your left motor and a right turn if you reduce the speed of the right motor. We use a value max_speed that has to be defined by you right in the beginning to control the peed of the motor. The maximum value of this is 256, which corresponds to the maximum output of the 8 bit DAC converter on the Arduino.

Now we have only one job left to do, to run the motors! So let’s define a function which does exactly that. ‘motor_right’ and ‘motor_left’ are the pin numbers at which your motors are connected via the motor driver. Remember to use PWM pins.

void motor_drive(intright_speed, intleft_speed){
// Drive motors according to the calculated values for a turn
analogWrite(motor_right, right_speed);
analogWrite(motor_left, left_speed);
delay(50);           // Optional
}

IMPORTANTIf you’re motors don’t run at the same speed, meaning it veers to aside even with both motors get the same power, add a line of code to correct it. This is a rare case, but it may happen nevertheless!

Say your left motor moves faster than your right motor, add this before the analogWrite().
Left_speed = left_speed–20;

The ‘20’ is a random number, and you should set it depending on your motors. Just set the values and do a test run if its still not approximately same add subtract accordingly till you have a more or less syncdmotors(i.e they run at  approx. the same speed).

Put the functions together, and use this statement in the loop section.

void loop(){
sensors_read();  //Reads sensor values and computes sensor sum and weighted average
pid_calc();      //Calculates position[set point] and computes Kp,Ki and Kd
calc_turn();     //Computes the error to be corrected
motor_drive(right_speed, left_speed);  //Sends PWM signals to the motors
}

Tuning

The most important parts of your algorithm are the three PID constants, Kp, Ki and Kd. They control the calculation of error and therefore affect the speed of the motors. PID is widely used industrially, and there are many techniques to tune PID. Here we’ll use the trial and error method, though painstaking, isthe easiest to use.We need to manually set the values of the PID constants, so double check your robot and make sure everything is working and your batteries are charged. Your bot has a lot of track to cover.
  1. Set all three constants to zero. Run the robot and see how it handles.
  2. Vary the values of Kp, Ki and Kd in that order, one at a time and test your robot.
  3. Do step 2 over and over again to get your bot perfectly tuned.
This also involves burning the code into the Arduino many, many times! I’ve tried to send values to the Arduino while the bot is running via the serial port. I’d even asked for help in the forums, but I could not implement it in the short time I had. If you do manage a simpler method please let me know.

Fast tuning is important because each track may require different PID constants, and to tune it differently each time is lengthy. You may not even get the time needed if you’re competing in a competition. What I finally managed to implement was a push-button entry system and a LCD display to help faster tuning.

Here’s the segment of code responsible for this. This runs only once in the beginning because I called the function in the setup(). Pressing the reset button on the Arduino will call this again. Read up the Arduino tutorial on LCD display integration first. This uses some functions for display manipulations you need to understand.

The LCD will need many digital output pins. You can use any of the ones, leaving 2 PWM pins for motor control and 2 digital pins for direction control (if you’re using it).
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: