View previous topic :: View next topic |
Author |
Message |
luckyluke
Joined: 18 Apr 2006 Posts: 45
|
Proportional Control |
Posted: Mon Mar 02, 2015 4:45 pm |
|
|
hello
i need some advice for motor controlling specially in pid control systems
for a pseudo code
Code: |
#include <18f452.H>
#device adc=8
#fuses HS, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#include "motor.c"
int16 FrontS,RightS;
void adchlx();
void main()
{
signed int16 Kp,OffsetFront,OffsetRight,ErrorFront,ErrorRight,Speed,Left,Right;
Kp=5;
Speed=100;
OffsetFront=55;
OffsetRight=62;
setup_adc(ADC_CLOCK_DIV_32);
setup_adc_ports(ALL_ANALOG );
setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
setup_timer_2(T2_DIV_BY_4, 200, 1);
setup_ccp1(CCP_PWM);
setup_ccp2(CCP_PWM);
ENABLE_INTERRUPTS(INT_TIMER1);
enable_interrupts(int_rda);
ENABLE_INTERRUPTS(global);
delay_ms(100);
while(1)
{
adchlx(); //meausure and avarege sharp analogue distance sensor
ErrorRight=RightS-OffsetRight;
Left=Speed-(Kp*ErrorRight);
Right=Speed+(Kp*ErrorRight);
if(FrontS>55)
{motor(0,50);}
else
{motor(Left,Right);}
}
}
|
for this simple "P" control code (for example a wall follower)
robot suppose to follow the wall to offset value with or without precision
but when i try it doesnt follow the wall, no forward moving, immediately it just turn and keep turn around
and it doesnt depend on Kp value
whats the reason of this?
should i put a delay in loop and stop motors for a while?
thanks have a nice day |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9245 Location: Greensville,Ontario
|
|
Posted: Mon Mar 02, 2015 6:08 pm |
|
|
Can't really help until you show us what's in 'motor.c'
it's also a very,very bad idea to enable an interrupt when you do not have an ISR for it !!!
you also can a function ( adchlx()) ) without showing us that code...
then there's the actual hardware, we need details as to the actual motors, drivers, feedback, etc.
Real PID controller can be made in about 50 lines of CCS C code though..
If you wnat real help, supply all real code not 'pseudo' code
Jay |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Mon Mar 02, 2015 6:17 pm |
|
|
OK. Mr T got in first.
Have you done any testing?
1) Do you KNOW the return signal from the distance sensor is correct?
2) What happens when you force known values into the various motor control parameters?
3) ................
4) ................
You're not giving us anything like enough to work on.
Mike |
|
|
luckyluke
Joined: 18 Apr 2006 Posts: 45
|
|
Posted: Tue Mar 03, 2015 1:22 am |
|
|
hello
Hardware is
Pololu TB6612FNG Dual Motor Driver Carrier x2 in parallel
Pololu 35:1 Metal Gearmotor x 4 (2 for left and 2 for right)
Sharp GP2Y0A41SK0F Analog Distance Sensor 4-30cm one for front and one for right
3S lipo battery
in the code i have three driver file
motor.c is using for TB6612FNG. it makes direction and pwm arragements.motor(left,right) is working with the range of -200 +200 both sides. its working and tested
serialdata.c is serial ring buffer (its a PCM Programmer code taken from this forum). i use it for Kp update and motor testing. For example in motor test routine if i send +100+0501250@ from the serial terminal microcontroller gives forward 100 pwm to left motors, forward 50 pwm for 1250 millisecond. in proportional control routine serial terminal is used for Kp updating. data is transferring with xbees
tictoc.c it calculates time lapse between tic(); and toc();
all interrupt handlers are in drivers. i forgot my flash drive and not possible to send whole program now.
adchlx(); is olympic radian adc averaging routine taken from this forum. its working and tested.
signal from distance sensor is correct. its working and tested.
all the individual part and function in program is working.
Problem is Proportional controlling part.
Code: |
ErrorRight=RightS-OffsetRight;
Left=Speed-(Kp*ErrorRight);
Right=Speed+(Kp*ErrorRight);
if(FrontS>55)
{motor(0,50);}
else
{motor(Left,Right);}
|
My control idea and implementing it wrong i guess |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Tue Mar 03, 2015 6:00 am |
|
|
OK. So you think you've got all the separate sections working.
You could try to get a feel for what's needed semi-manually:-
1) Read the sensor data to a PC.
2) Work out what to tell the motors.
3) Send motor drive parameters from PC.
4) Let it run for a short distance to a stop.
5) Loop back to (1).
Mike |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19549
|
|
Posted: Tue Mar 03, 2015 8:43 am |
|
|
One big problem, is that the PID is not synchronised to the PWM.
Normally I'd work out the worst case time for the PID loop, and then set the interrupt counter for the PWM timer, to give a potential time slightly longer than this.
Then don't use the interrupt, but 'poll' it.
So something like
Code: |
setup_timer_2(T2_DIV_BY_4, 200, 8);
//so an interrupt is generated every eight PWM pulses
//Then in the main loop:
while (!interrupt_active(INT_TIMER2))
; //delay till the timer interrupts
clear_interrupts(INT_TIMER2);
//and perform the PID calculations
|
A PID _must_ be synchronous to it's PWM, or you will get erratic behaviour.
Then the other thing is have you sat down and actually worked out the scales of the values used?. With your Kp as shown, an error of just '10', is going to give the '50' output. Normally for an integer PID, I'd be expecting to perform the arithmetic, and then divide by a fixed integer factor (like perhaps 8 or 16), to feed the motor code, otherwise no effective 'factional' part exists in the algorithm. |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Tue Mar 03, 2015 11:38 am |
|
|
In your original post you complained :- Quote: | but when i try it doesnt follow the wall, no forward moving, immediately it just turn and keep turn around
and it doesnt depend on Kp value | There must be something completely wrong.
I'd be looking closely at all the pertinent variables.
Mike |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9245 Location: Greensville,Ontario
|
|
Posted: Tue Mar 03, 2015 12:29 pm |
|
|
sounds like a defective 'turns' sensor.
normally you'd have 'test' programs to verify the action/range of each sensor before embarking on a 'mission'.
Jay |
|
|
luckyluke
Joined: 18 Apr 2006 Posts: 45
|
|
Posted: Mon Mar 09, 2015 12:20 pm |
|
|
hello
i have some progress with Mike Walne's guidance and Ttelmah's idea. it is following wall now.
also thank you temtronic i solve hit the wall problem
i want to ask how fast pid updates should be? mine is about 70 now in a second. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19549
|
|
Posted: Mon Mar 09, 2015 1:30 pm |
|
|
That's down to your hardware.
The PID for something like a heater can update just a few times a minute.
On one for a motor, the rate required depends for a minimum on how quickly a change in speed can be detected (depends on the number of lines in the encoder), versus for a maximum how quickly the speed will actually change. Within those limits, you then adjust the PID terms to get the required stability, and correction rate.
Also, don't get hooked on PID. PID is a common starting point, but many algorithms will use simplified or modified forms. PD will often be enough, while in some cases, forms like P(D^2), may apply. For slow corrections with a fast update rate which doesn't suffer from overshoot, PI may be used. |
|
|
|