Go to Post Cooling fans? Never had the need. Then again, we're talking New Jersey in March. Radiant heaters might be a better choice, or maybe snow boots. - DonRotolo [more]
Home
Go Back   Chief Delphi > Technical > Programming
CD-Media   CD-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 15-02-2006, 00:46
Rick TYler Rick TYler is offline
A VEX GUy WIth A STicky SHift KEy
VRC #0010 (Exothermic Robotics)
Team Role: Mentor
 
Join Date: Jan 2005
Rookie Year: 2005
Location: Redmond, Washington
Posts: 2,000
Rick TYler has a reputation beyond reputeRick TYler has a reputation beyond reputeRick TYler has a reputation beyond reputeRick TYler has a reputation beyond reputeRick TYler has a reputation beyond reputeRick TYler has a reputation beyond reputeRick TYler has a reputation beyond reputeRick TYler has a reputation beyond reputeRick TYler has a reputation beyond reputeRick TYler has a reputation beyond reputeRick TYler has a reputation beyond repute
Tuning PID Code

Help us, Kevin, you are our only hope! Or someone else...

Our programming guy (robotaddict -- my son as it turns out) has written single-stick code based heavily on Kevin's PID code routines. It's been a long, difficult road for a student who had little C experience at the beginning of the season, but the code seems to work pretty well. The wild oscillations are gone, and the robot is drivable. But there are some problems. I'm hoping some of you with real-world PID experience can give John -- er, I mean robotaddict -- some guidance of final debugging. We also use these routines for aiming and autonomous, so it is important that he fix them. John and the programming mentors have tweaked the P,I, and D settings a LOT, but the perfect blend of settings has been elusive.

1. The controls are pretty sensitive. Turning is especially twitchy.

2. Can someone describe the PID tuning process in even more detail than Kevin does in the comments in his code. Careful descriptions of what the robot is doing in relation to each of the control settings would be especially appreciated.

3. The robot nearly drives in a straight line, but gently drifts to one side in a long (say 30-40 feet) drive.

Thank you SO MUCH in advance.
__________________
Exothermic Robotics Club, Venturing Crew 2036
VRC 10A, 10B, 10D, 10Q, 10V, 10X, 10Z, and 575
  #2   Spotlight this post!  
Unread 15-02-2006, 01:11
gnirts gnirts is offline
Suspicious pointer conversion
AKA: Robinson Levin
FRC #1648 (The Gearbox Gangstaz)
Team Role: Programmer
 
Join Date: Jan 2006
Rookie Year: 2005
Location: ATL
Posts: 116
gnirts will become famous soon enough
Re: Tuning PID Code

I am facing this challenge too, except PID code is controlling the position and elevation of our turret, plus its steering and autonomous mode.

There is no one in my area who has responded with any PID experience except those that use it for temperature control.

This leaves me with many questions about the best way to do PID control, like how long should the I values stick around? For something like controlling the spin (yaw) of a turret, should I even use I, or switch to PD?

Quote:
Originally Posted by Rick TYler
Kevin's PID code routines
Are you talking about the NAV code from 2005?

Eagerly waiting,
Robinson
__________________
'... who are you, then?'
'I am part of that power which eternally
wills evil and eternally works good.'
Goethe, Faust
  #3   Spotlight this post!  
Unread 15-02-2006, 01:13
Rick TYler Rick TYler is offline
A VEX GUy WIth A STicky SHift KEy
VRC #0010 (Exothermic Robotics)
Team Role: Mentor
 
Join Date: Jan 2005
Rookie Year: 2005
Location: Redmond, Washington
Posts: 2,000
Rick TYler has a reputation beyond reputeRick TYler has a reputation beyond reputeRick TYler has a reputation beyond reputeRick TYler has a reputation beyond reputeRick TYler has a reputation beyond reputeRick TYler has a reputation beyond reputeRick TYler has a reputation beyond reputeRick TYler has a reputation beyond reputeRick TYler has a reputation beyond reputeRick TYler has a reputation beyond reputeRick TYler has a reputation beyond repute
Re: Tuning PID Code

