OCCRA
Go to Post Because FIRST wants everyone to have a sense of accomplishment even if you didn't accomplish anything during the match. - Koko Ed [more]
Home
Go Back   Chief Delphi > Technical > Programming
CD-Events   CD-Media   CD-Spy   FRC-Spy  
portal register members calendar search Today's Posts Mark Forums Read FAQ rules

 
Closed Thread
Thread Tools Rate Thread Display Modes
  #1   Spotlight this post!  
Unread 03-23-2012, 03:46 PM
tb0508 tb0508 is offline
Registered User
no team
 
Join Date: Mar 2012
Location: United States
Posts: 3
tb0508 is an unknown quantity at this point
PID algorithm using Arduino

I am fairly new to the microcontroller/robotics world. I am currently trying to write/understand the basics of the PID algorithm and notice that I could get by with using only the 'P' algorithm. I understand the basics of it, I am now just trying to write the code for it.

Onto the actual questions. I have a wireless cart(go cart). I have a target pot(attached to steering wheel) and a feedback pot(current position pot) that is attached to the wiper motor.
http://img703.imageshack.us/img703/9...lfrontpots.jpg

What I am trying to do is write my own 'P' algorithm for this to send to the motor controller I have for the wiper motor. I understand the basic equations for the 'P' algorithm and finding the value to send to the motor controller which will interpret it and turn left/right and how fast to turn. What my main concern is what is all involved besides the basic equations. I have just started learning the PID algorithm and have picked up on it well but as a beginner I am still trying to learn more. Any available information on this topic is great, or examples.

I have wrote out a detailed explanation of what I am trying to do involving the pots with equations(error, Turn, etc) and can post that if it helps. Thanks in advance.

Last edited by tb0508 : 03-23-2012 at 09:10 PM.
  #2   Spotlight this post!  
Unread 03-23-2012, 09:21 PM
RyanN's Avatar
RyanN RyanN is offline
RyanN
AKA: Ryan Nazaretian
FRC #0364 (Team Fusion)
Team Role: Mentor
 
Join Date: Jun 2006
Rookie Year: 2005
Location: Gulfport, MS
Posts: 995
RyanN has a reputation beyond reputeRyanN has a reputation beyond reputeRyanN has a reputation beyond reputeRyanN has a reputation beyond reputeRyanN has a reputation beyond reputeRyanN has a reputation beyond reputeRyanN has a reputation beyond reputeRyanN has a reputation beyond reputeRyanN has a reputation beyond reputeRyanN has a reputation beyond reputeRyanN has a reputation beyond repute
Send a message via Skype™ to RyanN
Re: PID algorithm using Arduino

For just P, it's not bad at all.

If you have the equations, then you know this:

Output = Kp * (Target Value - Process Value). What this does is findes the error (TV - PV), then applies a gain Kp to make the motor actually do something, or to calm it down some.

So with the Arduino, I'm assuming you're using a pre-made motor controller, such as a Victor or Jaguar, but since I don't see a team number, I might also assume you're using a different brand. Even so, the likelihood of it taking a PWM value is still high.

In the Arduino library, there's examples on how to run a servo. Most motor controllers that I have ever seen emulate a servo. There's actually an example on how to use a knob (read potentiometer) to control a servo. All you need to do is add in the feedback to the system using that equation above and you'll have yourself a simple P controller.

The I & D parts aren't hard to add either. The hardest part that you'll have is tuning it correctly. Seeing that you're driving a motor for steering, it will be extremely important to have a highly responsive system that does not overshoot or oscillate, as you can lose control.

Oh, by the way. Cool project! I always wanted to do something like that, but never had the time or money to do it in high school, and now I'm more broke than ever being in college. Maybe it can be a fun project for my wife and I do to once we're all finished and have our degrees in Electrical Engineering and Computer Engineering.
__________________
Controls Mentor
firstfusion364.com
  #3   Spotlight this post!  
Unread 03-23-2012, 10:41 PM
tb0508 tb0508 is offline
Registered User
no team
 
Join Date: Mar 2012
Location: United States
Posts: 3
tb0508 is an unknown quantity at this point
Re: PID algorithm using Arduino

Gulfport, MS...I am originally from Jackson.

Anyway, I am fairly new to the microcontroller/PID scene as this is a first for me. To answer some questions, I am using a Roboclaw 2x5A with the arduino uno. I am using two arduinos with xbee's to communicate wirelessly. I have the inputs(steering, the 'target') going into one arduino and sending to the second arduino(I have this code written for both). I have the pot at the wheels sent to the second arduino also so now the second arduino has the 'target' and 'curent' values.

I have a detailed explanation of trying to write the code if you don't mind looking over it and seeing if I have it correct.

