Blame |
Last modification |
View Log
| RSS feed
#include <kernel/kern.h>
#include <drivers/glib.h>
#include <drivers/keyb.h>
#include <semaphore.h>
//#include <stdlib.h>
#include <math.h>
#include <modules/cabs.h>
#include <modules/hartport.h>
#define NBEAM 6
#define NBALL 6
#define XMIN 50
#define XMAX 600
#define YMIN 100
#define YMAX 450
#define CONMKS 10
#define ESC 27 /* ASCII code of ESCAPE key */
#define MOVE 0
#define FALL 1
#define FALLSTART 2
#define SLEEP 3
#define JET_ON
#define JETCTRLGRP 5
const WORD RGB_BLACK
= rgb16
( 0, 0, 0);
const WORD RGB_GRAY
= rgb16
(127,127,127);
const WORD RGB_WHITE
= rgb16
(255,255,255);
const WORD RGB_RED
= rgb16
(255, 0, 0);
const WORD RGB_GREEN
= rgb16
( 0,255, 0);
const WORD RGB_BLUE
= rgb16
( 0, 0,255);
const WORD RGB_YELLOW
= rgb16
(255,255, 0);
const WORD RGB_MAGENTA
= rgb16
(255, 0,255);
const WORD RGB_CYAN
= rgb16
( 0,255,255);
const WORD RGB_D_RED
= rgb16
(127, 0, 0);
const WORD RGB_D_GREEN
= rgb16
( 0,127, 0);
const WORD RGB_D_BLUE
= rgb16
( 0, 0,127);
const WORD RGB_D_YELLOW
= rgb16
(127,127, 0);
const WORD RGB_D_MAGENTA
= rgb16
(127, 0,127);
const WORD RGB_D_CYAN
= rgb16
( 0,127,127);
const int TIMEPERIOD_MOVEBALL
= 40000;
const int TIMEPERIOD_FALLBALL
= 80000;
const int TIMEPERIOD_MOVEBEAM
= 40000;
const int TIMEPERIOD_CALCULATE_W
= 200000;
const int TIMEPERIOD_REFRESHSCREEN
= 80000;
const int TIMEPERIOD_DRAWBARGRAPHS
= 80000;
const int TIMEPERIOD_STARTBALL
= 3770400;
const int WCET_MOVEBALL
= 1000;
const int WCET_FALLBALL
= 1000;
const int WCET_MOVEBEAM
= 1000;
const int WCET_CALCULATE_W
= 1000;
const int WCET_STARTBALL
= 1000;
const float GRAVITY
= 9.8;
const float PI1
= 3.14;
const float LARGE_INCREASE
= 0.04;
const float MEDIUM_INCREASE
= 0.02;
const float SMALL_INCREASE
= 0.005;
const float THRESHOLD_S
= 105.0f;
const float THRESHOLD_V
= 1.0f;
const int CONSTANT_M
= 2;
const int CONSTANT_K
= 2;
const int INITIAL_S
= 25;
const int BALLRADIUS
= 8;
const int BEAMLENGTH
= 100;
const int FLOOR
= 480;
const int STARTX
= 425 + 250-100;
const int STARTY
= 25;
const int BEAMPOSITION
[][2] = {
{400 + 250-100,100},
{325 + 250-100,250},
{475 + 250-100,250},
{250 + 250-100,400},
{400 + 250-100,400},
{550 + 250-100,400}
};
int period
= 40000; /* task period */
int wcet
= 1000; /* task wcet */
PID pid
;
sem_t mx_grf
; /* mutex semaphores */
CAB palla
[NBEAM
]; /* CAB identifiers for communication between the ball and the beam*/
CAB beams
[NBALL
]; /* CAB identifiers for communication between the ball and the beam*/
char * ballNames
[] = { "p0",
"p1",
"p2",
"p3",
"p4",
"p5"
};
char * beamNames
[] = { "b0",
"b1",
"b2",
"b3",
"b4",
"b5"
};
struct BallColor
{
int r
;
int g
;
int b
;
};
struct SharedBall
{
float v
; // velocity of the ball
float s
;
int status
;
int beamId
;
struct BallColor color
; //ball color
};
struct Ball
{
float x
; //x position of the ball
float y
; //x position of the ball
int r
; //radius of the ball
float w
; //angular velocity of the ball
int id
;
struct SharedBall sball
;
};
struct SharedBeam
{
float theta
;
float dtheta
;
};
struct Beam
{
int l
;
int x
;
int y
;
float w
;
int id
;
struct SharedBeam sbeam
;
};
int whichBeam
(float s
, int id
) {
int i
= 0;
switch(id
) {
case 0:
i
= s
< 0.0? 1 : 2;
break;
case 1:
i
= s
< 0.0? 3: 4;
break;
case 2:
i
= s
< 0.0? 4: 5;
break;
default:
i
= -1;
}
return i
;
}
int checkifballisonbeam
(float ballx
,float bally
, int beamid
)
{
struct SharedBeam sbeam
;
char* p
;
float actualslope1
=0.0f;
float actualslope2
=0.0f;
const float slopetolerance
= 3 ;
float beamx
, beamy
, beamlength
,requiredslope
,ballposition
;
beamx
= BEAMPOSITION
[beamid
][0] ;
beamy
= BEAMPOSITION
[beamid
][1] ;
beamlength
= BEAMLENGTH
;
p
= cab_getmes
(beams
[beamid
]);
memcpy(&sbeam
,p
,sizeof(struct SharedBeam
));
cab_unget
(beams
[beamid
],p
);
/* I Want theta , x , y , s of the beam currospoding ot beam id .......... */
actualslope1
= ( bally
- beamy
+ slopetolerance
) / (ballx
- beamx
) ;
actualslope2
= ( bally
- beamy
- slopetolerance
) / (ballx
- beamx
) ;
requiredslope
= atan(sbeam.
theta) ;
if (( actualslope1
>= requiredslope
&& actualslope2
<= requiredslope
) || (actualslope2
>= requiredslope
&& actualslope1
<= requiredslope
))
{
ballposition
= sqrt( (ballx
-beamx
)*(ballx
-beamx
) + (bally
-beamy
)*(bally
-beamy
) ) ;
if(abs(ballposition
) < beamlength
)
{
if(ballx
< beamx
)
ballposition
= -ballposition
;
return (int)ballposition
;
}
}
return 10000 ;
}
TASK startBall
(void* param
) {
PORT readyballs
;
char msg
[4];
// char str[40];
int id
= -1;
struct SharedBall ball
;
char * p
;
readyballs
= port_create
("readyballs",4,NBALL
,MAILBOX
,READ
);
if( readyballs
< 0) {
grx_close
();
perror("Could not create to MailBox");
cprintf
("\n Could not create to MailBox ....");
sys_abort
(1);
}
while(1) {
if( (port_receive
(readyballs
,msg
,NON_BLOCK
)) == 1 )
{
//read the ball from the cab and change the status from SLEEP to FALLSTART
sscanf(msg
,"%d",&id
);
/*
sem_wait(&mx_grf);
grx_text(msg,10+id*5,700,rgb16(255,255,255), rgb16(0,0,0));
sem_post(&mx_grf);
*/
p
= cab_getmes
(palla
[id
]);
memcpy(&ball
,p
,sizeof(struct SharedBall
));
cab_unget
(palla
[id
], p
);
ball.
status = FALLSTART
;
//Putting the new values of the ball back in the CAB
p
= cab_reserve
(palla
[id
]);
memcpy(p
,&(ball
),sizeof(struct SharedBall
));
cab_putmes
(palla
[id
], p
);
}
/*else {
sem_wait(&mx_grf);
grx_text("Did not receive id",10,650,rgb16(255,255,255), rgb16(0,0,0));
sem_post(&mx_grf);
}
*/
task_endcycle
() ;
}
}
TASK drawbargraphs
(void* param
) {
int i
;
char* p
;
int plot_s
=0;
struct SharedBall ball
;
int x
[NBALL
];
int old_s
[NBALL
] = {0};
int oldx
= 10;
char str
[15];
const int graphpositions
[][2] = {
{10,10 },
{120+100,10},
{10,120+80},
{120+100,120+80},
{10,230+160},
{120+100,230+160}
};
for(i
=0;i
<NBALL
;i
++)
x
[i
]= graphpositions
[i
][0];
while(1)
{
for(i
=0; i
< NBALL
; i
++) {
//Reading the Shared ball parameters from the CAB
p
= cab_getmes
(palla
[i
]);
memcpy(&ball
,p
,sizeof(struct SharedBall
));
cab_unget
(palla
[i
], p
);
plot_s
= (-2 * ball.
s + (2*graphpositions
[i
][1] + 100)) / 2 ;
//Drawing the axes
//Plotting the value of s
oldx
= x
[i
] - 1;
if(oldx
<= graphpositions
[i
][0] - 1) oldx
= graphpositions
[i
][0] + 99;
sem_wait
(&mx_grf
);
grx_line
(graphpositions
[i
][0],graphpositions
[i
][1],graphpositions
[i
][0],graphpositions
[i
][1]+100,rgb16
(255,255,255));
grx_line
(graphpositions
[i
][0],graphpositions
[i
][1] + 50,graphpositions
[i
][0] + 100,graphpositions
[i
][1]+50,rgb16
(255,255,255));
grx_plot
(x
[i
],plot_s
,rgb16
(ball.
color.
r,ball.
color.
g,ball.
color.
b));
sem_post
(&mx_grf
);
old_s
[i
] = plot_s
;
x
[i
]++;
if(x
[i
]==graphpositions
[i
][0] + 100) {
x
[i
]=graphpositions
[i
][0];
sem_wait
(&mx_grf
);
grx_box
(graphpositions
[i
][0]-5,graphpositions
[i
][1]-5,graphpositions
[i
][0] + 110,graphpositions
[i
][1] + 110,rgb16
(0,0,0));
grx_line
(graphpositions
[i
][0],graphpositions
[i
][1],graphpositions
[i
][0],graphpositions
[i
][1]+100,rgb16
(255,255,255));
grx_line
(graphpositions
[i
][0],graphpositions
[i
][1] + 50,graphpositions
[i
][0] + 100,graphpositions
[i
][1]+50,rgb16
(255,255,255));
sprintf(str
,"%-4d",-1*BEAMLENGTH
/2);
grx_text
(str
,graphpositions
[i
][0] -5,graphpositions
[i
][1]+100,rgb16
(255,255,255), rgb16
(0,0,0));
sem_post
(&mx_grf
);
}
}
task_endcycle
() ;
}
}
TASK moveball
( void * ballparam
)
{
struct Ball ball
= (*(struct Ball
*)ballparam
);
struct SharedBeam beam
;
char * p
;
char str
[40]; //debugging
PORT readyballs
;
char msg
[4];
int i
= 10; //debugging
float fallingvx
;
float fallingvy
;
fallingvx
= 3.0 ;
fallingvy
= 0.0 ;
const float KFALLINGGRAVITY
= 0.01 ;
float fallingvelocityseed
= 0.1 ;
while(1)
{
//If the ball's status is SLEEP it reads SharedBall from the CAB
if(ball.
sball.
status == SLEEP
) {
p
= cab_getmes
(palla
[ball.
id]);
memcpy(&(ball.
sball),p
,sizeof(struct SharedBall
));
cab_unget
(palla
[ball.
id], p
);
}
//Read the Sharedbeam parameters from the CAB
p
= cab_getmes
(beams
[ball.
sball.
beamId]);
memcpy(&beam
,p
,sizeof(struct SharedBeam
));
cab_unget
(beams
[ball.
sball.
beamId], p
);
//Painting the previous position of the ball BLACK
sem_wait
(&mx_grf
);
grx_disc
(ball.
x, ball.
y, ball.
r,rgb16
(0,0,0));
sem_post
(&mx_grf
);
/************************************************************************************/
/* THIS IS WHERE THE NEW CO-ORDINATES OF THE BALL ARE CALCULATED */
/************************************************************************************/
if(ball.
sball.
status == MOVE
)
{
ball.
sball.
v = ball.
sball.
v - CONSTANT_K
* sin(beam.
dtheta);
ball.
sball.
s = ball.
sball.
s + CONSTANT_M
* ball.
sball.
v ;
ball.
x = BEAMPOSITION
[ball.
sball.
beamId][0] + ball.
sball.
s * cos(beam.
theta);
ball.
y = BEAMPOSITION
[ball.
sball.
beamId][1] - ball.
sball.
s * sin(beam.
theta) - ball.
r * cos(beam.
theta);
if(abs(ball.
sball.
s) > BEAMLENGTH
/ 2)
{
/* Indicates that ball is not on any of the beam ....... Now Calculate will access this function to identify the balls on the beam and according to calculate the Omega .... There may be case when there are two balls on the same beam .... at that time Calculate will give priority to any of the ball...
*/
ball.
sball.
beamId = whichBeam
(ball.
sball.
s , ball.
sball.
beamId);
fallingvx
= ball.
sball.
v * cos(beam.
theta+6.28) ;
fallingvy
= ( -1 * ball.
sball.
v * sin(beam.
theta)) ;
/*
sem_wait(&mx_grf);
sprintf(str,"%f %f %f",ball.sball.v,beam.theta,fallingvx);
grx_text(str,200,700 + ball.id*10,rgb16(255,255,255), rgb16(0,0,0));
sem_post(&mx_grf);
*/
ball.
sball.
status = FALL
;
}
}
/********************************************************************************************/
// This status is necessary when ball is falling from the initial position ......
/*******************************************************************************************/
if(ball.
sball.
status == FALLSTART
)
{
ball.
sball.
beamId = 0;
ball.
x = STARTX
;
ball.
y = STARTY
;
fallingvx
= fallingvelocityseed
;
fallingvy
= 0 ;
fallingvelocityseed
= - fallingvelocityseed
;
ball.
sball.
status = FALL
;
}
if (ball.
sball.
status == FALL
)
{
ball.
x = ball.
x + fallingvx
;
ball.
y = ball.
y + fallingvy
;
// Change the velocity in Y direction ............
fallingvy
= fallingvy
+ GRAVITY
* KFALLINGGRAVITY
;
// Check the ball is reached on the floor .........
if(ball.
y > FLOOR
)
{
readyballs
= port_connect
("readyballs",4,MAILBOX
,WRITE
);
if(readyballs
== -1) {
grx_close
();
perror("Could not connect to MailBox");
cprintf
("\n Could not connect to MailBox ....");
sys_abort
(1);
}
sprintf(msg
,"%d",ball.
id);
if(port_send
(readyballs
,msg
,NON_BLOCK
)) {
ball.
sball.
status = SLEEP
;
ball.
x = STARTX
;
ball.
y = STARTY
;
p
= cab_reserve
(palla
[ball.
id]);
memcpy(p
,&(ball.
sball),sizeof(struct SharedBall
));
cab_putmes
(palla
[ball.
id], p
);
}
/*
else {
sem_wait(&mx_grf) ;
sprintf(str,"%s %d ","Unable to add ballId to the mailbox",ball.id);
grx_text(str ,450,50 + i, rgb16(100,103,127), rgb16(255,255,255) );
sem_post(&mx_grf);
}*/
port_disconnect
(readyballs
);
}
//check the position of ball and if it has reached the beam
//1)change the value of s
//2)change status to MOVE
if(ball.
sball.
beamId != -1)
{
float ballposition
;
if( (ballposition
= checkifballisonbeam
(ball.
x,ball.
y,ball.
sball.
beamId )) != 10000 )
{
/* Update the s and beam id of the ball in side the CABS ......*/
ball.
sball.
s = ballposition
;
ball.
sball.
v = 0 ;
ball.
sball.
status = MOVE
;
}
}
}
/************************************************************************************/
/* END OF CALCULATIONS */
/************************************************************************************/
//Putting the new values of the ball back in the CAB
if(ball.
sball.
status != SLEEP
) {
p
= cab_reserve
(palla
[ball.
id]);
memcpy(p
,&(ball.
sball),sizeof(struct SharedBall
));
cab_putmes
(palla
[ball.
id], p
);
}
i
+= 2;
if(i
==400) i
= 2;
//Repainting the ball again
sem_wait
(&mx_grf
);
grx_disc
(ball.
x, ball.
y, ball.
r, rgb16
(ball.
sball.
color.
r,ball.
sball.
color.
g,ball.
sball.
color.
b));
// sprintf(str,"%d",ball.sball.beamId);
// grx_text(str ,ball.x,ball.y,rgb16(100,103,127), rgb16(255,255,255) );
sem_post
(&mx_grf
);
task_endcycle
();
}//End of while
}
TASK calculate
(void * param
) { //To calculate the theta values of each beam
int beams_covered
[NBEAM
] = {0};
int i
=0;
struct SharedBall ball
;
struct SharedBeam beam
;
char *p
;
const float MAX_THETA
= 0.5 ;
const float MIN_THETA
= -0.5;
while(1) {
for(i
=0; i
< NBEAM
; i
++)
beams_covered
[i
] = 0;
for(i
=0; i
< NBALL
; i
++) {
//Reading the Shared ball parameters from the CAB
p
= cab_getmes
(palla
[i
]);
memcpy(&ball
,p
,sizeof(struct SharedBall
));
cab_unget
(palla
[i
], p
);
//skip the beam theta calculation if
//1)beam's theta was calculated earlier in the loop
//2)If the status of the ball is falling
if(beams_covered
[ball.
beamId] == 1 || ball.
beamId ==-1 || ball.
status == FALL
|| ball.
status == FALLSTART
|| ball.
status == SLEEP
) continue;
//read the Shared beam parameters from ball's beamId
p
= cab_getmes
(beams
[ball.
beamId]);
memcpy(&beam
,p
,sizeof(struct SharedBeam
));
cab_unget
(beams
[ball.
beamId], p
);
/************************************************************************************/
/* THIS IS WHERE THE NEW theta OF THE BEAM IS CALCULATED */
/************************************************************************************/
beam.
dtheta = beam.
theta;
if(ball.
v > 0) { //ball going towards right
if(ball.
s > 0) { //ball going away from the center
if(abs(ball.
s) < THRESHOLD_S
&& abs(ball.
v) < THRESHOLD_V
)
{
beam.
theta = beam.
theta + SMALL_INCREASE
;
} else if(abs(ball.
s) > THRESHOLD_S
&& abs(ball.
v) > THRESHOLD_V
)
{
beam.
theta = beam.
theta + LARGE_INCREASE
;
} else
{
beam.
theta = beam.
theta + MEDIUM_INCREASE
;
}
} else { //ball going towards center
if(abs(ball.
s) < THRESHOLD_S
&& abs(ball.
v) < THRESHOLD_V
)
{
beam.
theta = beam.
theta - SMALL_INCREASE
;
} else
{
beam.
theta = beam.
theta - MEDIUM_INCREASE
;
}
}
} else { //ball going towards left
if(ball.
s > 0) { //ball going away from the center
if(abs(ball.
s) < THRESHOLD_S
&& abs(ball.
v) < THRESHOLD_V
)
{
beam.
theta = beam.
theta + SMALL_INCREASE
;
} else
{
beam.
theta = beam.
theta + MEDIUM_INCREASE
;
}
} else {
if(abs(ball.
s) < THRESHOLD_S
&& abs(ball.
v) < THRESHOLD_V
)
{
beam.
theta = beam.
theta - SMALL_INCREASE
;
} else if(abs(ball.
s) > THRESHOLD_S
&& abs(ball.
v) > THRESHOLD_V
)
{
beam.
theta = beam.
theta - LARGE_INCREASE
;
} else
{
beam.
theta = beam.
theta - MEDIUM_INCREASE
;
}
}
}
if(beam.
theta > MAX_THETA
) beam.
theta = MAX_THETA
;
if(beam.
theta < MIN_THETA
) beam.
theta = MIN_THETA
;
beam.
dtheta = beam.
theta - beam.
dtheta;
/************************************************************************************/
/* END OF CALCULATIONS */
/************************************************************************************/
//mark the beam as already covered
beams_covered
[ball.
beamId] = 1;
//write the updated SharedBeam back to the CAB
p
= cab_reserve
(beams
[ball.
beamId]);
memcpy(p
,&beam
,sizeof(struct SharedBeam
));
cab_putmes
(beams
[ball.
beamId], p
);
}//end of for loop
task_endcycle
();
}//end of task while
}
TASK movebeam
( void * beamparam
) {
struct Beam beam
= (*(struct Beam
*)beamparam
);
while(1)
{
//The beam attributes(theta and dtheta) are read from the CAB.
char *p
= cab_getmes
(beams
[beam.
id]);
memcpy(&(beam.
sbeam),p
,sizeof(struct SharedBeam
));
cab_unget
(beams
[beam.
id], p
);
//Old Parameters of the beam based on the value of theta read.
int old_beam_start_x
= beam.
x - (beam.
l)/2 * cos(beam.
sbeam.
theta - beam.
sbeam.
dtheta);
int old_beam_start_y
= beam.
y + (beam.
l)/2 * sin(beam.
sbeam.
theta - beam.
sbeam.
dtheta);
int old_beam_end_x
= beam.
x + (beam.
l)/2 * cos(beam.
sbeam.
theta - beam.
sbeam.
dtheta);
int old_beam_end_y
= beam.
y - (beam.
l)/2 * sin(beam.
sbeam.
theta - beam.
sbeam.
dtheta);
//Painting the old beam position BLACK
sem_wait
(&mx_grf
);
grx_line
(old_beam_start_x
,old_beam_start_y
,old_beam_end_x
,old_beam_end_y
,rgb16
(0,0,0));
sem_post
(&mx_grf
);
//New Parameters of the beam based on the value of theta read.
int new_beam_start_x
= beam.
x - (beam.
l)/2 * cos(beam.
sbeam.
theta);
int new_beam_start_y
= beam.
y + (beam.
l)/2 * sin(beam.
sbeam.
theta);
int new_beam_end_x
= beam.
x + (beam.
l)/2 * cos(beam.
sbeam.
theta);
int new_beam_end_y
= beam.
y - (beam.
l)/2 * sin(beam.
sbeam.
theta);
//Painting the beam again with updated values
sem_wait
(&mx_grf
);
grx_line
(new_beam_start_x
,new_beam_start_y
,new_beam_end_x
,new_beam_end_y
,rgb16
(255,255,255));
sem_post
(&mx_grf
);
//Printing some values to get current state
sem_wait
(&mx_grf
) ;
// sprintf(str,"%d %d %s",beam.x,beam.y,"moveBeam after");
// grx_text(str ,485,104 + 30, RGB_GREEN, RGB_BLACK );
sem_post
(&mx_grf
);
task_endcycle
() ;
}
}
void byebye
(void *arg
)
{
grx_close
();
cprintf
("Bye Bye!\n");
}
void endfun
(KEY_EVT
*k
)
{
grx_close
();
cprintf
("Ending...\n");
sys_end
();
}
/****************************** MAIN ******************************/
int main
(int argc
, char **argv
)
{
KEY_EVT k
;
SOFT_TASK_MODEL sm
;
char *p
;
char c
;
WORD r
,g
,b
;//Colours
struct Ball ballArray
[NBALL
];
struct Beam beamArray
[NBALL
];
PID balltasks
[NBALL
];
PID beamtasks
[NBEAM
];
PID calculate_id
;
PID drawbargraphs_id
;
PID startball_id
;
int i
= 0; /* number of tasks created */
sem_init
(&mx_grf
,0,1) ;
/* Set the closing function */
sys_atrunlevel
(byebye
, NULL
, RUNLEVEL_BEFORE_EXIT
);
/* graphic card Initialization */
if (grx_init
() < 1)
{
sys_abort
(1);
}
if (grx_open
(1024,768, 8) < 0)
{
cprintf
("GRX Err\n");
sys_abort
(1);
}
//grx_rect(BEAMPOSITION[3][0] - 70,BEAMPOSITION[0][1] - 98,BEAMPOSITION[5][0] + 70, 510,rgb16(155,155,215));
grx_line
(1,600,1024,600,rgb16
(155,155,215));
//grx_line(370,1,370,600,rgb16(155,155,215));
grx_text
("SPACE TO CREATE NEW BALL",495, 650, rgb16
(255,255,255), RGB_BLACK
);
grx_text
("ENTER/ESC FOR EXIT ",495, 665, rgb16
(255,255,255), RGB_BLACK
);
grx_text
("X: time",165, 540, rgb16
(255,255,255), RGB_BLACK
);
grx_text
("Y: displacement",165, 555, rgb16
(255,255,255), RGB_BLACK
);
keyb_set_map
(itaMap
);
k.
flag = CNTR_BIT
;
k.
scan = KEY_C
;
k.
ascii = 'c';
keyb_hook
(k
,endfun
);
k.
flag = CNTL_BIT
;
k.
scan = KEY_C
;
k.
ascii = 'c';
keyb_hook
(k
,endfun
);
k.
flag = 0;
k.
scan = KEY_ENT
;
k.
ascii = 13;
keyb_hook
(k
,endfun
);
//creating cabs for shared Ball parameters
for(i
=0; i
<NBALL
; i
++) {
palla
[i
] = cab_create
(ballNames
[i
], sizeof(struct SharedBall
), 5);
}
for(i
=0; i
<NBALL
; i
++) {
r
=100+i
*8;
g
=55+i
*6;
b
=i
*20;
ballArray
[i
].
id = i
;
ballArray
[i
].
x = STARTX
;
ballArray
[i
].
y = STARTY
;
ballArray
[i
].
r = BALLRADIUS
;
ballArray
[i
].
sball.
color.
r = r
;
ballArray
[i
].
sball.
color.
g = g
;
ballArray
[i
].
sball.
color.
b = b
;
ballArray
[i
].
w = 0;
ballArray
[i
].
sball.
v = 0;
ballArray
[i
].
sball.
s = INITIAL_S
+ i
*2;
ballArray
[i
].
sball.
status = FALLSTART
; //SLEEP;
ballArray
[i
].
sball.
beamId = 0;
}
//put initial Sharedball structures in the CAB
for(i
=0; i
<NBALL
; i
++) {
p
= cab_reserve
(palla
[i
]);
memcpy(p
,&ballArray
[i
].
sball,sizeof(struct SharedBall
));
cab_putmes
(palla
[i
], p
);
}
//creating cabs for shared Beam parameters
for(i
=0; i
<NBEAM
; i
++) {
beams
[i
] = cab_create
(beamNames
[i
], sizeof(struct SharedBeam
), 5);
}
for(i
=0; i
<NBEAM
; i
++) {
beamArray
[i
].
id = i
;
beamArray
[i
].
x = BEAMPOSITION
[i
][0];
beamArray
[i
].
y = BEAMPOSITION
[i
][1];
beamArray
[i
].
l = BEAMLENGTH
;
beamArray
[i
].
w = 0;
beamArray
[i
].
sbeam.
theta = 0;
beamArray
[i
].
sbeam.
dtheta = 0;
}
//put initial Sharedbeam structures in the CAB
for(i
=0; i
<NBEAM
; i
++) {
p
= cab_reserve
(beams
[i
]);
memcpy(p
,&(beamArray
[i
].
sbeam),sizeof(struct SharedBeam
));
cab_putmes
(beams
[i
], p
);
}
//Creating ball tasks
soft_task_default_model
(sm
);
soft_task_def_met
(sm
,100);
soft_task_def_ctrl_jet
(sm
);
for(i
=0; i
<NBALL
; i
++) {
soft_task_def_arg
(sm
,(void *)&ballArray
[i
]);
soft_task_def_period
(sm
,TIMEPERIOD_MOVEBALL
);
balltasks
[i
] = task_create
("Ball", moveball
, &sm
, NULL
);
if (balltasks
[i
] == NIL
) {
grx_close
();
perror("Could not create task <moveball>");
sys_abort
(1);
}
}
//creating beam tasks
soft_task_default_model
(sm
);
soft_task_def_met
(sm
,100);
soft_task_def_ctrl_jet
(sm
);
for(i
=0; i
<NBEAM
; i
++) {
soft_task_def_arg
(sm
,(void *)&beamArray
[i
]);
soft_task_def_period
(sm
,TIMEPERIOD_MOVEBEAM
);
beamtasks
[i
] = task_create
("Beam", movebeam
, &sm
, NULL
);
if (beamtasks
[i
] == NIL
) {
grx_close
();
perror("Could not create task <movebeam>");
sys_abort
(1);
}
}
soft_task_default_model
(sm
);
soft_task_def_met
(sm
,100);
soft_task_def_ctrl_jet
(sm
);
i
=0;
soft_task_def_arg
(sm
,(void *)i
);
soft_task_def_period
(sm
,TIMEPERIOD_CALCULATE_W
);
calculate_id
= task_create
("Calculate",calculate
, &sm
, NULL
);
if (calculate_id
== NIL
) {
grx_close
();
perror("Could not create task <calculate>");
sys_abort
(1);
}
soft_task_default_model
(sm
);
soft_task_def_met
(sm
,100);
soft_task_def_ctrl_jet
(sm
);
i
= 0;
soft_task_def_arg
(sm
,(void *)i
);
soft_task_def_period
(sm
,TIMEPERIOD_DRAWBARGRAPHS
);
drawbargraphs_id
= task_create
("DrawBarGrapphs",drawbargraphs
, &sm
, NULL
);
if (drawbargraphs_id
== NIL
) {
grx_close
();
perror("Could not create task <drawbargraphs>");
sys_abort
(1);
}
//creating task <startball>
soft_task_default_model
(sm
);
soft_task_def_met
(sm
,100);
soft_task_def_ctrl_jet
(sm
);
i
=0;
soft_task_def_arg
(sm
,(void *)i
);
soft_task_def_period
(sm
,TIMEPERIOD_STARTBALL
);
startball_id
= task_create
("StartBall",startBall
, &sm
, NULL
);
if (startball_id
== NIL
) {
grx_close
();
perror("Could not create task <StartBall>");
sys_abort
(1);
}
for(i
=0; i
<NBEAM
; i
++) {
task_activate
(beamtasks
[i
]);
}
task_activate
(calculate_id
);
task_activate
(drawbargraphs_id
);
task_activate
(startball_id
);
i
=0;
c
= keyb_getch
(BLOCK
);
#ifdef JET_ON
scenario_jetcontrol
();
#endif
#ifdef JET_ON
init_jetcontrol
();
#endif
group_activate
(JETCTRLGRP
);
do {
if ((c
== ' ') && (i
< NBALL
)) {
task_activate
(balltasks
[i
]);
i
++;
}
c
= keyb_getch
(BLOCK
);
} while (c
!= ESC
);
sys_end
();
return 0;
}
/*--------------------------------------------------------------*/