Quote:
Originally Posted by gnirts
Are you talking about the NAV code from 2005?
Yep, that's it. John, er "robotaddict," wrote his own which was extremely complex and never worked very well (unless you wanted your robot to go back and forth rapidly), and then developed "version 2" based on Kevin's code. It almost worked great. KEVIN!! (Or other guru)
__________________
Exothermic Robotics Club, Venturing Crew 2036
VRC 10A, 10B, 10D, 10Q, 10V, 10X, 10Z, and 575
  #4   Spotlight this post!  
Unread 15-02-2006, 01:59
gnirts gnirts is offline
Suspicious pointer conversion
AKA: Robinson Levin
FRC #1648 (The Gearbox Gangstaz)
Team Role: Programmer
 
Join Date: Jan 2006
Rookie Year: 2005
Location: ATL
Posts: 116
gnirts will become famous soon enough
Re: Tuning PID Code

Quote:
developed "version 2" based on Kevin's code.
Are you willing to post it?

The actual PID algorithm is not very complex, just the tuning process.

I found this on the Wikipedia for PID Controller:
Quote:
There are several methods for tuning a PID loop. The choice of method will depend largely on whether or not the loop can be taken "offline" for tuning, and the response speed of the system. If the system can be taken offline, the best tuning method often involves subjecting the system to a step change in input, measuring the output as a function of time, and using this response to determine the control parameters.

If the system must remain online, one tuning method is to first set the I and D values to zero. Increase the P until the output of the loop oscillates. Then increase I until oscillation stops. Finally, increase D until the loop is acceptably quick to reach its reference. A fast PID loop tuning usually overshoots slightly to reach the setpoint more quickly; however, some systems cannot accept overshoot.
Code:
Effects of increasing parameters
Parameter      Rise Time      Overshoot      Settling Time      S.S. Error
P              Decrease       Increase       Small Change       Decrease
I              Decrease       Increase       Increase           Eliminate
D              Small Chang    Decrease       Decrease           Small Change
Another tuning method is formally known as the "Ziegler-Nichols method". It starts in the same way as the method described before: first set the I and D gains to zero and then increase the P gain until the output of the loop starts to oscillate. Write down the critical gain (Kc) and the oscillation period of the output (Pc). Then adjust the P, I and D controls as the table shows:
Code:
Ziegler-Nichols method
Control 	P           Tr        Td
P           0.5 * Kc        -         -
PI         0.45 * Kc     Pc / 1.2     -
PID         0.6 * Kc     Pc / 2      Pc/8
Everyone wish everyone else luck, (God knows at least I need it)
Robinson
__________________
'... who are you, then?'
'I am part of that power which eternally
wills evil and eternally works good.'
Goethe, Faust
  #5   Spotlight this post!  
Unread 15-02-2006, 02:04
gnirts gnirts is offline
Suspicious pointer conversion
AKA: Robinson Levin
FRC #1648 (The Gearbox Gangstaz)
Team Role: Programmer
 
Join Date: Jan 2006
Rookie Year: 2005
Location: ATL
Posts: 116
gnirts will become famous soon enough
Re: Tuning PID Code

