Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: MODSERIAL mbed Encoder
main.cpp
- Committer:
- Socrates
- Date:
- 2013-11-04
- Revision:
- 31:5c90e931dbfe
- Parent:
- 30:c569058f10aa
- Child:
- 32:5ae627e1bce8
File content as of revision 31:5c90e931dbfe:
#include "mbed.h" #include "MODSERIAL.h" #include "encoder.h" #define PI 3.14159265358979323 //XenY //Een pwm van 0.05 is net genoeg om de heugel te bewegen. linksom bewegen is negatief voor de encoder. getposition gaat in ticks. //4123 ticks is een rondje. //Rechts is x, links is y //Inputs. AnalogIn emgtr(PTB3); AnalogIn emgbr(PTB2); AnalogIn emgtl(PTB1); AnalogIn emgbl(PTB0); PwmOut pwm_A(PTA12); PwmOut pwm_B(PTA5); MODSERIAL pc(USBTX,USBRX); DigitalOut motordirA(PTD3); DigitalOut motordirB(PTD1); Encoder motor1(PTD0,PTC9); Encoder motor2(PTD5,PTC8); //Functies en flags. void keep_in_range(double * in, double min, double max); void keep_in_rangeint(int * in, int min, int max); volatile bool looptimerflag; void setlooptimerflag(void) { looptimerflag = true; } volatile bool dirflagx=true; volatile bool dirflagy=true; void tricheck(void) { dirflagx=true; dirflagy=true; } volatile bool startflag=true; volatile bool calA=true, calB=true; volatile bool frictionflag=true; volatile bool calflag=true; volatile bool meetflag=true; volatile bool patroonflag=false; int main() { //Constantes en tickers. pwm_A.period(1.0/2500.0); pwm_B.period(1.0/2500.0); Ticker looptimer; Timeout dirtimeout; const double ts=0.004; looptimer.attach(setlooptimerflag,ts); double numh1,numh2,denh2,numl1,numl2,numl3,denl2,denl3; double xtr,ytr,y1tr,x1tr,ztr,z1tr,z2tr,yabstr,yabs1tr,yabs2tr,ktr; double xbr,ybr,y1br,x1br,zbr,z1br,z2br,yabsbr,yabs1br,yabs2br,kbr; double xtl,ytl,y1tl,x1tl,ztl,z1tl,z2tl,yabstl,yabs1tl,yabs2tl,ktl; double xbl,ybl,y1bl,x1bl,zbl,z1bl,z2bl,yabsbl,yabs1bl,yabs2bl,kbl; double zx,zy, xuit,yuit, rt; double vxuit, vyuit, Ap, Ad, Ad1, kd, kp, ki, Ai, Ai1, Bp, Bd, Bd1, Bi, Bi1; double for_A, for_B, ctrlA, ctrlB, kdc, kpc, kic; double gain, emggrens,friction; int xdir, ydir, Adir, Bdir; int ticka, tickb, refA,refB, errA, errB; int Aboven, Aonder, Bboven,Bonder; //Startwaarden. x1tr=0; y1tr=0; z1tr=0; z2tr=0; yabs1tr=0; yabs2tr=0; x1br=0; y1br=0; z1br=0; z2br=0; yabs1br=0; yabs2br=0; x1tl=0; y1tl=0; z1tl=0; z2tl=0; yabs1tl=0; yabs2tl=0; x1bl=0; y1bl=0; z1bl=0; z2bl=0; yabs1bl=0; yabs2bl=0; zx=0; zy=0; xdir=0; ydir=0; xuit=0; yuit=0; kpc=1.0*0.1545; kdc=0.0*2.8*pow(10.0,-3.0); kic=0.1*1.0; kp=0.1*0.1545; kd=0.1*2.8*pow(10.0,-3.0); ki=0.1*1.0; rt=0.032805; gain=4.0; emggrens=0.35; friction=0.4; Ai1=0; Ad1=0; Bi1=0; Bd1=0; pc.baud(115200); Aboven=820; Aonder=165; Bboven=10900; Bonder=3400; //Filtercoëfficienten. //High pass, 35Hz, 1e orde, 4 ms. numh1=0.680011076547878; numh2=-0.680011076547878; //denh1=1; denh2=-0.360022153095757; //Low pass, 5 Hz, 2e orde, 4 ms. numl1=0.003621681514929; numl2=0.007243363029857; numl3=0.003621681514929; //denl1=1; denl2=-1.822694925196308; denl3=0.837181651256023; //Low pass, 2 Hz, 2e orde, 1 ms. //numl1=0.391302053991682*pow(10.0,-4.0); //numl2=0.782604107983365*pow(10.0,-4.0); //numl3=0.391302053991682*pow(10.0,-4.0); //denl1=1; //denl2=-1.982228929792529; //denl3=0.982385450614126; //Opzetje voor calibratie wait(4); if(startflag==true); { motor1.setPosition(0); motor2.setPosition(1200); startflag=false; } while(calflag==true) { while(looptimerflag != true); looptimerflag = false; //515 - 3536 voor rechtsonder. refA=515; refB=3536; while(calB==true) { tickb=motor2.getPosition(); errB=refB-tickb; Bp=errB*kpc; Bd=(errB-Bd1)*kdc/ts; Bi=(Bi1+ts*errB)*kic; Bd1=Bd; Bi1=Bi; ctrlB=(Bi+Bp+Bd); for_B=(ctrlB)/1000.0; if(ctrlB<0.0) { Bdir=0; } else { Bdir=1; } keep_in_range(&for_B, -1.0,1.0); if (frictionflag==true) { for_B=abs(for_B)+friction; keep_in_range(&for_B, 0.0,0.1); } pwm_B.write(abs(for_B)); motordirB.write(Bdir); //pc.printf("B %f %i \n\r",for_B,errB); if(errB<10) { calB=false; pwm_B.write(0.0); } } while(calA==true) { ticka=-motor1.getPosition(); //NOTE: deze moet volgens mij gewoon weer positief zijn. errA=refA-ticka; Ap=errA*kpc; Ad=(errA-Ad1)*kdc/ts; Ai=(Ai1+ts*errA)*kic; Ad1=Ad; Ai1=Ai; ctrlA=(Ai+Ap+Ad); for_A=(ctrlA)/1000.0; if(ctrlA<0) { //NOTE: als ticka weer +get is, kan deze weer 0 else 1 zijn. Adir=1; } else { Adir=0; } keep_in_range(&for_A, -1,1); if (frictionflag==true) { for_A=abs(for_A)+friction; keep_in_range(&for_A, 0,0.08); } pwm_A.write(abs(for_A)); motordirA.write(Adir); //pc.printf("A %f %i \n\r",for_A,errA); if(errA<20) { calA=false; pwm_A.write(0); calflag=false; } } } //Einde opzetje. //Loop. wait(1); while(meetflag==true) { while(looptimerflag != true); { } looptimerflag = false; //EMG lezen. ktr=emgtr.read(); xtr=(ktr-0.5)*2.0; ytr=xtr*numh1+x1tr*numh2-y1tr*denh2; yabstr=abs(ytr); ztr=yabstr*numl1+yabs1tr*numl2+yabs2tr*numl3-z1tr*denl2-z2tr*denl3; x1tr=xtr; y1tr=ytr; z2tr=z1tr; z1tr=ztr; yabs2tr=yabs1tr; yabs1tr=yabstr; kbr=emgbr.read(); xbr=(kbr-0.5)*2.0; ybr=xbr*numh1+x1br*numh2-y1br*denh2; yabsbr=abs(ybr); zbr=yabsbr*numl1+yabs1br*numl2+yabs2br*numl3-z1br*denl2-z2br*denl3; x1br=xbr; y1br=ybr; z2br=z1br; z1br=zbr; yabs2br=yabs1br; yabs1br=yabsbr; ktl=emgtl.read(); xtl=(ktl-0.5)*2.0; ytl=xtl*numh1+x1tl*numh2-y1tl*denh2; yabstl=abs(ytl); ztl=yabstl*numl1+yabs1tl*numl2+yabs2tl*numl3-z1tl*denl2-z2tl*denl3; x1tl=xtl; y1tl=ytl; z2tl=z1tl; z1tl=ztl; yabs2tl=yabs1tl; yabs1tl=yabstl; kbl=emgbl.read(); xbl=(kbl-0.5)*2.0; ybl=xbl*numh1+x1bl*numh2-y1bl*denh2; yabsbl=abs(ybl); zbl=yabsbl*numl1+yabs1bl*numl2+yabs2bl*numl3-z1bl*denl2-z2bl*denl3; x1bl=xbl; y1bl=ybl; z2bl=z1bl; z1bl=zbl; yabs2bl=yabs1bl; yabs1bl=yabsbl; //Gains om filter te compenseren. zx=(zbr*gain); zy=(zbl*gain); //Grenzen voor emg. if (zx>1.0) { zx=0.99999; } if (zy>1.0) { zy=0.99999; } if (zx<emggrens) { zx=emggrens; } if (zy<emggrens) { zy=emggrens; } zx=zx-emggrens; zx=zx*(1.0/(1.0-emggrens)); zy=zy-emggrens; zy=zy*(1.0/(1.0-emggrens)); //Richting omdraaien met triceps. if (ztr>0.1 && dirflagx == true) { dirflagx = false; xdir ^= 1; //zx=0; //NOTE: deze weghalen kan schelen? dirtimeout.attach(tricheck,1.0); } if (ztl>0.1 && dirflagy == true) { dirflagy = false; ydir ^= 1; //zy=0; dirtimeout.attach(tricheck,1.0); } //Motoraansturing. if (ydir==0) { zy=-1.0*zy; } if (xdir==1) { //NOTE: moet dit geen 0 zijn? zx=-1.0*zx; } ticka=-1*motor1.getPosition(); //NOTE: -1 weghalen? tickb=motor2.getPosition(); //Begrenzing. vxuit=zx*4.0*pow(10.0,-1.0); // 4cm/s //NOTE: deze shizzle kan er misschien uit. In ieder geval de vier. En anders moet het /1000 zijn. vyuit=zy*4.0*pow(10.0,-2.0); // 4cm/s xuit += ts*vxuit; yuit += ts*vyuit; keep_in_range(&xuit,-4.5,2.75); //NOTE: Iets met de grenzen. En de richtingpins. keep_in_range(&yuit,-4.5,2.8); //NOTE: als bovenstaande weer klopt moeten de grenzen voor x zijn: .125 en 0.422. Voor y is dat 0.125 en 0.335. refA=4123.0*atan2(yuit,xuit)/(2.0*PI); refB=4123.0*sqrt(xuit*xuit+yuit*yuit)/(2.0*PI*rt); keep_in_rangeint(&refA,Aonder,Aboven); keep_in_rangeint(&refB,Bonder,Bboven); errA=refA-ticka; errB=refB-tickb; //Controllers Ap=errA*kp; Ad=(errA-Ad1)*kd/ts; Ai=(Ai1+ts*errA)*ki; //keep_in_range(&Ad,-0.1,0.1); //keep_in_range(&Ai,-0.1,0.1); Ad1=Ad; Ai1=Ai; ctrlA=(Ai+Ap+Ad); for_A=(ctrlA)/700.0; //NOTE: maak eens een plot van ctrlA en ctrlB. Kan leerzaam zijn voor deze gains. Bp=errB*kp; Bd=(errB-Bd1)*kd/ts; Bi=(Bi1+ts*errB)*ki; //keep_in_range(&Bd,-0.1,0.1); //keep_in_range(&Bi,-0.1,0.1); Bd1=Bd; Bi1=Bi; ctrlB=(Bi+Bp+Bd); for_B=(ctrlB)/7000.0; //x en y uit emg in meters. IK naar radialen. dan radialen naar ticks. if(ctrlA<0) { //NOTE: zeker gezien de vorige omdraaiingen moet deze volgens mij weer 0 else 1 zijn. Adir=1; } else { Adir=0; } if(ctrlB<0) { Bdir=0; } else { Bdir=1; } keep_in_range(&for_A, -1.0,1.0); keep_in_range(&for_B, -1.0,1.0); if (frictionflag==true) { for_A=abs(for_A)+friction; for_B=abs(for_B)+friction; keep_in_range(&for_A, 0,1.0); //NOTE: misschien valt hier nog wat te begrenzen, maar dan wel op ondergrens friction. keep_in_range(&for_B, 0,1.0); } motordirA.write(Adir); motordirB.write(Bdir); pwm_A.write(abs(for_A)); pwm_B.write(abs(for_B)); if(pc.txBufferGetSize(0)-pc.txBufferGetCount() > 100) { //pc.printf(" %f %f \n\r",zx, zy); //pc.printf(" %f %i %i %f %i %i\n\r",for_A,ticka,refA,for_B,tickb, refB); pc.printf(" %i %i %i %i %f %f \n\r", ticka,tickb,refA,refB,xuit,yuit); //pc.printf("A %i %i B %i %i\n\r",Adir, ticka,Bdir, tickb); //pc.printf(" %f %f %f %f \n\r",kbl,zy,vyuit,yuit); //pc.printf(" %i %i %i %f\n\r",tickb,refB,errB,for_B); //pc.printf(" %f %f %f %f \n\r",kbl,zy,vyuit, yuit); //pc.printf("A %i %i %i %i %f %f\n\r",ticka,refA,errA,ctrlA,for_A); //pc.printf("tr %f br %f tl %f bl %f\n\r",ztr,zbr,ztl,zbl); //pc.printf("%i\n",motor2.getPosition()); //pc.printf("%f %f\n\r",for_A,for_B); } } while(patroonflag==true) { while(looptimerflag != true); looptimerflag = false; xuit=400.0; yuit=140.0; ticka=-1*motor1.getPosition(); tickb=motor2.getPosition(); refA=4123.0*atan2(yuit,xuit)/(2.0*PI); refB=4123.0*sqrt(xuit*xuit+yuit*yuit)/(2.0*PI*rt*1000.0); errA=refA-ticka; errB=refB-tickb; while(errA>20 && errB>20) { ticka=-1*motor1.getPosition(); tickb=motor2.getPosition(); refA=4123.0*atan2(yuit,xuit)/(2.0*PI); refB=4123.0*sqrt(xuit*xuit+yuit*yuit)/(2.0*PI*rt); errA=refA-ticka; errB=refB-tickb; //Controllers Ap=errA*kpc; Ad=(errA-Ad1)*kdc/ts; Ai=(Ai1+ts*errA)*kic; Ad1=Ad; Ai1=Ai; ctrlA=(Ai+Ap+Ad); for_A=(ctrlA)/1000.0; Bp=errB*kpc; Bd=(errB-Bd1)*kdc/ts; Bi=(Bi1+ts*errB)*kic; Bd1=Bd; Bi1=Bi; ctrlB=(Bi+Bp+Bd); for_B=(ctrlB)/1000.0; if(ctrlA<0) { Adir=0; } else { Adir=1; } if(ctrlB<0) { Bdir=0; } else { Bdir=1; } keep_in_range(&for_A, -1.0,1.0); keep_in_range(&for_B, -1.0,1.0); if (frictionflag==true) { for_A=abs(for_A)+friction; for_B=abs(for_B)+friction; keep_in_range(&for_A, 0,0.08); keep_in_range(&for_B, 0,0.1); } motordirA.write(Adir); motordirB.write(Bdir); pwm_A.write(abs(for_A)); pwm_B.write(abs(for_B)); } wait(1); xuit=400.0; yuit=180.0; while(errA>20 && errB>20) { ticka=-1*motor1.getPosition(); tickb=motor2.getPosition(); refA=4123.0*atan2(yuit,xuit)/(2.0*PI); refB=4123.0*sqrt(xuit*xuit+yuit*yuit)/(2.0*PI*rt*1000.0); //keep_in_rangeint(&refA,Aonder,Aboven); //keep_in_rangeint(&refB,Bonder,Bboven); errA=refA-ticka; errB=refB-tickb; //Controllers Ap=errA*kpc; Ad=(errA-Ad1)*kdc/ts; Ai=(Ai1+ts*errA)*kic; Ad1=Ad; Ai1=Ai; ctrlA=(Ai+Ap+Ad); for_A=(ctrlA)/1000.0; Bp=errB*kpc; Bd=(errB-Bd1)*kdc/ts; Bi=(Bi1+ts*errB)*kic; Bd1=Bd; Bi1=Bi; ctrlB=(Bi+Bp+Bd); for_B=(ctrlB)/1000.0; if(ctrlA<0) { Adir=0; } else { Adir=1; } if(ctrlB<0) { Bdir=0; } else { Bdir=1; } keep_in_range(&for_A, -1.0,1.0); keep_in_range(&for_B, -1.0,1.0); if (frictionflag==true) { for_A=abs(for_A)+friction; for_B=abs(for_B)+friction; keep_in_range(&for_A, 0,0.08); keep_in_range(&for_B, 0,0.1); } motordirA.write(Adir); motordirB.write(Bdir); pwm_A.write(abs(for_A)); pwm_B.write(abs(for_B)); } } } void keep_in_range(double * in, double min, double max) { *in > min ? *in < max? : *in = max: *in = min; } void keep_in_rangeint(int * in, int min, int max) { *in > min ? *in < max? : *in = max: *in = min; }