First question dealing with the 'target' pot with the steering wheel. The way I understand it is I will have a 'proportional range', since the pot on the steering will have a range of 0-1023. I figured the range will be about 300 - 900. Reason I say this is I have a pin in the steering wheel which only allows the wheel to turn so far to the left and right. I will calculate this range of the pot using my code to see the values.
Pin view:
http://img560.imageshack.us/img560/7...ngwheelpin.jpg

So, I will need to read in the proportional values of the range and try to get it to where it is a very close range when comparing the left to right. So, range from 200 to 500(center) to 800...where 300 is the range on each side(example). Am I off track right now?

Next, I will convert this range to an 'error range' where 0 is the center and the range is from -300 and +300 using the above example. I will then take the value of the steering pot(target) and subtract it from the current value of the 'feedback' pot to get the error, then compare it to the 'error range'. This value will be negative or positive, small or large.

I will need to get the constant K to use: Turn=K*error, where error is the target-current . With K being (0-800)/(-300-0) = 2.6.. (using example, not sure if K is correct)? I assume, Turn is the value that will be sent to the motor controller(using roboclaw 2x5a) to determine the left/right and how fast (depending on how far away the Turn value is on the 'error range' graph), correct?

This is my idea, correct me if I am wrong or if there is an easier way(I am new to this), is this over complicating it? The roboclaw has PID algorithm itself, so I assume it will receive the Turn value and interpret the number and tell the wiper motor what to do and how fast.

If this is a correct way, I am currently trying to right the code to incorporate this and determining how to send the value to the roboclaw. Any input, correction, would help. Thanks

Last edited by tb0508 : 03-23-2012 at 10:44 PM.
  #4   Spotlight this post!  
Unread 03-24-2012, 01:05 AM
StevenB StevenB is offline
is having FRC withdrawal symptoms.
AKA: Steven Bell
no team
Team Role: College Student
 
Join Date: May 2005
Rookie Year: 2005
Location: Stanford, CA
Posts: 398
StevenB has a reputation beyond reputeStevenB has a reputation beyond reputeStevenB has a reputation beyond reputeStevenB has a reputation beyond reputeStevenB has a reputation beyond reputeStevenB has a reputation beyond reputeStevenB has a reputation beyond reputeStevenB has a reputation beyond reputeStevenB has a reputation beyond reputeStevenB has a reputation beyond reputeStevenB has a reputation beyond repute
Re: PID algorithm using Arduino

Congratulations on getting your feet wet with PID. It's fun, and an incredibly useful concept to have practical experience with. Last year my roommates were taking a control systems class and were frustrated trying to understand PID - but it made sense to me, because I've seen it in action and gotten my hands dirty coding it.

Now, to your questions: I think you're making it too complicated. (It's ok - It took me weeks to distill PID when I was learning it, but now I can code it in half a dozen lines.)

Think about it this way: you have a sensor input which produces a range of values, which you want to use to control the position of the output. The first thing to do is to translate the input sensor value to the output sensor value. This will probably be a linear function, based on the center readings and range of the sensors.

Once you have a target measurement, you compare it with the current measurement. This is your error. If the measurements are the same (error is zero), then you don't want to move. If the error is large, you want to move fast. If it's small and negative, you want to move slowly in the other direction.

If I have a control input from 200 to 800 (center of 500) and a measurement ranging from 0 to 800 (center of 400), the code would look something like this:

Code:
control = readInputValue(); // AnalogRead or whatever you do to get the input
// Convert to sensor range:  Subtract the input offset to center
// around 0, multiply by the range scale, and add the output offset
target = (input - 500) * (500/300) + 400;
current = readSensorValue();
error = target-current;
outputPower = error * kP; // Assuming output is +/- 127 or similar

Note that you can't compute kP without modeling the underlying system and doing some nasty mathematical analysis. The best way to determine it is to experiment with some different values and see how they perform.

I wouldn't use the RoboClaw's built-in PID to start off. You'll learn more and be less frustrated if you code the feedback loop yourself. I used a RoboClaw 2x5A with and Arduino last year for my senior design project. I selected the RoboClaw specifically because it could handle the PID loop without the Arduino having to do any heavy lifting, but the interface and tuning took a lot of debugging time.
__________________
Need a physics refresher? Want to know if that motor is big enough for your arm? A FIRST Encounter with Physics

2005-2007: Student | Team #1519, Mechanical Mayhem | Milford, NH
2008-2011: Mentor | Team #2359, RoboLobos | Edmond, OK
2014-??: Mentor | Looking for a team...
  #5   Spotlight this post!  
Unread 03-24-2012, 01:24 AM
tb0508 tb0508 is offline
Registered User
no team
 
Join Date: Mar 2012
Location: United States
Posts: 3
tb0508 is an unknown quantity at this point
Re: PID algorithm using Arduino

