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;
}
