Blame | Last modification | View Log | RSS feed
/*************************************************************
* *
* Stabilizzazione di un pendolo inverso *
* *
* *
*Written by: Gabriele Bolognini - Scuola S.Anna -- Pisa *
* *
*************************************************************/
#include "demo.h"
#include "pclab.h"
#include "cost.h" /* Contiene le costanti del task DISEGNA */
#ifdef SOFTPROG
long int PERIOD_CARRELLO={1200}, PERIOD_TRACKING={12000};
long int WCET_CARRELLO={240}, WCET_TRACKING={7200};
#else
long int PERIOD_CARRELLO={1800}, PERIOD_TRACKING={22200};
#endif
#define LUNGH 35.0
#define THETAMAX 45.0
#define VDANG 2.4
#define NMAX 300
#define SEC_ID 7.0
#define MAXRUN_ID 9 //16
int start_id=0;
// dati da scrivere nei files
static long int contat_id=-1, num_id=0;
#ifdef DATAPLANT
struct DATA_FILE {
TIME time;
float xist ;
float thist ;
float par1 ;
float par2 ;
float par3 ;
float par4 ;
} dati[NMAX];
long int numdat=0; // numero dati scritti su DATI[NMAX]
#endif
#define NSAMPLES 500
#define NTASKS 10
static float timetab[NSAMPLES][NTASKS];
static int index[NTASKS];
static float somma[MAXRUN_ID][2]; // valore dello indice di prestazione
mutex_t mutex,mutexadc;
#define MAX_TEMPI 15
static char stringa[MAX_TEMPI][250];
// **- ACHTUNG!!!: param. iniz. del guadagno, deadline, ecc.-----******* /
#define INIPARAMS {{ 2.3 , 300 , 0.5 , 15 },1.,1.0,20.,20., 0.1, 1 , 1, 0.}
#define MODPARAMS {{ 1. , 300 , 0.9 , 34 },0.74 ,1.,20.,20., 0.2, 1 , 1, 0.}
#define PARAM2 {{ 1. , 300 , 0.79 , 23 },0.70 ,2.5 ,20.,20., 0.1, 1 , 1, 0.}
/*
struct Parametri{
float GUAD[4];
float COST;
float NOISE;
float WCUT;
float WCUT1;
float OFFSVAL;
int DEADLINE;
int SCAN;
float XTRASL;
};
struct Data_cab1 {
float rif;
int imp;
};
struct Data_cab2 {
float x;
float y;
} ;
*/
struct Parametri prm=PARAM2, prmbase=INIPARAMS, prmmod=MODPARAMS, prm2=PARAM2;
#define DEADSECX(x) ( x /*PERIOD_TRACKING*/ * 1.0e-6 ) // mit task TRACK in sec
#define DEADSECTH(x) (x /*PERIOD_CARRELLO*/ * 1.0e-6 ) // mit task CARRELLO in sec
CAB cab1, cab2;
float vmax, vmin, vmaxth, vminth;
float vin=0, vout, yout, thout;
void graphframe(void);
void my_end(void);
void scritt(void);
void scritt1(void);
void scritt2(void);
void scritt3(void);
void nuovi_tempi(long int*);
void initial(void);
void scenario_jetcontrol(void);
void init_jetcontrol(void);
TASK jetslide_task(void *);
TASK jetctrl_task(void *);
TASK jetdummy_task(void *);
void framegrabber_close(void *);
TASK camera_task(void *);
TASK tracking_task(void *);
extern int white, black, red, gray, green, blue;
float integrale(float y[], float u, int flag)
{
static float sum=0, oldcoeff=0;
float coeff=0 ;
static float R=1 , Q[2][2]={1,0,0,1.5} ;
if(flag) sum=0; //reset
coeff=Q[0][0]*y[0]*y[0]+Q[0][1]*y[0]*y[1]+Q[1][0]*y[1]*y[0]+Q[1][1]*y[1]*y[1]+R*u*u;
sum += (coeff+oldcoeff)*DEADSECTH(PERIOD_CARRELLO) / 2.0 ;
oldcoeff=coeff;
return sum;
}
void zerofun(KEY_EVT *k)
{
int i;
for (i=0; i<MAX_PROC; i++) jet_delstat(i);
}
int da_motor(float v)
{
da_conv( 2.5 , 2 );
da_conv( v + 2.5 , 1 );
return(0);
}
float v2x(float v)
{ /* trasforma i volt in x */
float x;
x= LUNGH * (v-(vmax+vmin)/2 ) / (vmax-vmin);
return x;
}
float v2theta(float v)
{ /* trasforma i volt in angoli */
float theta;
theta=2.0*(THETAMAX/FCA) * (v-(vmaxth+vminth)/2 ) / (vmaxth-vminth);
return theta;
}
float bass1(float u)
{
float y;
static float oldy=0;
y=(oldy + prm.WCUT * DEADSECX(PERIOD_TRACKING) *u)/(1+ prm.WCUT * DEADSECX(PERIOD_TRACKING));
oldy=y;
return y;
}
float bass2(float u)
{
float y;
static float oldy=0;
y=(oldy + prm.WCUT1 * DEADSECX(PERIOD_TRACKING) *u)/(1+ prm.WCUT1 * DEADSECX(PERIOD_TRACKING));
oldy=y;
return y;
}
float bass3(float u)
{
float y;
static float oldy=0;
y=(oldy + prm.WCUT * DEADSECTH(PERIOD_CARRELLO) *u)/(1+ prm.WCUT * DEADSECTH(PERIOD_CARRELLO));
oldy=y;
return y;
}
float bass4(float u)
{
float y;
static float oldy=0;
y=(oldy + prm.WCUT1 * DEADSECTH(PERIOD_CARRELLO) *u)/(1+ prm.WCUT1 * DEADSECTH(PERIOD_CARRELLO));
oldy=y;
return y;
}
float dx(float u)
{
static float oldu=0;
float y;
y=(u-oldu)/DEADSECX(PERIOD_TRACKING);
oldu=u;
return y;
}
float dth(float u)
{
static float oldu=0;
float y;
y=(u-oldu)/DEADSECTH(PERIOD_CARRELLO);
oldu=u;
return y;
}
TASK eval(void)
{
int x,y;
char str[100];
mutex_lock(&mutex);
grx_rect(10,325,XTI - 20,479,blue);
x = 20;
y = 350;
grx_text("PARAMETRI DI CONTROLLO ( R , T ) ", x+60, y-18 , red, 0);
grx_text("Guad=", x, y,green, 0);y+=18;
grx_text("Cost=", x, y,green, 0); y+=18;
grx_text("WCUT=", x, y,green, 0); y+=18;
grx_text("WCUT1=", x, y,green, 0); y+=18;
grx_text("NOISE=", x, y,green, 0); y+=18;
grx_text("DEADL=", x, y,green, 0);y+=18;
grx_text("OFFS=", x, y,green, 0);y+=18;
{ /* legenda */
int x=280, y=350;
grx_text("Guad 1,2 3,4 5,6 7,8", x, y,green, 0);y+=18;
grx_text("Cost [ , ]", x, y,green, 0); y+=18;
grx_text("WCUT o , p", x , y,green, 0); y+=18;
grx_text("WCUT1 k , l", x, y,green, 0); y+=18;
grx_text("NOISE n , m", x, y,green, 0); y+=18;
grx_text("DEADL - , +", x, y,green, 0);y+=18;
grx_text("OFFS / , *", x, y,green, 0);y+=18;
}
{ /* frame dei valori rilevati dai sensori */
int x=15, y=YTI+10;
grx_rect(10,YTI,XTI - 20,YTI+70,red);
grx_text("V_com = ", x, y,green, 0);y+=14;
grx_text("V+offs = ", x, y,green, 0);y+=14;
grx_text("V_sens_x = ", x, y,green, 0);y+=14;
grx_text("SCAN = ", x, y,green, 0);y+=14;
}
mutex_unlock(&mutex);
while(1){
x = 70;
y = 350;
mutex_lock(&mutex);
grx_text(" ", x, y, 12, 0);
sprintf(str, "%6.2f %6.2f %6.2f %6.2f ", prm.GUAD[0],prm.GUAD[1],prm.GUAD[2],prm.GUAD[3]);
grx_text(str, x, y, blue, 0);y+=18;
grx_text(" ", x, y, 12, 0);
sprintf(str, "%6.2f ", prm.COST);
grx_text(str, x, y, blue, 0); y += 18;
grx_text(" ", x, y, 12, 0);
sprintf(str, "%6.2f Hz", prm.WCUT);
grx_text(str, x, y, blue, 0); y += 18;
grx_text(" ", x, y, 12, 0);
sprintf(str, "%6.2f Hz ", prm.WCUT1);
grx_text(str, x, y, blue, 0); y += 18;
grx_text(" ", x, y, 12, 0);
sprintf(str, "%6.2f Volt ", prm.NOISE);
grx_text(str, x, y, blue, 0); y += 18;
grx_text(" ", x, y, 12, 0);
sprintf(str, "%d ticks ", prm.DEADLINE);
grx_text(str, x, y, blue, 0); y += 18;
grx_text(" ", x, y, 12, 0);
sprintf(str, "%6.2f Volt ", prm.OFFSVAL);
grx_text(str, x, y, blue, 0); y += 18;
mutex_unlock(&mutex);
/* scrivo vin , vout (vin+offs) , SCAN e PARAMETRIBASE*/
{ int x=95, y= YTI + 10;
mutex_lock(&mutex);
grx_text(" ", x, y, 0, 0);
sprintf(str, "%7.4f ", vin);
grx_text(str, x, y, blue, 0);y += 14;
grx_text(" ", x, y, 0, 0);
sprintf(str, "%7.4f", vout);
grx_text(str, x, y, blue, 0);y += 14;
grx_text(" ", x, y, 0, 0);
sprintf(str, "%7.3f", yout);
grx_text(str, x, y , blue, 0); y += 14;
grx_text(" ", x, y, 0, 0);
sprintf(str, "%3.2d c , v", prm.SCAN);
grx_text(str, x, y , blue, 0); y += 14;
mutex_unlock(&mutex);
}
task_endcycle();
}
}
/*------------------------------------------------------------------------
Il task CARRELLO controlla la posizione del carrello
y = posizione angolare dell'asta (non usata)
x = posizione lineare del carrello
-----------------------------------------------------------------------*/
float xrif=0, orif=1;
TASK carrello(void)
{
float thist=0, y[2]={0,0}, yp[2]={0,0}; /* valori attuali */
PORT pa, pb; /* communication ports */
struct Data_cab1 data;
struct Data_cab2 tmp;
char *pun, *pun2;
int i;
float offset;
long int k=0;
long int stime =0 ;
/* Si creano 2 per mandare al task DISEGNA le var.di stato x1 e x3 */
pa = port_create("porta1",sizeof(float),1,STICK,WRITE);
pb = port_create("porta2",sizeof(float),1,STICK,WRITE);
while (1) {
/* prendo i dati sul riferimento in volt per la x */
pun = cab_getmes(cab1);
memcpy(&data, pun, sizeof(struct Data_cab1));
cab_unget(cab1, pun);
/* prendo i dati sulle posizioni dal trasduttore ADC */
task_nopreempt();
thout=ad_conv(10);
task_preempt();
/* taglio brusco dei livelli di rumore sopra il NOISE */
{
#define AVR 10
static float othout[AVR];
float avth;
static int index=0, flag=1;
if(flag==1) {
for(i=0; i<AVR;++i) { othout[i] = thout;}
flag=0;
}
avth=0;
for(i=0;i<AVR;++i) { avth += othout[i]; }
avth /= AVR ;
if(fabs(thout-avth)>=prm.NOISE) { thout=avth;}
othout[index]=thout;
index = (index+1) % AVR ;
}
/* converto i valori dei sensori in posizioni */
/* calcolo le velocita' lineari e angolari opportunamente filtrate */
thist=v2theta(thout);
y[1]=bass3(thist);
yp[1] = bass4(dth(y[1]));
/* a questo punto dovrei prendere i valori dall'altro task CARR2 */
pun2 = cab_getmes(cab2);
memcpy(&tmp , pun2, sizeof(struct Data_cab2));
cab_unget(cab2, pun2);
y[0]=yout=tmp.x;
yp[0]=tmp.y;
/* PARAMETRI del controllore :1 */
vin = prm.COST * (prm.GUAD[0] * (y[0]-v2x(data.rif+prm.XTRASL))+ prm.GUAD[1] * thist + prm.GUAD[2] * yp[0] + prm.GUAD[3] * yp[1]) ;
/* metto un offset che mi elimina l'attrito */
if( vin >= 0) offset=prm.OFFSVAL;
else offset=-prm.OFFSVAL;
vout=vin+offset;
if(vout >= VDANG ) vout = VDANG ;
if(vout <= -VDANG ) vout = -VDANG ;
/* la applico */
da_motor(vout);
/* mando i dati sulle posizioni al task DISEGNA */
port_send(pa, &y[1], NON_BLOCK);
port_send(pb, &y[0], NON_BLOCK);
{
char str[5];
static long int contatwait=-1;
// extern float xrif;
if(start_id == 1) {
start_id=0;
contat_id=(int) (SEC_ID / DEADSECTH(PERIOD_CARRELLO));
num_id++;
somma[num_id-1][1]=contat_id;
integrale(y,vout,1);
contatwait=(long int) (1.5 * SEC_ID / DEADSECTH(PERIOD_CARRELLO));
}
if(contat_id > 0) {
xrif=0.0; //pone la xrif a zero
somma[num_id-1][0]=integrale(y,vout,0);
somma[num_id-1][1]= --contat_id;
}
if(contat_id == 0) {
if(num_id>= (MAXRUN_ID-1)) nuovi_tempi(&contatwait); //sys_end();
xrif=-10.0;
contatwait--; if(contatwait==0) start_id=1;//attiva la racc. dati
}
if(contat_id == -1 ) ; // vero solo allo inizio del programma
}
/* aggiorno i riferimenti utilizzati in questo task, piu' in alto*/
data.rif=(vmax+vmin)/2. + xrif * (vmax-vmin)/LUNGH;
data.imp=0;
pun = cab_reserve(cab1);
memcpy(pun, &data, sizeof(struct Data_cab1));
cab_putmes(cab1, pun);
/* scrivo i dati istantanei (fino a NMAX) nella struttura 'dati' */
#ifdef DATAPLANT
if((contat_id>0)&&(k<(NMAX-1))) {
dati[k].time=sys_gettime(NULL)/1000;
dati[k].xist=y[0];
dati[k].thist=thist;
dati[k].par1=vout;
dati[k].par2=yp[0];
dati[k].par3=yp[1];
dati[k].par4=thist*FCA;
numdat=k++;
}
#endif
task_endcycle();
}
/* Eliminazione porte di comunicazione */
port_delete(pa);
port_delete(pb);
} /* FINE DEL TASK CARRELLO */
/*--------------------------------------------------------------*/
/* Il task DISEGNA riceve dal task CONTROLLO i valori delle */
/* variabili x1 e x3 e disegna il pendolo corrispondente */
/*--------------------------------------------------------------*/
TASK diseg(void)
{
WORD xp, yp, oxp, oyp; /* coordinate carrello */
WORD xa, ya, oxa, oya; /* coordinate asta */
float x1, x3; /* variabili di stato */
char str[100];
PORT pra, prb, prc; /* communication ports */
int delta; /* dimensione finestre */
/* Connessione alle porte create dal task CONTROLLO */
pra = port_connect("porta1",sizeof(float),STICK,READ);
prb = port_connect("porta2",sizeof(float),STICK,READ);
delta = 120;
/* Inizializzazione variabili carrello e asta */
xp = oxp = 100;
xa = oxa = 100;
yp = oyp = 105 + delta - H;
ya = oya = 105 + delta - H;
graphframe();
while (1) {
/*if(contat_id==0)*/ {
char str1[15];
mutex_lock(&mutex);
grx_text(" ", XTI, YTI+174, 0, 0);
sprintf(str1, "%d ", contat_id);
grx_text(str1, XTI, YTI+174, red, 0);
grx_text(" ", XTI, YTI+188, 0, 0);
sprintf(str1, "%d ", num_id);
grx_text(str1, XTI, YTI+188,green , 0);
grx_text(" ", XTI, YTI+202, 0, 0);
sprintf(str1, "%f ", somma[num_id-1][0]);
grx_text(str1, XTI, YTI+202,green , 0);
grx_text(" ", XTI, YTI+216, 0, 0);
sprintf(str1, "carr= %d %d %f", PERIOD_CARRELLO, WCET_CARRELLO, ((float) WCET_CARRELLO) / PERIOD_CARRELLO );
grx_text(str1, XTI, YTI+216,green , 0);
grx_text(" ", XTI, YTI+230, 0, 0);
sprintf(str1, "track= %d %d %f", PERIOD_TRACKING, WCET_TRACKING, ((float) WCET_TRACKING) / PERIOD_TRACKING );
grx_text(str1, XTI, YTI+230,green , 0);
mutex_unlock(&mutex);
}
/* disegna il pendolo */
port_receive(pra, &x1, BLOCK);
port_receive(prb, &x3, BLOCK);
/* scrivo posizione del carrello e angolo dell'asta */
mutex_lock(&mutex);
grx_text(" ", XTI+45, YTI+28, 0, 0);
sprintf(str, "%5.2f", x3);
grx_text(str, XTI+45, YTI+28, blue, 0);
grx_text(" ", XTI+50, YTI+42, 0, 0);
sprintf(str, "%4.3f", x1 * FCA );
grx_text(str, XTI+50, YTI+42, blue, 0);
mutex_unlock(&mutex);
/* calcolo ascissa del punto P del carrello */
xp = XMED + x3 * SGX;
/* calcolo ascissa e ordinata dell'estremo dell'asta */
xa = xp + LA * sin((double)(x1 * SGA));
ya = yp - LA * cos((double)(x1 * SGA));
mutex_lock(&mutex);
/* cancella e disegna il carrello */
grx_box(oxp-LC,oyp,oxp+LC,oyp+H,0);
grx_box(xp-LC,yp,xp+LC,yp+H,blue);
/* cancella e disegna la ruota sinistra del carrello */
grx_circle(oxp-LC+8,oyp+H+4,RAGGIO+2,0);
grx_circle(xp-LC+8,yp+H+4,RAGGIO+2,green);
/* cancella e disegna la ruota destra del carrello */
grx_circle(oxp+LC-8,oyp+H+4,RAGGIO+2,0);
grx_circle(xp+LC-8,yp+H+4,RAGGIO+2,green);
/* cancella e disegna l'asta */
grx_line(oxp,oyp,oxa,oya,0);
grx_line(xp,yp,xa,ya,red);
/* cancella e disegna la pallina sull'asta */
grx_circle(oxa,oya,RAGGIO,0);
grx_circle(xa,ya,RAGGIO,blue);
mutex_unlock(&mutex);
/* aggiornamento variabili */
oxp = xp;
oyp = yp;
oxa = xa;
oya = ya;
task_endcycle();
}
port_disconnect(pra);
port_disconnect(prb);
port_disconnect(prc);
} /* FINE TASK DISEGNA */
TASK query(void)
{
char c, str[100];
int count = 0;
char *pun;
struct Data_cab1 data={0,0};
while(1)
{
do {
c = keyb_getch(BLOCK);
switch (c) {
case 'd': xrif += 1; break;
case 's': xrif -= 1; break;
case 'D': xrif=7; break;
case 'S': xrif=-7; break;
case '0': xrif =0 ; break;
case '1': prm.GUAD[0] -= 0.1 ; break;
case '2': prm.GUAD[0] += 0.1; break;
case '3': prm.GUAD[1] -= 10 ; break;
case '4': prm.GUAD[1] += 10 ; break;
case '5': prm.GUAD[2] -= 0.05; break;
case '6': prm.GUAD[2] += 0.05; break;
case '7': prm.GUAD[3] -= 0.5; break;
case '8': prm.GUAD[3] += 0.5; break;
case 'o': prm.WCUT -= 2. ; break;
case 'p': prm.WCUT += 2. ; break;
case 'k': prm.WCUT1 -= 2. ; break;
case 'l': prm.WCUT1 += 2. ; break;
case 'n': prm.NOISE -= 0.1; break;
case 'm': prm.NOISE += 0.1; break;
case '/': prm.OFFSVAL -= 0.1; break;
case '*': prm.OFFSVAL += 0.1; break;
case '[': prm.COST -= 0.02; break;
case ']': prm.COST += 0.02; break;
case 'c': prm.SCAN -= 1; break;
case 'v': prm.SCAN += 1; break;
case 'R': prm = prmbase; break;
case 'T': prm = prmmod; break;
case 'U': prm = prm2; break;
case '<': prm.XTRASL -= .05; break;
case '>': prm.XTRASL += .05; break;
case '!': start_id=1; break;
case '@': if(num_id>0) num_id--; break;
default: break;
}
data.rif=(vmax+vmin)/2. + xrif * (vmax-vmin)/LUNGH;
/* controllo che il riferim non vada fuori scala massima */
if (data.rif > vmax) data.rif = vmax;
if (data.rif < vmin) data.rif = vmin;
/* controllo l'impulso */
if (count>0) count--;
if (data.imp != 0 && count==0) data.imp = 0;
/* scrivo sul cab1 i riferim ( rif + imp) per il carrello */
pun = cab_reserve(cab1);
memcpy(pun, &data, sizeof(struct Data_cab1));
cab_putmes(cab1, pun);
/* si visualizza il riferimento del carrello. */
if (xrif != orif) {
orif = xrif;
mutex_lock(&mutex);
grx_text(" ", XTI+45, YTI+14, 0, 0);
sprintf(str, "%2.1f cm.", xrif);
grx_text(str, XTI+55, YTI+14, green, 0);
mutex_unlock(&mutex);
}
} while (c != 27);
sys_end();
task_endcycle();
}
}
int printglob;
TASK timejet(void *arg)
{
TIME table[JET_TABLE_DIM];
int k, nistan;
PID i;
int printed;
while(1) {
for (i=2, printed=0; i<NTASKS ; i++) {
if ( (nistan=jet_gettable(i,(TIME *) table, -1)) != -1) {
for(k=0;k<nistan;k++){
if(index[i] >= NSAMPLES) break;
if( i>=NTASKS ) {grx_close();perror("Ntask too high for jet");sys_end();}
timetab[ index[i] ][i] = (float) table[k];
index[i]++;
}
printed++;
}
}
printglob=printed;
task_endcycle();
}
}
/****************** * MAIN * ******************************/
PID pc,pc2, pd, pe, pq, pt;
PID camera_PID;
PID tracking_PID;
void main(int argc, char **argv)
{
int modenum;
HARD_TASK_MODEL m;
SOFT_TASK_MODEL ms, md, mt;
SOFT_TASK_MODEL m1, m2;
HARD_TASK_MODEL m3;
white = rgb16(255,255,255);
black = rgb16(0,0,0);
red = rgb16(255,0,0);
gray = rgb16(128,128,128);
green = rgb16(0,255,0);
blue = rgb16(0,0,255);
#ifdef SOFTPROG
if(argc!=4) {perror("numero di parametri errato. Rilancia");keyb_getchar();sys_end();}
PERIOD_TRACKING=atol(argv[1]);
PERIOD_CARRELLO=atol(argv[2]);
WCET_TRACKING =(long int) PERIOD_TRACKING *( 1.0 - (atof(argv[3])) - 0.2) ;
WCET_CARRELLO =(long int) PERIOD_CARRELLO * ( atof(argv[3]));
#else
if(argc!=3) {perror("numero di parametri errato. Rilancia");keyb_getchar();sys_end();}
PERIOD_TRACKING=atol(argv[1]);
PERIOD_CARRELLO=atol(argv[2]);
#endif
sys_atrunlevel((void *) my_end,NULL, RUNLEVEL_BEFORE_EXIT);
#ifdef TIMEJET
sys_atrunlevel((void *) scritt,NULL, RUNLEVEL_AFTER_EXIT);
#endif
#ifdef DATAPLANT
sys_atrunlevel((void *) scritt1,NULL, RUNLEVEL_AFTER_EXIT);
#endif
sys_atrunlevel((void *) scritt2,NULL, RUNLEVEL_AFTER_EXIT);
sys_atrunlevel((void *) scritt3,NULL, RUNLEVEL_AFTER_EXIT);
modenum = grx_getmode(800, 600, 16);
if (modenum == -1) {
cprintf("Errore in grx_mode");
sys_end();
exit(2);
}
if (grx_setmode(modenum) == -1) {
cprintf("Non posso andare in modo grafico");
sys_end();
exit(3);
}
init_framegrabber();
{ char str[50];
sprintf(str, "CARRELLO = %d TRACK = %d ", PERIOD_CARRELLO, PERIOD_TRACKING);
grx_text(str, 20 , 20 , green, 0);
grx_text("Premi un tasto per continuare", 20 , 30 , green, 0);
keyb_getchar();
grx_text(" ", 20 , 20 , black, 0);
grx_text(" ", 20 , 30 , black, 0);
}
initial();
app_mutex_init(&mutex);
scenario_jetcontrol();
{
KEY_EVT k;
k.flag = ALTL_BIT;
k.scan = KEY_C;
k.ascii = 'c';
keyb_hook(k,zerofun);
}
/* Creazione dei CAB */
cab1 = cab_create("cab1", sizeof(struct Data_cab1), 3);
cab2 = cab_create("cab2", sizeof(struct Data_cab2), 3);
/* Creazione dei task */
#ifdef SOFTPROG
soft_task_default_model(m1);
soft_task_def_level(m1,1);
soft_task_def_met(m1,WCET_TRACKING);
soft_task_def_usemath(m1);
soft_task_def_period(m1,(PERIOD_TRACKING));
soft_task_def_group(m1,1);
soft_task_def_ctrl_jet(m1);
// soft_task_def_skip_arrivals(m1);
tracking_PID = task_create("track", tracking_task, &m1, NULL);
if (tracking_PID == -1) {
sys_end();
exit(4);
}
#else
hard_task_default_model(m3);
//hard_task_def_level(m3,1);
hard_task_def_wcet(m3,WCET_TRACKING);
hard_task_def_mit(m3,(PERIOD_TRACKING));
hard_task_def_usemath(m3);
hard_task_def_group(m3,1);
hard_task_def_ctrl_jet(m3);
tracking_PID = task_create("track", tracking_task, &m3, NULL);
if (tracking_PID == -1) {
sys_end();
exit(4);
}
#endif
soft_task_default_model(m2);
soft_task_def_level(m2,1);
soft_task_def_met(m2,WCET_CAMERA);
soft_task_def_usemath(m2);
soft_task_def_period(m2,PERIOD_CAMERA);
soft_task_def_group(m2,1);
soft_task_def_ctrl_jet(m2);
camera_PID = task_create("cam", camera_task, &m2, NULL);
if (camera_PID == -1) {
sys_end();
exit(4);
}
hard_task_default_model(m);
hard_task_def_mit(m, PERIOD_CARRELLO );
hard_task_def_wcet(m,WCET_CARRELLO );
hard_task_def_group(m,2);
hard_task_def_ctrl_jet(m);
hard_task_def_usemath(m);
soft_task_default_model(ms);
soft_task_def_period(ms, PERIOD_CARRELLO );
soft_task_def_met(ms,WCET_CARRELLO );
soft_task_def_group(ms,2);
soft_task_def_ctrl_jet(ms);
soft_task_def_usemath(ms);
soft_task_default_model(md);
soft_task_def_level(md,1);
soft_task_def_period(md,PERIOD_DESIGN);
soft_task_def_met(md, WCET_DESIGN);
soft_task_def_group(md, 2);
soft_task_def_ctrl_jet(md);
soft_task_def_usemath(md);
#ifdef TIMEJET
soft_task_default_model(mt);
soft_task_def_level(mt,1);
soft_task_def_period(mt,PERIOD_TIMEJET);
soft_task_def_met(mt, WCET_TIMEJET);
soft_task_def_group(mt, 2);
soft_task_def_ctrl_jet(mt);
soft_task_def_usemath(mt);
#endif
#ifndef TIMEJET
init_jetcontrol();
#else
pt = task_create("timejet",(TASK) timejet,&md,NULL);
if (pt == -1) {
sys_end();
exit(4);
}
#endif
#ifdef SOFTPROG
pc = task_create("carrello",(TASK) carrello, &ms, NULL);
if (pc == -1) {
sys_end();
exit(4);
}
#else
pc = task_create("carrello",(TASK) carrello, &m, NULL);
if (pc == -1) {
sys_end();
exit(4);
}
#endif
pe = task_create("eval",(TASK) eval,&md, NULL);
if (pe == -1) {
sys_end();
exit(4);
}
pd = task_create("diseg",(TASK) diseg,&md,NULL);
if (pd == -1) {
sys_end();
exit(4);
}
pq = task_create("query",(TASK) query,&md,NULL);
if (pq == -1) {
sys_end();
exit(4);
}
/* Attivo i task per controllare e disegnare il carrello */
#ifdef TIMEJET
task_activate(pt);
#endif
// task_activate(pc2);
task_activate(pd);
task_activate(pc);
task_activate(pe);
task_activate(pq);
group_activate(1);
}
/****************************************************************/
/* initial */
/****************************************************************/
void initial(void)
{
int x, y;
grx_rect(1, 1, 639, 243, blue); /* dialog box pendolo */
da_motor(0.);
x = 10;
y = YTI;
grx_text("INIZIALIZZ.", x, y, blue, 0); y += 42;
grx_text("Carr a sx e premi un tasto", x, y, green, 0);y += 28;
keyb_getchar();
vmin=ad_conv(11);
grx_text("Carr a dx e premi un tasto",x,y,green,0); y += 28;
keyb_getchar();
vmax=ad_conv(11);
grx_text("Asta a sx e premi un tasto", x, y, green, 0);y += 28;
keyb_getchar();
vminth=ad_conv(10);
grx_text("Asta a dx e premi un tasto", x, y, green, 0);y += 28;
keyb_getchar();
vmaxth=ad_conv(10);
grx_text("Premi 'y' per l' identificazione ", x, y, green, 0);y += 28;
keyb_getchar();
grx_clear(0);
}
/****************************************************************/
/* graphframe */
/****************************************************************/
void graphframe(void)
{
int x, y;
mutex_lock(&mutex);
grx_rect(XTI-15,245,639,479,blue); /* finestra di stato */
grx_rect(1, 1, 450 /*639*/, 243, blue); /* dialog box pendolo */
x = XTI;
y = YTI;
grx_text("PENDOLO", x, y, red, 0); y += 14;
grx_text("Rif.:", x, y, green, 0); y += 14;
grx_text("X =", x, y, green, 0); y += 14;
grx_text("Ang =", x, y, green, 0); y += 14;
grx_text("s sx, d dx", x, y, green, 0); y += 14;
grx_text("S: xrif-> -7 ", x, y, green, 0); y += 14;
grx_text("D: xrif-> +7 ", x, y, green, 0); y += 14;
grx_text("0: xrif-> 0 ", x, y, green, 0); y += 14;
grx_text("S imp-,D imp+", x, y, green, 0); y += 14;
grx_text("CALIBRAZ: < , >", x, y, green, 0); y += 14;
grx_text("Dati Start: !", x, y, green, 0); y += 14;
grx_text("Cancel Last: @", x, y, green, 0); y += 14;
mutex_unlock(&mutex);
}
/*--------------------------------------------------------------*/
/* This function is called at system termination */
/*--------------------------------------------------------------*/
void my_end(void)
{
da_motor(0.0);
grx_close();
// sys_status(CLOCK_STATUS|SCHED_STATUS);
sys_end();
}
/*--------------------------------------------------------------*/
/* This function writes the data in the file DATA */
/*--------------------------------------------------------------*/
void scritt(void)
{
DOS_FILE *file;
long int i , k;
char str[500];
file = DOS_fopen("data","w");
#if 1
for(i=2;i<NTASKS;i++) {
sprintf(str,"%s ",proc_table[i].name);
cprintf("%s", str);
DOS_fwrite(str,1,strlen(str) ,file);
}
DOS_fwrite("\n",1,1,file);
cprintf("%s", "\n");
#endif
for(k=0;k<NSAMPLES;k++){
for(i=2;i<NTASKS;i++) {
sprintf(str,"%f ",timetab[k][i]);
cprintf("%s", str);
// keyb_getchar();
DOS_fwrite(str,1,strlen(str) ,file);
}
DOS_fwrite("\n",1,1,file);
cprintf("%s", "\n");
}
DOS_fclose(file);
}
#ifdef DATAPLANT
void scritt1(void)
{
DOS_FILE *file;
char str[300];
long int i;
float pippy=3.14;
file = DOS_fopen("dataplant","w");
for(i=0;i<numdat;i++) {
sprintf(str,"%lu %f %f %f %f %f %f \n",dati[i].time , dati[i].xist,dati[i].thist,dati[i].par1, dati[i].par2, dati[i].par3, dati[i].par4 );
cprintf("%lu %f %f %f %f %f %f \n",dati[i].time , dati[i].xist,dati[i].thist,dati[i].par1, dati[i].par2, dati[i].par3, dati[i].par4 );
if(DOS_fwrite(str,1,strlen(str),file)==0) perror("Errore in write");
}
DOS_fclose(file);
}
#endif
void scritt2(void)
{
DOS_FILE *file;
char tmp[15]={0}, str[250];
int i;
float parz=0.0 , average=0.0, sumsq=0.0, confid_int=0.0;
float t_stud[20]={0.0, 6.314,2.920,2.353,2.132,2.015,1.943,1.895,1.860,\
1.833,1.812,1.796,1.782,1.771,1.761,1.753,1.746,1.740,1.734,1.729};
file = DOS_fopen("integrale","wa");
for(i=0;i<num_id;i++) {
sprintf(tmp,"%f %f \n",somma[i][0],somma[i][1]);
strcat(str,tmp);
}
for(i=0;i<num_id;i++) parz += somma[i][0];
average=parz /num_id;
for(i=0;i<num_id;i++) sumsq +=(average-somma[i][0])*(average-somma[i][0]);
confid_int= t_stud[num_id-1]*sqrt((double) sumsq/((float) num_id*(num_id-1)));
sprintf(tmp,"n.run=%d aver=%f confid_int=%f \n",num_id,average,confid_int);
strcat(str,tmp);
if(DOS_fwrite(str,1,strlen(str),file)==0) perror("Errore in write");
DOS_fclose(file);
file = DOS_fopen("intdata","wa");
sprintf(str,"%d %d %f %f %d %d %d \n",PERIOD_CARRELLO, PERIOD_TRACKING,average,confid_int, num_id,WCET_CARRELLO, WCET_TRACKING );
// strcat(str,tmp);
if(DOS_fwrite(str,1,strlen(str),file)==0) perror("Errore in write");
DOS_fclose(file);
}
void nuovi_tempi(long int * contatwait)
{
int i;
float parz=0.0 , average=0.0, sumsq=0.0, confid_int=0.0;
float t_stud[20]={0.0, 6.314,2.920,2.353,2.132,2.015,1.943,1.895,1.860,\
1.833,1.812,1.796,1.782,1.771,1.761,1.753,1.746,1.740,1.734,1.729};
static int num_tempi=0;
// calcolo la media e lo interv di confidenza
for(i=0;i<num_id;i++) parz += somma[i][0];
average=parz /num_id;
for(i=0;i<num_id;i++) sumsq +=(average-somma[i][0])*(average-somma[i][0]);
confid_int= t_stud[num_id-1]*sqrt((double) sumsq/((float) num_id*(num_id-1)));
// scrivo i dati relativi alrun in una matrice globale
sprintf(stringa[num_tempi],"%d %d %f %f %d %d %d \n",PERIOD_CARRELLO, PERIOD_TRACKING,average,confid_int, num_id,WCET_CARRELLO, WCET_TRACKING );
num_tempi++;
if(num_tempi >= MAX_TEMPI) sys_end();
// cambio i periodi-banda dei tasks
{
double band;
band=((float) WCET_CARRELLO)/PERIOD_CARRELLO;
PERIOD_CARRELLO = PERIOD_CARRELLO; // + 500;
PERIOD_TRACKING = PERIOD_TRACKING; // +2000;
band+=0.1;
WCET_CARRELLO = band * PERIOD_CARRELLO;
WCET_TRACKING = ( 0.8 - band) * PERIOD_TRACKING;
}
CBS_modify_bandwidth(pc,(TIME) PERIOD_CARRELLO,(int) WCET_CARRELLO);
CBS_modify_bandwidth(tracking_PID,(TIME) PERIOD_TRACKING,(int) WCET_TRACKING);
// resetto le variabili per il run successivo
num_id=0;
*contatwait=(long int) (1.5 * SEC_ID / DEADSECTH(PERIOD_CARRELLO));
}
void scritt3(void)
{
DOS_FILE *file;
char tmp[1000]={0};
int i;
file = DOS_fopen("totaldata","wa");
for(i=0;i<MAX_TEMPI;i++) {
if(DOS_fwrite(stringa[i],1,strlen(stringa[i]),file)==0) perror("Errore in write");
// strcat(tmp, stringa[i][0]);
}
// if(DOS_fwrite(tmp,1,strlen(tmp),file)==0) perror("Errore in write");
DOS_fclose(file);
}