Go to most recent revision |
Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
/*
* Project: S.Ha.R.K.
*
* Coordinators:
* Giorgio Buttazzo <giorgio@sssup.it>
* Paolo Gai <pj@gandalf.sssup.it>
*
* Authors :
* Bera Marco mbera@libero.it
* Varasio Gabriele varasio@odino.unipv.it
*
* Universita' degli studi di Pavia
*
* http://www.sssup.it
* http://retis.sssup.it
* http://shark.sssup.it
*/
/**
------------
CVS : $Id: tel.c,v 1.1.1.1 2004-05-24 18:03:39 giacomo Exp $
File: $File$
Revision: $Revision: 1.1.1.1 $
Last update: $Date: 2004-05-24 18:03:39 $
------------
**/
/*
* Copyright (C) 2000 Paolo Gai and Giorgio Buttazzo
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
/****************************************************************/
/* PERIODIC PROCESS TEST */
/****************************************************************/
#include <ll/i386/x-dos.h>
#include <kernel/kern.h>
#include <modules/cabs.h>
#include <drivers/glib.h>
#include <drivers/keyb.h>
#include <math.h>
#include <semaphore.h>
#include <stdlib.h>
#include "moon.h"
#define N_MAX_TELESCOPI 5
#define X0 10
#define pi 3.14
#define ex 2.71
#define NCAB N_MAX_TELESCOPI+1
#define dim_msg 8
#define dim_x 49
#define dim_y 49
#define radius 9
#define Y_TELESCOPI 300
/* task periods */
#define PERIOD_T1 80000
#define PERIOD_T4 100000
#define PERIOD_T5 100000
#define WCET_T 5000
int period_t1
=0;
#define SOGLIA 8
char *cname
[NCAB
] = {"cab1", "cab2", "cab3", "cab4","cab5","cab6"};
// posizioni dei telescopi e rispettivi poli
int x
[5] = {100, 200, 300, 400,500};
//double poli[5]={-50,-30,-1, -20, -5};
double poli
[5];
// guadagno proporzionale
double kp
=0.0;
// flag per rilevare la pressione del tasto spazio
int numero_telescopi
=0;
int flag
=0;
KEY_EVT move_tasto
;
// Immagini ausiliarie per il disegno della luna
BYTE lunabkg
[900];
BYTE lunadest
[900];
/* A semaphore used to access Video Cards in mutual exclusion */
sem_t mutex
;
sem_t mutex_tasto
;
/***************************************************************/
// cab necessari allo scambio delle coordinate dell'oggetto e delle
// immagini dei rispettivi telescopi
CAB cid
[NCAB
];
// vettori per memorizzare le immagini
BYTE videobuf
[dim_x
*dim_y
];
BYTE videobuf1
[dim_x
*dim_y
];
BYTE videobuf2
[dim_x
*dim_y
];
BYTE videobuf3
[dim_x
*dim_y
];
BYTE videobuf4
[dim_x
*dim_y
];
BYTE videobuf5
[dim_x
*dim_y
];
// Variabili per il disegno delle stelle sullo sfondo
int num_p
;
int y_p
[7];
int x_p
[7];
int dim_p
[7];
int col_p
[7];
TASK media
(void *arg
)
{
char *p
;
int i
=0;
int j
=0;
while(1)
{
p
= cab_getmes
(cid
[1]);
memcpy(videobuf
,p
,dim_x
*dim_y
*sizeof(BYTE
));
cab_unget
(cid
[1], p
);
p
= cab_getmes
(cid
[2]);
memcpy(videobuf1
,p
,dim_x
*dim_y
*sizeof(BYTE
));
cab_unget
(cid
[2], p
);
p
= cab_getmes
(cid
[3]);
memcpy(videobuf2
,p
,dim_x
*dim_y
*sizeof(BYTE
));
cab_unget
(cid
[3], p
);
p
= cab_getmes
(cid
[4]);
memcpy(videobuf4
,p
,dim_x
*dim_y
*sizeof(BYTE
));
cab_unget
(cid
[4], p
);
p
= cab_getmes
(cid
[5]);
memcpy(videobuf5
,p
,dim_x
*dim_y
*sizeof(BYTE
));
cab_unget
(cid
[5], p
);
// calcolo media
for (i
=0;i
<dim_x
;i
++)
{
for(j
=0;j
<dim_y
;j
++)
{
videobuf3
[i
*dim_x
+j
]=(double)(videobuf
[i
*dim_x
+j
]+videobuf1
[i
*dim_x
+j
]+videobuf2
[i
*dim_x
+j
]+videobuf4
[i
*dim_x
+j
]+videobuf5
[i
*dim_x
+j
])/numero_telescopi
;
}
}
// visualizza immagine mediata
sem_wait
(&mutex
);
grx_putimage
(570,10,570+dim_x
-1,10+dim_y
-1,videobuf3
);
sem_post
(&mutex
);
task_endcycle
();
}
}
TASK move
(void *arg
)
{
//int i = (int)arg;
char *p
;
int x_object
=300; // posizione dell'oggetto da rilevare
int y_object
=200;
// variabile contatore
int z
=0;
char coord_x
[dim_msg
];
p
= cab_reserve
(cid
[0]);
sprintf(coord_x
,"%d %d",x_object
,y_object
);
memcpy(p
,coord_x
,dim_msg
*sizeof(char));
cab_putmes
(cid
[0], p
);
//Normalizzazione
for(z
=0;z
<900;z
++)
{
if (luna
[z
]>0)
{
luna
[z
]=((luna
[z
])*16.0/255.0)+16;
}
}
task_endcycle
();
while (1)
{
// Cancellazione Luna
sem_wait
(&mutex
);
grx_box
(x_object
-15,y_object
-15,x_object
+14,y_object
+14,0);
sem_post
(&mutex
);
if (keyb_getcode
(&move_tasto
,NON_BLOCK
))
{
if (move_tasto.
ascii=='4')
x_object
=x_object
-5;
if (move_tasto.
ascii=='6')
x_object
=x_object
+5;
if (move_tasto.
ascii=='2')
y_object
=y_object
+5;
if (move_tasto.
ascii=='8')
y_object
=y_object
-5;
if (move_tasto.
ascii=='9'){
y_object
=y_object
-5;
x_object
=x_object
+5; }
if (move_tasto.
ascii=='1'){
y_object
=y_object
+5;
x_object
=x_object
-5; }
if (move_tasto.
ascii=='7'){
y_object
=y_object
-5;
x_object
=x_object
-5; }
if (move_tasto.
ascii=='3'){
y_object
=y_object
+5;
x_object
=x_object
+5;}
if (move_tasto.
ascii==' '){
sem_wait
(&mutex_tasto
);
flag
=1;
if(numero_telescopi
<N_MAX_TELESCOPI
)
{
numero_telescopi
++;
}
sem_post
(&mutex_tasto
);
}
//CONTROLLI SULLA POSIZIONE
if(y_object
<(dim_y
/2+70)) y_object
=dim_y
/2+70;
if(y_object
>(240-dim_y
/2)) y_object
=(240-dim_y
/2);
if(x_object
<(dim_x
/2+20 )) x_object
=dim_x
/2+20;
if(x_object
>(630-dim_x
/2-10)) x_object
=(630-dim_x
/2-10);
}
p
= cab_reserve
(cid
[0]);
sprintf(coord_x
,"%d %d",x_object
,y_object
);
memcpy(p
,coord_x
,dim_msg
*sizeof(char));
cab_putmes
(cid
[0], p
);
for(z
=0;z
<7;z
++)
{
if (sqrt(pow((x_object
-x_p
[z
]),2)+pow((y_object
-y_p
[z
]),2))<20+dim_p
[z
]+radius
)
grx_disc
(x_p
[z
],y_p
[z
],dim_p
[z
],col_p
[z
]);
}
sem_wait
(&mutex
);
// Gestione sfondo
grx_getimage
(x_object
-15,y_object
-15,x_object
+14, y_object
+14,lunabkg
);
for(z
=0;z
<900;z
++)
{
if( luna
[z
]==0 && lunabkg
!=0 )
{
lunadest
[z
]=lunabkg
[z
];
}
else
{
lunadest
[z
]=luna
[z
];
}
}
grx_putimage
(x_object
-15,y_object
-15,x_object
+14, y_object
+14,lunadest
);
sem_post
(&mutex
);
task_endcycle
();
}
}
TASK tele
(void *arg
)
{
int i
= (int)arg
;
int passi
;
char s
[100];
int x_object
=300; // posizione dell'oggetto da rilevare
int y_object
=200;
int x_start
=500; // posizione iniziale dei telescopi
int y_start
=190;
int x_current
=x_start
; // posizione corrente dei telescopi
int y_current
=y_start
;
int x_current_d
[9];
int y_current_d
[9];
int y
= Y_TELESCOPI
; // coordinata y dei telescopi
double alpha_new
=atan((y
-(double)y_current
)/((x
[i
]-(double)x_current
)));
double alpha
=alpha_new
;
double distance
=0.0;
double alpha_target
=0.0;
double tc
=0.1;
double u
=0.0;
double u_old
=0.0;
double errore
=0.0;
double delta_x
=0;
double delta_y
=0;
char *p
;
//int j=0;
// indice matrice per aggiunta di rumore
int k
=0;
int q
=0;
double polo
=poli
[i
];
int val
=0;
BYTE videobuf
[dim_x
*dim_y
];
passi
= 0;
//srand(i);
//srand(i+sys_gettime(NULL));
alpha_target
=atan((y
-(double)y_object
)/((double)x_object
-x
[i
]));
sem_wait
(&mutex
);
grx_text
("targ",4,340,12,0);
sprintf(s
,"%f",poli
[i
]);
grx_text
(s
,x
[i
],y
+60,12,0);
grx_text
("polo",4,y
+60,12,0);
grx_text
("new",4,y
+50,12,0);
sprintf(s
,"%1.6f",alpha_target
);
grx_text
(s
, x
[i
]-25,y
+50,12,0);
grx_rect
(x
[i
]-40,y
+25,x
[i
]+40,y
+85,2);
grx_rect
(x
[i
]-40,y
+90,x
[i
]+40,y
+150,2);
sem_post
(&mutex
);
// Disegno telescopio
grx_disc
(x
[i
],y
,19,i
+1);
grx_box
( x
[i
]-19,y
,x
[i
]+19,y
+20,i
+1);
task_endcycle
();
while (1) {
// legge di controllo
passi
++;
//sprintf(s,"%d",passi);
//grx_text(s, 50,110,12,0);
p
= cab_getmes
(cid
[0]);
sscanf(p
,"%d %d",&val
,&y_object
);
cab_unget
(cid
[0], p
);
x_object
=val
;
alpha_target
=atan((y
-(double)y_object
)/((double)x_object
-x
[i
]));
if (alpha_target
<0)
{
alpha_target
=3.14+alpha_target
;
}
errore
=alpha_target
-alpha_new
;
u
=u_old
+kp
*tc
*errore
;
//alpha_new=0.13*alpha+0.87*u;
alpha_new
=(exp(polo
*tc
))*alpha
+(1-exp(polo
*tc
))*u
;
u_old
=u
;
alpha
=alpha_new
;
// implementazione dei limiti degli attuattori
if (alpha_new
> 3.14)
alpha_new
=3.14;
if (alpha_new
<0)
alpha_new
=0;
distance
=sqrt(((y
-y_object
)*(y
-y_object
))+((x_object
-x
[i
])*(x_object
-x
[i
])));
sem_wait
(&mutex
);
// Cancello braccio telescopio
if (passi
>1)
{
for (k
=0; k
<9 ; k
++)
{
grx_line
(delta_x
,delta_y
,x_current_d
[k
],y_current_d
[k
],0);
}
}
x_current
=x
[i
]+distance
*cos(alpha_new
);
y_current
=300-distance
*sin(alpha_new
);
// lettura immagine
grx_getimage
(x_current
-(dim_x
/2),y_current
-(dim_y
/2),x_current
+(dim_x
/2),y_current
+(dim_y
/2),videobuf
);
//aggiunta rumore
sem_post
(&mutex
);
for (k
=0;k
<dim_x
;k
++)
{
for(q
=0;q
<dim_y
;q
++)
{
int num
=0;
num
=rand();
num
=(num
%10)+1;
if (num
>SOGLIA
)
{
videobuf
[k
*dim_x
+q
]=videobuf
[k
*dim_x
+q
]+1;
}
}
}
sem_wait
(&mutex
);
grx_putimage
(x
[i
]-25,y
+92,x
[i
]-25+dim_x
-1,y
+92+dim_y
-1,videobuf
);
sprintf(s
,"%3.4f",(180*(alpha_target
/pi
)));
grx_text
(s
, x
[i
]-25,y
+40,12,0);
sprintf(s
,"%3.4f",180*(alpha_new
/pi
));
grx_text
(s
, x
[i
]-25,y
+50,12,0);
delta_x
=x
[i
]+20*cos(alpha_new
);
delta_y
=y
-20*sin(alpha_new
);
for ( k
=0; k
<9 ; k
++) {
x_current_d
[k
]=x
[i
]+50*cos(alpha_new
+(k
-4)*0.01);
y_current_d
[k
]=300-50*sin(alpha_new
+(k
-4)*0.01); }
// Disegno braccio telescopio
for(k
=0 ; k
<9 ; k
++)
grx_line
(delta_x
,delta_y
,x_current_d
[k
],y_current_d
[k
],i
+1);
sem_post
(&mutex
);
// scrive immagine nel cab
p
= cab_reserve
(cid
[i
+1]);
memcpy(p
,videobuf
,dim_x
*dim_y
*sizeof(BYTE
));
cab_putmes
(cid
[i
+1], p
);
task_endcycle
();
}
}
/****************************************************************/
/* This is the exception handler. It is called when an exception
is raised.
It exits from the graphical mode, then it prints a message and
shutdown the kernel using sys_abort()
*/
void demo_exc_handler
(int signo
, siginfo_t
*info
, void *extra
)
{
struct timespec t
;
grx_close
();
/* Default action for an kern exception is */
kern_cli
();
ll_gettime
(TIME_EXACT
, &t
),
kern_printf
("\nS.Ha.R.K. Exception raised!!!"
"\nTime (s:ns) :%ld:%ld"
"\nException number:%d (numbers in include/bits/errno.h)"
"\nPID :%d\n",
t.
tv_sec, t.
tv_nsec, info
->si_value.
sival_int,
info
->si_task
);
sys_abort
(1);
}
/******************************************************************/
/* This function is called when Alt-X is pressed.
It simply shutdown the system using sys_end.
Note that the byebye() function is called only if we exit from
the system using sys_end()!!!!
*/
void my_end
(KEY_EVT
* e
)
{
sys_end
();
}
/******************************************************************/
/* This function is called when the system exit correctly after Alt-X.
It exits from the graphic mode and then it prints a small greeting.
Note that:
- The function calls grx_exit, so it must be registered using
RUNLEVEL_BEFORE_EXIT (RUNLEVEL_AFTER_EXIT does not work because
at that point the kernel is already returned in real mode!!!)
- When an exception is raised, the exception handler is called.
Since the exception handler already exits from the graphic mode,
this funcion has not to be called. For this reason:
. we registered byebye using the flag NO_AT_ABORT
. the exception handler exits using sys_abort; in that way byebye is
NOT called
*/
void byebye
(void *arg
)
{
grx_close
();
kern_printf
("Bye Bye!\n");
}
/****************************** MAIN ******************************/
int main
(int argc
, char **argv
)
{
PID pid1
, pid4
,pid5
;
KEY_EVT emerg
;
int i
=0;
int z
=0; // contatore per disegno dei pianeti
HARD_TASK_MODEL m1
, m4
,m5
;
//FILE *fp;
struct sigaction action
;
cid
[0] = cab_create
(cname
[0], dim_msg
, 5);
cid
[1] = cab_create
(cname
[1], dim_x
*dim_y
, 3);
cid
[2] = cab_create
(cname
[2], dim_x
*dim_y
, 3);
cid
[3] = cab_create
(cname
[3], dim_x
*dim_y
, 3);
cid
[4] = cab_create
(cname
[4], dim_x
*dim_y
, 4);
cid
[5] = cab_create
(cname
[5], dim_x
*dim_y
, 3);
cid
[6] = cab_create
(cname
[6], dim_x
*dim_y
, 3);
/*fp=fopen("file.txt","r");
fscanf(fp,"%d",a);
fclose(fp);
*/
/* Init the standard S.Ha.R.K. exception handler */
action.
sa_flags = SA_SIGINFO
; /* Set the signal action */
action.
sa_sigaction = demo_exc_handler
;
action.
sa_handler = 0;
sigfillset
(&action.
sa_mask); /* we block all the other signals... */
if (sigaction
(SIGHEXC
, &action
, NULL
) == -1) { /* set the signal */
perror("Error initializing signals...");
sys_end
();
}
/* Set the closing function */
sys_atrunlevel
(byebye
, NULL
, RUNLEVEL_BEFORE_EXIT
|NO_AT_ABORT
);
/* Initializes the semaphore */
sem_init
(&mutex
,0,1);
/* graphic card Initialization */
if (grx_init
() < 1) {
sys_abort
(1);
}
if (grx_open
(640, 480, 8) < 0) {
kern_printf
("GRX Err\n");
sys_abort
(1);
}
kern_printf
("Video card ok!\n");
/* set the keyboard handler to exit correctly */
emerg.
ascii = 'x';
emerg.
scan = KEY_X
;
emerg.
flag = ALTL_BIT
;
keyb_hook
(emerg
,my_end
);
srand(i
+sys_gettime
(NULL
));
emerg.
ascii = 'x';
emerg.
scan = KEY_X
;
emerg.
flag = ALTR_BIT
;
keyb_hook
(emerg
,my_end
);
sem_wait
(&mutex
);
/* a small banner */
grx_clear
(0);
grx_text
("REALTIME TELESCOPES di Marco Bera e Gabriele Varasio",8,8,WHITE
,0);
grx_text
("Premere Spazio per creare un telescopio",8,22,WHITE
,0);
grx_text
("Premere Alt-X per uscire",8,32,WHITE
,0);
grx_text
("Usare il tastierino numerico per muovere l'oggetto",8,42,WHITE
,0);
// DISEGNARE BORDI
grx_rect
(1,1,638,478,2);
grx_rect
(558,1,638,61,2);
grx_rect
(1,1,638,61,2);
// Disegno sfondo
for(z
=0;z
<7;z
++)
{
num_p
=rand();
y_p
[z
]=100+((num_p
%130)+1);
x_p
[z
]=50+((num_p
%540)+1);
dim_p
[z
]=2+((num_p
%5)+1);
col_p
[z
]=((num_p
%10)+1);
grx_disc
(x_p
[z
],y_p
[z
],dim_p
[z
],col_p
[z
]);
}
sem_post
(&mutex
);
hard_task_default_model
(m4
);
hard_task_def_ctrl_jet
(m4
);
hard_task_def_arg
(m4
, (void *)3);
hard_task_def_wcet
(m4
, 19000);
hard_task_def_mit
(m4
, PERIOD_T4
);
hard_task_def_group
(m4
,1);
pid4
= task_create
("move", move
, &m4
, NULL
);
if (pid4
== NIL
) {
grx_close
();
perror("Could not create task <move>");
sys_abort
(1);
}
task_activate
(pid4
);
hard_task_default_model
(m5
);
hard_task_def_ctrl_jet
(m5
);
hard_task_def_arg
(m5
, (void *)3);
hard_task_def_wcet
(m5
, 19000);
hard_task_def_mit
(m5
, PERIOD_T5
);
hard_task_def_group
(m5
,1);
pid5
= task_create
("media", media
, &m5
, NULL
);
if (pid5
== NIL
) {
grx_close
();
perror("Could not create task <move>");
sys_abort
(1);
}
task_activate
(pid5
);
/* and finally we activate the three threads... */
do {
int val_flag
=0;
sem_wait
(&mutex_tasto
);
val_flag
=flag
;
sem_post
(&mutex_tasto
);
if ((val_flag
==1) && (i
< N_MAX_TELESCOPI
))
{
flag
=0;
hard_task_default_model
(m1
);
hard_task_def_ctrl_jet
(m1
);
hard_task_def_arg
(m1
, (void *)i
);
hard_task_def_wcet
(m1
, WCET_T
);
// hard_task_def_mit (m1, PERIOD_T1);
hard_task_def_mit
(m1
, period_t1
);
hard_task_def_group
(m1
,1);
pid1
= task_create
("tele1", tele
, &m1
, NULL
);
if (pid1
== NIL
)
{
grx_close
();
perror("Could not create task <tele1>");
sys_abort
(1);
}
task_activate
(pid1
);
i
++;
}
} while (1);
/*
now the task main ends, but the system does not shutdown because
there are others.
The demo will finish if a Alt-X key is pressed.
*/
return 0;
}
/*********** lettura da file ********************/
void read_cfg_file
(int argc
, char **argv
)
{
int err
;
DOS_FILE
*fp
;
char myfilebuf
[1000];
int myfilebuf_length
;
if (2)
{
fp
= DOS_fopen
("dati.cnf","r");
if (fp
)
{
/* read up to 1000 chars */
myfilebuf_length
= DOS_fread
(&myfilebuf
,1,1000,fp
);
/* check for errors */
err
= DOS_error
();
cprintf
("Read %d bytes...\n", myfilebuf_length
);
if (err
)
{
cprintf
("Error %d reading file...Using default values\n", err
);
}
else
{
//geti(myfilebuf, &pos, &NMouses); // Number of Mouses
sscanf(myfilebuf
,"%lf %lf %lf %lf %lf %lf %d",&poli
[0],&poli
[1],&poli
[2],&poli
[3],&poli
[4],&kp
,&period_t1
);
}
DOS_fclose
(fp
);
return;
}
else {
/* error!! */
err
= DOS_error
();
/* note that if you call DOS_error() here, it return 0!!! */
cprintf
("Error %d opening myfile.txt...Using default values\n", err
);
}
}
else {
cprintf
("Wrong number of arguments...\n");
l1_exit
(0);
}
}
/****************************************************************/