Thank you for helping. So, I see it is less complicated than I am making it.

So, to get the values that you used of 200 to 800 with the center being 500. Is that the same as me using the min and max of the steering wheel pot?
http://img560.imageshack.us/img560/7...ngwheelpin.jpg
Using this image, you can see I have a pin that allows me to go left and right only a certain distance. I have code wrote to output the value of the current steering input, so I need to find the min, max, and center using this method?
I will be able to use:
target = (input - 500) * (500/300) + 400;
Once I find the values of my pot?

Here is my code for the input arduino('target') and second arduino that is receiving this value.
Code:
int potPin = 0; // select input pin 
int val = 0; // variable to store the value

void setup() {
Serial.begin(9600);
}

void loop() 
{
val = analogRead(potPin); // read the value from the pot
Serial.println( val );
delay(1);
}
second arduino the receives the 'target' through xbee(This arduino also receives the value of the 'current' directly with the bottom wheel pot)
Code:
char string[8]; //can be 4, 8 is fine
int var;
int index;
boolean started=false;
boolean ended=false;

void setup()
{
  Serial.begin(9600);
}

void loop()
{
   while(Serial.available() >= 0) //since 0-1023
    {
      var=Serial.read(); //read the character
      if(var=='<') //not sure what to put in if statement to run until end
      {
        started = true;
        index=0;
        string[index]='\0';
      }
      else if(var=='>')
      {
        ended = true;
        break; //break out of while loop when '>' received
      }
      
      else if(started)
      {
        string[index]=var;
        index++;
        string[index]='\0';
        string[index]=var; //store character
      }
    //x = Serial.read(); //read another string
    }
    
    if(started && ended)
    {
      //convert portion of string to integer representation
      int val=atoi(string); 
      Serial.print("<");
      Serial.print(val);
      Serial.print(">");
      
      //next time
      started = false;
      ended = false;
      
      index = 0;
      string[index]='\0';
    }
  }
This second arduino will be able to compare the 'target' and 'current' values to use the 'P'. I plan to trial and error the Kp. Now it can use the:
current = readSensorValue();
error = target-current;
outputPower = error * kP;

That you mentioned.

Also, I plan to send the outputPower value to the roboclaw to determine left/right and how fast. Is this correct way? And I am a little confused on how exactly to send the value/data to the roboclaw for it to interpret.

Last edited by tb0508 : 03-24-2012 at 02:22 AM.
  #6   Spotlight this post!  
Unread 03-24-2012, 01:27 PM
StevenB StevenB is offline
is having FRC withdrawal symptoms.
AKA: Steven Bell
no team
Team Role: College Student
 
Join Date: May 2005
Rookie Year: 2005
Location: Stanford, CA
Posts: 398
StevenB has a reputation beyond reputeStevenB has a reputation beyond reputeStevenB has a reputation beyond reputeStevenB has a reputation beyond reputeStevenB has a reputation beyond reputeStevenB has a reputation beyond reputeStevenB has a reputation beyond reputeStevenB has a reputation beyond reputeStevenB has a reputation beyond reputeStevenB has a reputation beyond reputeStevenB has a reputation beyond repute
Re: PID algorithm using Arduino

Quote:
Originally Posted by tb0508 View Post
So, to get the values that you used of 200 to 800 with the center being 500. Is that the same as me using the min and max of the steering wheel pot?
Probably, but not necessarily; think about the values you're trying to convert, rather than how to plug it into an equation. The graph below shows an example mapping of input values to output values. The input is the x-axis; these are the readings you get from the steering wheel. The output is the y axis; these are the desired positions for the output. Draw this graph for whatever values you have, and the equation for Y in terms of X will follow naturally from that.



Quote:
Originally Posted by tb0508 View Post
Also, I plan to send the outputPower value to the roboclaw to determine left/right and how fast. Is this correct way? And I am a little confused on how exactly to send the value/data to the roboclaw for it to interpret.
Look through the Roboclaw datasheet and Arduino examples, if you haven't already. In theory you could use any of the four control modes the RoboClaw allows.

As a side note, it would be simpler and more efficient to use Serial.write() and Serial.read() to send the bytes directly, rather than converting them to character strings and back. But if you've got it working with print() and atoi(), then carry on!
__________________
Need a physics refresher? Want to know if that motor is big enough for your arm? A FIRST Encounter with Physics

2005-2007: Student | Team #1519, Mechanical Mayhem | Milford, NH
2008-2011: Mentor | Team #2359, RoboLobos | Edmond, OK
2014-??: Mentor | Looking for a team...
Closed Thread


Thread Tools
Display Modes Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump


All times are GMT -5. The time now is 03:40 PM.

The Chief Delphi Forums are sponsored by Innovation First International, Inc.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi