Pages: [1]   Go Down
Author Topic: Need help for building a pid controled robot  (Read 1106 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 16
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi this I have made an arduino line follower. using An arduino dumilave. A 5 ir sensor  array. A 12v and 850ma battery and 300 rpm motors.I am unable to find Kp Ki Kd values and my robot is not at all following the line. This is my code. Pls some  one help

Quote
const int motor3Pin = 3;
 const int motor1Pin = 10;
 const int motor2Pin = 6;
 const int motor4Pin = 11;
int right_speed = 0;
int left_speed = 0;
long sensors[] = {0,0,0,0,0};
long sensors_average = 0;
int sensors_sum = 0;
int posn; //position
int proportional = 0;
long integral = 0;
int derivative = 0;
int last_proportional = 0;
float Kp = 2;  // Havent decided the values yet
float Ki = 2;
float Kd = 2;
int error_value = 0;
int max_speed = 200;
int set_point = 1987;//the posn on the center of line, I have to decide the value yet

void setup(){
   pinMode(motor1Pin, OUTPUT);
  pinMode(motor2Pin, OUTPUT);
  pinMode(motor3Pin, OUTPUT);
  pinMode(motor4Pin, OUTPUT);
  Serial.begin(9600);
}

void read_sensors () {
  for (int i = 0; i < 5; i++) {
  sensors = analogRead(i);
  sensors_average += sensors * i * 1000;
  sensors_sum += int(sensors);
  }
}

void pid_calc () {
  posn = int(sensors_average / sensors_sum);
  proportional = posn - set_point;
  integral = integral + proportional;
  derivative = proportional - last_proportional;
  last_proportional = proportional;
  error_value = int(proportional * Kp + integral * Ki + derivative * Kd);
}

void calc_turn(){
  if (error_value < -256) {
    error_value = -256;
  }
  
  if (error_value > 256) {
    error_value = 256;
  }
  
  if (error_value < 0) {
    right_speed = max_speed + error_value;
    left_speed = max_speed;
  }
  
  else {
    right_speed = max_speed;
    left_speed = max_speed + error_value;
  }
}


void motor_drive (int right_speed, int left_speed) {
  analogWrite(motor1Pin, right_speed);
  analogWrite(motor2Pin, left_speed);
  delay(20);
}

void loop () {
  read_sensors ();
  pid_calc ();
  calc_turn ();
  motor_drive (right_speed, left_speed);
  Serial.print(error_value);
  Serial.print("   ");
  Serial.print(right_speed);
  Serial.print("   ");
  Serial.print(left_speed);
  Serial.println("   ");
}


Thanx
Logged

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 613
Posts: 49338
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
my robot is not at all following the line.
Do you KNOW that the robot is reading the sensors correctly?

Reading the 5 sensors, adding up the values, and determining an average will tell you nothing about where the line is. I think you are barking up the wrong tree. As a matter of fact, I don't think you are even barking in the right forest.
Logged

Offline Offline
Edison Member
*
Karma: 26
Posts: 1339
You do some programming to solve a problem, and some to solve it in a particular language. (CC2)
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Writing a PID algorithm is not the easiest of the jobs. Please have a look at the PID library, and learn to use and tune it.

http://brettbeauregard.com/blog/2011/04/improving-the-beginners-pid-direction/
Logged

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 613
Posts: 49338
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Please have a look at the PID library, and learn to use and tune it.
Good advice - IF you have any kind of good data to drive the PID algorithm.
Logged

Offline Offline
Edison Member
*
Karma: 26
Posts: 1339
You do some programming to solve a problem, and some to solve it in a particular language. (CC2)
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Well, a good advice could have been also "are you _sure_ you need a PID ?".  smiley

What made me jump to that (bookmarked) page, though, was that pid_calc() function...
Logged

the land of sun+snow
Offline Offline
Faraday Member
**
Karma: 159
Posts: 2916
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Seems to me there must have been 10,000 roboticists who have made line-following robots that
never even heard the term PID. Why not try doing it the simple way [differential sensor readings]
FIRST, like everyone else.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 16
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hey my senors are reading correctly and i can differentiate between the set point and other positions. I have built line followers first and they were successful. Now i want to make a high speed and accurate line follower so i have chosen the pid algorithm.

Thanx for ur help the link was useful   
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 302
Posts: 26290
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

OP: could you repost your code please, not using "format for forum" (or whatever it is called), but simply copying the contents of your IDE window, and pasting the result between [code] [/code] tags?

That way, we'll avoid the nonsense of
Code:
void read_sensors () {
  for (int i = 0; i < 5; i++) {
  sensors = analogRead(i);
  sensors_average += sensors * i * 1000;
  sensors_sum += int(sensors);
  }
}
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Offline Offline
Newbie
*
Karma: 0
Posts: 16
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

const int motor3Pin = 3;
 const int motor1Pin = 10;
 const int motor2Pin = 6;
 const int motor4Pin = 11;
int right_speed = 0;
int left_speed = 0;
long sensors[] = {0,0,0,0,0};
long sensors_average = 0;
int sensors_sum = 0;
int posn; //position
int proportional = 0;
long integral = 0;
int derivative = 0;
int last_proportional = 0;
float Kp = 2;  // Havent decided the values yet
float Ki = 2;
float Kd = 2;
int error_value = 0;
int max_speed = 200;
int set_point = 1987;//the posn on the center of line, I have to decide the value yet

void setup(){
   pinMode(motor1Pin, OUTPUT);
  pinMode(motor2Pin, OUTPUT);
  pinMode(motor3Pin, OUTPUT);
  pinMode(motor4Pin, OUTPUT);
  Serial.begin(9600);
}

void read_sensors () {
  for (int i = 0; i < 5; i++) {
  sensors = analogRead(i);
  sensors_average += sensors * i * 1000;
  sensors_sum += int(sensors);
  }
}

void pid_calc () {
  posn = int(sensors_average / sensors_sum);
  proportional = posn - set_point;
  integral = integral + proportional;
  derivative = proportional - last_proportional;
  last_proportional = proportional;
  error_value = int(proportional * Kp + integral * Ki + derivative * Kd);
}

void calc_turn(){
  if (error_value < -256) {
    error_value = -256;
  }
 
  if (error_value > 256) {
    error_value = 256;
  }
 
  if (error_value < 0) {
    right_speed = max_speed + error_value;
    left_speed = max_speed;
  }
 
  else {
    right_speed = max_speed;
    left_speed = max_speed + error_value;
  }
}


void motor_drive (int right_speed, int left_speed) {
  analogWrite(motor1Pin, right_speed);
  analogWrite(motor2Pin, left_speed);
  delay(20);
}

void loop () {
  read_sensors ();
  pid_calc ();
  calc_turn ();
  motor_drive (right_speed, left_speed);
  Serial.print(error_value);
  Serial.print("   ");
  Serial.print(right_speed);
  Serial.print("   ");
  Serial.print(left_speed);
  Serial.println("   ");
}
Logged

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 613
Posts: 49338
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
void read_sensors () {
  for (int i = 0; i < 5; i++) {
  sensors = analogRead(i);
  sensors_average += sensors * i * 1000;
  sensors_sum += int(sensors);
  }
}
Well, that's certainly a lot better.

Since OP can't seem to follow simple directions, it's no real wonder why the robot can't follow a line.
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 302
Posts: 26290
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

OP. Please look at your source code.
Does it contain italics?

No, I thought not.

Please use [code] [/code] tags when posting code - you can either type them, or use the # icon on the editor's toolbar.
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Offline Offline
Newbie
*
Karma: 0
Posts: 16
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
const int motor3Pin = 3;
 const int motor1Pin = 10;
 const int motor2Pin = 6;
 const int motor4Pin = 11;
int right_speed = 0;
int left_speed = 0;
long sensors[] = {0,0,0,0,0};
long sensors_average = 0;
int sensors_sum = 0;
int posn; //position
int proportional = 0;
long integral = 0;
int derivative = 0;
int last_proportional = 0;
float Kp = 2;  // Havent decided the values yet
float Ki = 2;
float Kd = 2;
int error_value = 0;
int max_speed = 200;
int set_point = 1987;//the posn on the center of line, I have to decide the value yet

void setup(){
   pinMode(motor1Pin, OUTPUT);
  pinMode(motor2Pin, OUTPUT);
  pinMode(motor3Pin, OUTPUT);
  pinMode(motor4Pin, OUTPUT);
  Serial.begin(9600);
}

void read_sensors () {
  for (int i = 0; i < 5; i++) {
  sensors[i] = analogRead(i);
  sensors_average += sensors[i] * i * 1000;
  sensors_sum += int(sensors[i]);
  }
}

void pid_calc () {
  posn = int(sensors_average / sensors_sum);
  proportional = posn - set_point;
  integral = integral + proportional;
  derivative = proportional - last_proportional;
  last_proportional = proportional;
  error_value = int(proportional * Kp + integral * Ki + derivative * Kd);
}

void calc_turn(){
  if (error_value < -256) {
    error_value = -256;
  }
 
  if (error_value > 256) {
    error_value = 256;
  }
 
  if (error_value < 0) {
    right_speed = max_speed + error_value;
    left_speed = max_speed;
  }
 
  else {
    right_speed = max_speed;
    left_speed = max_speed + error_value;
  }
}


void motor_drive (int right_speed, int left_speed) {
  analogWrite(motor1Pin, right_speed);
  analogWrite(motor2Pin, left_speed);
  delay(20);
}

void loop () {
  read_sensors ();
  pid_calc ();
  calc_turn ();
  motor_drive (right_speed, left_speed);
  Serial.print(error_value);
  Serial.print("   ");
  Serial.print(right_speed);
  Serial.print("   ");
  Serial.print(left_speed);
  Serial.println("   ");
}
Logged

UK
Offline Offline
Shannon Member
****
Karma: 223
Posts: 12630
-
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The plus here should probably be a minus:
Code:
left_speed = max_speed + error_value;

Is your calculation of posn returning sensible values based on what is in front of your sensors? I guess you're trying to calculate where the 'hot spot' is.

You don't seem to be providing any control over the timing of your PID algorithm. The derivative and integral elements are with respect to time, and I don't see anything to provide a consistent sample rate. Is there some reason you aren't just using the PID library?
Logged

I only provide help via the forum - please do not contact me for private consultancy.

Pages: [1]   Go Up
Jump to: