Igualación de la velocidad de los motores para equilibrar el robot

1

Actualmente estoy trabajando en un proyecto de robot de balanceo utilizando Arduino Uno. Puedo lograr que el robot se equilibre, pero uno de sus motores tiene la tendencia a girar más que el otro.

Estoy usando el controlador de motor L298N con 2 x 30: 1 Metal Gearmotor 37Dx68L mm con 64 CPR Encoder de polulu.com. También he intentado compensar la diferencia de velocidad al monitorear el valor del codificador en cada motor. Desafortunadamente, la lógica de compensación parece contradecir el control de PWM necesario para equilibrar el robot y hace que oscile bastante.

Actualmente estoy usando el siguiente código para equilibrar la velocidad del motor:

dPos = leftCounterCurr - rightCounterCurr;
if(dPos > 10) {
  leftPWM = u + k*abs(dPos);
  rightPWM = u - k*abs(dPos);
}
else if(dPos < -10) {
  leftPWM = u - k*abs(dPos);
  rightPWM = u + k*abs(dPos);
}

dPos se refiere a la diferencia en los valores de los dos codificadores. leftPWM y rightPWM son los valores de PWM para controlar el motor izquierdo y derecho respectivamente. u es la salida del control PID y se ajusta mediante cierto valor de ganancia para compensar la diferencia en la velocidad del motor.

Espero que alguien con experiencias similares pueda ayudarme. Gracias de antemano.

Edición 1: @Marko hice alguna caracterización de mis motores hoy. Pensé que lo publicaría aquí en caso de que alguien pudiera encontrarlo útil. Los resultados se muestran a continuación. Parece que con un ajuste de capacitancia adecuado, puedo hacer que los motores den respuestas casi similares. Sin embargo, creo que todavía hay una necesidad de usar un bucle de control para un mejor rendimiento.

Por ejemplo, si el motor izquierdo tiene un condensador de 0.3uF en sus terminales, mientras que el motor derecho tiene un capacitor de 0.2uF en su terminal, podemos observar que las dos curvas de respuesta están muy juntas.

Otra cosa que noté fue que el motor no se movería para un ciclo de trabajo por debajo del 20%. Y parece ser un problema universal con el control PWM de los motores de escobillas de CC ... o al menos todavía no he encontrado ningún método para superar este comportamiento.

    
pregunta ckong80

2 respuestas

3

Por lo general, un bucle P, PI simple es mejor que un bucle PID malo. Puede poner 2 controladores PI para la velocidad, para cada rueda tiene su propio controlador PI. Entonces solo controlas la velocidad de cada rueda por separado. Aquí hay un pequeño pseudo algoritmo del controlador PI con el método de integración de captura: \ $ u (k) = K_p \ bigg [e (k) -e (k-1) + \ dfrac {T_s} {2T_i} \ big [e (k) + e (k-1) \ big] + \ \ + \ dfrac {T_d} {T_s} \ big [e (k) -2e (k-1) + e (k-2) \ big] \ bigg] + u (k-1) \ $

EDIT 1: EsteesundiagramadebloquesdePMDC,observequeenlasalidahayunintegrador\$\dfrac{1}{s}\$queintegralavelocidad\$\Omega\$enlaposición\$\Theta\$.Importasisucontroladorutilizaretroalimentacióndevelocidadovelocidad(oambos).Dadoquelaretroalimentacióndevelocidadseobtienederivandodelaposición,asíescomosehacenormalmente,puedeusarPI,delocontrario,uncontroladorPessuficientementebueno,peroledaráunarespuestadetodoelbucleP->integrating->I.ElusodePDleproporcionaráunarespuestadetipoPIPD->interating->PI(IP).Debedecidirsiusarálavelocidadolaposicióncomopuntodeajuste.Elequipoprofesionalutilizalamedicióncombinadadelperíodoylafrecuenciaparaestimarlainformaciónderetroalimentacióndevelocidaddelaretroalimentacióndeposición,porloquesimplementederivarlaposiciónledaráunmalresultadoabajavelocidad.

OMI,debecomenzarhaciendoungeneradordevelocidaddepuntodeajusteconrampa,luegointegrarloenelpuntodeajustedelaposiciónyusarlaposicióncomopuntodeajuste.