Also, while I am at it, note this post (and the rest of the thread, really)
Quote:
Originally Posted by Joel J.
PD is pretty much the most common way to go about velocity control.
- Set Kd to 0.
- Increase Kp slowly until the robot starts to oscillate around its setpoint. Watch the oscillations, are they dying down, or staying consistent?
- - + If yes, then set Kp to about 30% of its current value.
- - + If no, then Kp is set way too high, for some reason. Reduce it by 60%, and watch for the oscillations again. When the oscillations are reasonable (staying about constant, or dying away, and aren't too violent), then move to the next step.
- Increase Kd slowly until the robot "snaps" to its setpoint.
- If the robot "snaps" eventually, but there is some error between where it snaps, and the desired setpoint (and you can't live with this error), then you have to add in a bit of Ki.
- Ki is usally ends up being 1/Kd. I don't like Ki for velocity control purposes, but you can fiddle with it if you want.
from Problems Using PID for Velocity

Send us more luck,
Robinson
__________________
'... who are you, then?'
'I am part of that power which eternally
wills evil and eternally works good.'
Goethe, Faust
  #6   Spotlight this post!  
Unread 15-02-2006, 03:23
Eldarion's Avatar
Eldarion Eldarion is offline
Electrical Engineer / Computer Geek
AKA: Eldarion Telcontar
no team (Teamless Orphan)
Team Role: Alumni
 
Join Date: Nov 2005
Rookie Year: 2005
Location: Númenor
Posts: 558
Eldarion has a reputation beyond reputeEldarion has a reputation beyond reputeEldarion has a reputation beyond reputeEldarion has a reputation beyond reputeEldarion has a reputation beyond reputeEldarion has a reputation beyond reputeEldarion has a reputation beyond reputeEldarion has a reputation beyond reputeEldarion has a reputation beyond reputeEldarion has a reputation beyond reputeEldarion has a reputation beyond repute
Send a message via AIM to Eldarion Send a message via Yahoo to Eldarion
Re: Tuning PID Code

Quote:
Originally Posted by gnirts
I am facing this challenge too, except PID code is controlling the position and elevation of our turret, plus its steering and autonomous mode.

There is no one in my area who has responded with any PID experience except those that use it for temperature control.

This leaves me with many questions about the best way to do PID control, like how long should the I values stick around? For something like controlling the spin (yaw) of a turret, should I even use I, or switch to PD?

Are you talking about the NAV code from 2005?

Eagerly waiting,
Robinson
The integral term is used for long-term steady-state error compensation.
Unless your robot will sit in the middle of the field for the entire match, I don't think it's really necessary.
There will be much larger errors induced by motion than the (usually small) steady-state error.
__________________
CMUCam not working? Tracks sporadically? Try this instead: http://www.falconir.com!
PM me for more information if you are interested (it's open source!).

Want the FIRST Email blasts? See here: http://www.chiefdelphi.com/forums/sh...ad.php?t=50809

"The harder the conflict, the more glorious the triumph. What we obtain too cheaply, we esteem too lightly; it is dearness only that gives everything its value."
-- Thomas Paine

If it's falling apart it's a mechanical problem. If it's spewing smoke it's a electrical problem.
If it's rampaging around destroying things it's a programming problem.

"All technology is run on 'Magic Smoke' contained within the device. As everyone knows, whenever the magic smoke is released, the device ceases to function."
-- Anonymous

I currently speak: English, some German, Verilog, x86 and 8051 Assembler, C, C++, VB, VB.NET, ASP, PHP, HTML, UNIX and SQL
  #7   Spotlight this post!  
Unread 15-02-2006, 07:48
gnirts gnirts is offline
Suspicious pointer conversion
AKA: Robinson Levin
FRC #1648 (The Gearbox Gangstaz)
Team Role: Programmer
 
Join Date: Jan 2006
Rookie Year: 2005
Location: ATL
Posts: 116
gnirts will become famous soon enough
Re: Tuning PID Code

Quote:
Originally Posted by Eldarion
The integral term is used for long-term steady-state error compensation.
Unless your robot will sit in the middle of the field for the entire match, I don't think it's really necessary.
There will be much larger errors induced by motion than the (usually small) steady-state error.
So just PD is the way to go with the turret? What about steering (i.e. if both joysticks (we do tank drive) are set to the same value and the robot should be going straight, but the gyro tells me my angular rate is > 0 deg/s). I would like to compensate with some form of closed loop control, is PID/PD/P/PI/whatever the way to do this?

Thanks in advance,
Robinson
__________________
'... who are you, then?'
'I am part of that power which eternally
wills evil and eternally works good.'
Goethe, Faust
  #8   Spotlight this post!  
Unread 15-02-2006, 08:12
Chris_Elston's Avatar
Chris_Elston Chris_Elston is offline
Controls Engineer
AKA: chakorules
FRC #1501 (Team THRUST)
Team Role: Engineer
 
Join Date: Feb 2004
Rookie Year: 2001
Location: Huntington, Indiana
Posts: 751
Chris_Elston has a reputation beyond reputeChris_Elston has a reputation beyond reputeChris_Elston has a reputation beyond reputeChris_Elston has a reputation beyond reputeChris_Elston has a reputation beyond reputeChris_Elston has a reputation beyond reputeChris_Elston has a reputation beyond reputeChris_Elston has a reputation beyond reputeChris_Elston has a reputation beyond reputeChris_Elston has a reputation beyond reputeChris_Elston has a reputation beyond repute
Re: Tuning PID Code

I won't go in the method of tuning a PID as others have done, but here are some tips to get you up in running FAST.

1. Use three POTs on a board labeling them P,I,D. Connect them to Analog ports. Say 14,15,16 respectfully. Make a function to read the pots, and then multiply the values out. Like K_P = analog14 * 0.0001. Of course K_P needs to be a float.

Your analog will be 0-1024 so you need to make your K_P, K_I, K_D values smaller, normally less than 1

K_P = analog14 * 0.0001
K_I = analog15 * 0.0001
K_D = analog16 * 0.0001

If you need a bigger "tweak" just shrink the multiplier

K_P = analog14 * 0.001
K_I = analog15 * 0.001
K_D = analog16 * 0.001

You won't be able to view K_P in your "Print to Screen" so just display your analog value, so you can multiply or divide back to get your "real" K_P,K_I,orK_D value to "hard code" it back into the system so you can REMOVE the PID trimmer pot board.


2. Wow...use LABVIEW to tune your PID system. We tuned our ball velocity PID by connecting the ball motor to PWM1, then mapped our velocity variable to PWM2. Start Labview Dashboard. Both applications, the connections one, and the view application. Of course there ARE NO MOTORS connected to PWM2, we are just transporting the information to Labview because we don't know how to edit Labview. Out of the box, PWM1 and PWM2 was configured in a graph......;-)

See these handy video tutorials if you haven't done it yet.
http://www.lasarobotics.org/Forum/viewtopic.php?t=366

Now you can view your PWM1 which is your motor OUTPUT, and your pretending that PWM2 is your velocity output so you can just use Labview PWM2 to view, graph and log your PID tuning. You'll see very quickly how effective this tool is.

In combination of the two tools, making a PID tuning POT trimmer board, and displaying the tune on Labview, you'll have your PID tuning done in a matter of minutes.

Hopfully this helps.




-
__________________
Team T.H.R.U.S.T. 1501
Download all of our past robot's source code here:Repository

Favorite CD quote:
"That can't be their 'bot. not nearly enough (if any) rivets to be a 1501 machine." ~RogerR: Team #1369

Last edited by Chris_Elston : 15-02-2006 at 08:16.
  #9   Spotlight this post!  
Unread 26-01-2007, 11:59
Chaychay Chaychay is offline
Registered User
AKA: Jay Shah
FRC #0610 (Crescent Robotics)
Team Role: College Student
 
Join Date: Dec 2003
Rookie Year: 2004
Location: Toronto, Ontario
Posts: 48
Chaychay is on a distinguished road
Send a message via MSN to Chaychay
Re: Tuning PID Code

Mr. Elston, first off, what an amazing idea. Our team had nightmares tuning last year, we didn't get the values right until Atlanta! (albeit, we didn't have much testing time before hand anyway)

Quote:
Originally Posted by Chris_Elston View Post

Use three POTs on a board labeling them P,I,D. Connect them to Analog ports. Say 14,15,16 respectfully.

-
I was wondering if this would work equally as well if the POTs were connected to the OI kind of like joysticks. I ask because I want to be able to tune the drive PID system and give it to our driver to see how he likes it. Based on this feedback I can retune and he can test again. Or I can teach him what they P, I, D means, and just get him to tune it to his liking. I don't see any obvious reason why this wouldn't work, but I might be missing something. Thanks very much for this time saving idea!!!
  #10   Spotlight this post!  
Unread 26-01-2007, 12:25
Alan Anderson's Avatar
Alan Anderson Alan Anderson is offline
Software Architect
FRC #0045 (TechnoKats)
Team Role: Mentor
 
Join Date: Feb 2004
Rookie Year: 2004
Location: Kokomo, Indiana
Posts: 9,113
Alan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond repute
Re: Tuning PID Code

Quote:
Originally Posted by Chaychay View Post
I was wondering if this would work equally as well if the POTs were connected to the OI kind of like joysticks.
We did exactly that last year. A student built a "tuning box" with three pots and three pushbuttons (there wasn't really room to make it four and four) that connects to a joystick port. We reserved that port for debug and calibration use.

We used the box to set the PID constants for our turret, drivebase position seek, and direction tracking; and for setting the motor speed and timing for the catapult winder mechanism we started with. We will probably be doing the same thing for our PID parameters this year, with the additional feature of using menus and commands through the program port to save the data to EEPROM the way Kevin Watson's camera software works.
  #11   Spotlight this post!  
Unread 26-01-2007, 12:36
Chris_Elston's Avatar
Chris_Elston Chris_Elston is offline
Controls Engineer
AKA: chakorules
FRC #1501 (Team THRUST)
Team Role: Engineer
 
Join Date: Feb 2004
Rookie Year: 2001
Location: Huntington, Indiana
Posts: 751
Chris_Elston has a reputation beyond reputeChris_Elston has a reputation beyond reputeChris_Elston has a reputation beyond reputeChris_Elston has a reputation beyond reputeChris_Elston has a reputation beyond reputeChris_Elston has a reputation beyond reputeChris_Elston has a reputation beyond reputeChris_Elston has a reputation beyond reputeChris_Elston has a reputation beyond reputeChris_Elston has a reputation beyond reputeChris_Elston has a reputation beyond repute
Re: Tuning PID Code

Yes you can.

You'll need 3 100K pots.

See this document:
http://www.ifirobotics.com/docs/lega...-2004-2-17.pdf


PDF Page #5

Each port provides four analog inputs. These inputs are typically connected to joysticks and potentiometers, providing an analog input ranging from 0 to 254 (in software) that is transmitted to the Robot Controller. In the event that an analog input is less than 0.05V, a value of 127 will be generated. This ensures that when a joystick is unplugged, the corresponding output on the Robot Controller will not go to a full reverse condition. Each port provides +5V Aux, used for wiring to potentiometers or other sensors. The wiring diagram for a potentiometer is shown below. Always use 100kΩ potentiometers.

You'll need to "borrow" a joystick port. And then scale your PID to something different like 0-254 instead of 0-1024 like you would see on the analog port of the RC.


WARNING....UNPLUG....PID pots when in competition.....LOL....


WARNING #2....Make sure that your values default to 0 when radio drops...because by default they go to 127.

I like the pots onboard the robot the best, when robot was up on blocks. Though the below picture looks "kewl" from the OI, RC tuning from the analog was my favorite....
Attached Thumbnails
Click image for larger version

Name:	oi4.jpg
Views:	111
Size:	90.2 KB
ID:	4942  
__________________
Team T.H.R.U.S.T. 1501
Download all of our past robot's source code here:Repository

Favorite CD quote:
"That can't be their 'bot. not nearly enough (if any) rivets to be a 1501 machine." ~RogerR: Team #1369

Last edited by Chris_Elston : 26-01-2007 at 12:42.
  #12   Spotlight this post!  
Unread 26-01-2007, 13:45
Chaychay Chaychay is offline
Registered User
AKA: Jay Shah
FRC #0610 (Crescent Robotics)
Team Role: College Student
 
Join Date: Dec 2003
Rookie Year: 2004
Location: Toronto, Ontario
Posts: 48
Chaychay is on a distinguished road
Send a message via MSN to Chaychay
Re: Tuning PID Code

Mr. Anderson & Mr. Elston,

Thank you for confirming this. This is going to save so much time for us , we're hoping on getting this tuning board built today.

Thanks again for the help =)
  #13   Spotlight this post!  
Unread 28-01-2007, 15:29
Chaychay Chaychay is offline
Registered User
AKA: Jay Shah
FRC #0610 (Crescent Robotics)
Team Role: College Student
 
Join Date: Dec 2003
Rookie Year: 2004
Location: Toronto, Ontario
Posts: 48
Chaychay is on a distinguished road
Send a message via MSN to Chaychay
Re: Tuning PID Code

Ok, so our team looked around the lab for 100 K ohm potentiometers, and we could not find any. So after some thought we decided to slice open the KOP Joystick from last year (it was semi-busted anyway) and extract the 2 potentiometers from there.

To our surpise, these pots are 120K ohms, can we still use them for the PID trimming board? Seems to me that if they were used for the KOP joystick, there is no reason why they would pose a threat.

Thanks for your help, I just want to make sure because that OI is mighty expensive to repair/replace if we blew it...
  #14   Spotlight this post!  
Unread 28-01-2007, 16:10
Andrew Blair's Avatar
Andrew Blair Andrew Blair is offline
SAE Formula is FIRST with Gasoline.
FRC #0306 (CRT)
Team Role: Alumni
 
Join Date: Feb 2005
Rookie Year: 2004
Location: Corry
Posts: 1,193
Andrew Blair has a reputation beyond reputeAndrew Blair has a reputation beyond reputeAndrew Blair has a reputation beyond reputeAndrew Blair has a reputation beyond reputeAndrew Blair has a reputation beyond reputeAndrew Blair has a reputation beyond reputeAndrew Blair has a reputation beyond reputeAndrew Blair has a reputation beyond reputeAndrew Blair has a reputation beyond reputeAndrew Blair has a reputation beyond reputeAndrew Blair has a reputation beyond repute
Send a message via AIM to Andrew Blair Send a message via Yahoo to Andrew Blair
Re: Tuning PID Code

As a side note, I have read that the easiest way to tune a full PID controller is to increase your P constant until there is a constant steady-state error, then increase your I constant until the steady-state error is gone and you have minor oscillation. Finally, increase the D constant to soak up any oscillation.

Hope this helps! We'll have some tuning to do pretty soon ourselves hopefully...
__________________
Reading makes a full man, conference a ready man, and writing an exact man.
-Sir Francis Bacon

"Any intelligent fool can make things bigger, more complex, and more violent. It takes a touch of genius -- and a lot of courage -- to move in the opposite direction."
-Albert Einstein
  #15   Spotlight this post!  
Unread 28-01-2007, 17:51
Kevin Watson's Avatar
Kevin Watson Kevin Watson is offline
La Cañada High School
FRC #2429
Team Role: Mentor
 
Join Date: Jan 2002
Rookie Year: 2001
Location: La Cañada, California
Posts: 1,335
Kevin Watson has a reputation beyond reputeKevin Watson has a reputation beyond reputeKevin Watson has a reputation beyond reputeKevin Watson has a reputation beyond reputeKevin Watson has a reputation beyond reputeKevin Watson has a reputation beyond reputeKevin Watson has a reputation beyond reputeKevin Watson has a reputation beyond reputeKevin Watson has a reputation beyond reputeKevin Watson has a reputation beyond reputeKevin Watson has a reputation beyond repute
Re: Tuning PID Code

Quote:
Originally Posted by Chaychay View Post
Ok, so our team looked around the lab for 100 K ohm potentiometers, and we could not find any. So after some thought we decided to slice open the KOP Joystick from last year (it was semi-busted anyway) and extract the 2 potentiometers from there.

To our surpise, these pots are 120K ohms, can we still use them for the PID trimming board? Seems to me that if they were used for the KOP joystick, there is no reason why they would pose a threat.

Thanks for your help, I just want to make sure because that OI is mighty expensive to repair/replace if we blew it...
Anything above ~5K ohms will work well.

-Kevin
__________________
Kevin Watson
Engineer at stealth-mode startup
http://kevin.org
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

Similar Threads
Thread Thread Starter Forum Replies Last Post
Out of the Box Camera Code russell Programming 9 21-10-2009 05:28
Problem with idata_user_routines.o? Adrien Programming 3 12-02-2006 01:33
Drive Straight C Code using Encoders without PID? Chris_Elston Programming 17 15-02-2005 23:41
Team THRUST - Kevin's Code and Camera Code Combine Chris_Elston Programming 3 31-01-2005 22:28
heres the code. y this not working omega Programming 16 31-03-2004 15:18


All times are GMT -5. The time now is 15:31.

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


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