\$v_{set}(k)=v_{set}(k)+\Deltav_{max}\$
\$p_{set}(k)=p_{set}(k)+v_{set}(k)\cdotT_{muestra}\$posiciónintegradora
Estaposicióndeintegracióndebeserexactamentedelmismotamañoquesucontador,porejemplo,unenterode32bits,porloquedebeanalizarloenformadeentero.Cuandosereinvertirá,estonoafectaráelcálculodelerror:\$\varepsilon=p_{measure}-p_{set}\$

EDIT2:

v_max..maximumspeed[pulses/s]Acc..maximumacceleration[pulses/s^2]orAcc=v_max/Tramp..TrampramptimetomaxvelocityT_s...samplingtime[s]if(FWD==1){v_set=v_set+Acc*T_s;//pulsespersecondifv_set>v_maxv_set=v_max;}elsif(BKW==1){v_set=v_set-Acc*T_s;ifv_set<-v_maxv_set=-v_max;}else{//stopmovingifv_set>0.0{v_set=v_set-Acc*T_s;ifv_set<0.0v_set=0.0;}ifv_set<0.0{v_set=v_set+Acc*T_s;ifv_set>0.0v_set=0.0;}}p_float=p_float+v_set*T_s;//pulsesifp_float>32767.0p_float=p_float-65535.0;//for16-bitpositioncounterelseifp_float<-32768.0p_float=p_float+65535.0;p_int=int_16(p_float);epsilon=p_int-p_measured;//allnumbersequalint16,32,...y_out=Kp*float(epsilon)+v_set;//pulsespersecond,velocityisfedforwardy_pwm=y_out*k_pulse;//rpm,k_pulse[rpm/pulses]y_pwm=y_pwm*kv;//volts,kv[V/rpm]frommotorspecy_pwm=y_pwm*k_pwm;//%k_pwm[%/V]-100%equalstoVccvolts,approx.ify_pwm>100.0y_pwm=100.0;//maxpositivelimitpwmDTelseify_pwm<-100.0<y_pwm=-100.0;//maxneglimitpwmDT

EDIT3:CódigofuenteindustrialPIDcontrllerzn3fd.Elalgoritmoesincremental:\$u(k)=u(k-1)+\Deltau(k),\;\Deltau(k)=\DeltaP+\DeltaI+\DeltaD\$Funcióndetransferencia:\$G(s)=K_p(1+\dfrac{1}{sT_i}+\dfrac{sT_d}{1+sT_d/\alpha})\$Nota\$alfa\$esunfactordefiltradodelcomponenteDqueserecomiendaqueseade4a20,elvalorpredeterminadoes10.Unvalormásgrandesignificamenosfiltrado,unvalormásbajosignificamásfiltro,notienesentidousarvaloresbajos.

enlace

// industrial PID controller, author: Bobal et al.
// parameters: Kp, Ti, Td, alpha, u_in, u_max
// inputs: Setponit, ProcesVar 
// output: u

double ek, ek1, ek2, uk1, uk2, Setponit, ProcesVar;
double Ts, gamma, u_min, u_max;
double Kpu, Tu, Kp, Ti, Td, Tf, cf, ci, cd;
double q0, q1, q2, p1, p2;

//initialzation, calcualte coefficients
ek1=ek2=uk1=uk2=u=0.0;
Tf = Td/alpha;
cf = Tf/Ts;
ci = Ts/Ti;
cd = Td/Ts;
p1 = -4*cf/(1+2*cf);
p2 = (2*cf-1)/(1+2*cf);
q0 = Kp * (1 + 2*(cf+cd) + (ci/2)*(1+2*cf))/(1+2*cf);
q1 = Kp * (ci/2-4*(cf+cd))/(1+2*cf);
q2 = Kp * (cf*(2-ci) + 2*cd + ci/2 - 1)/(1+2*cf);

// ISR PID algo
ek2 = ek1;
ek1 = ek;
ek = (Setpoint - ProcesVar);
uk2 = uk1;
uk1 = u;

u = q0*ek + q1*ek1 + q2*ek2 - p1*uk1 - p2*uk2;
//limit
if   u>u_max u = u_max;
else if u<u_min u = u_min;
    
respondido por el Marko Buršič
0

El chip L298 está clasificado para un máximo de 2A por canal con funcionamiento continuo de CC (2.5A si está controlado por PWM con un 80% encendido y un 20% apagado), pero los motores 37D de Pololu tienen una corriente de bloqueo de 5A. Es posible que esto no responda a tu pregunta (no tengo suficiente reputación para publicarlo como un comentario), pero podría ser una buena idea obtener un controlador de motor actual más alto.

    
respondido por el macleos

Lea otras preguntas en las etiquetas