Ceci est une version archivée de
Display à 2008-03-20 16:33:24.
Retour
FONCTION DISPLAY()
Voici le code de la fonction display()
/**
Cette fonction s'exécute indéfiniement. Elle sert à intéragir en temps réel sur les différentes
fonctions du programme.
**/
void display(void)
{
//********************
//Déclaration des variables
//********************
dGeomID geom_box;
dContactGeom *contact;
int flag = 0x0020;
FILE * x;
float y;
//********************
//*********************************************************************************************
//***************************************GESTION DU CLAVIER************************************
//*********************************************************************************************
GestionClavier(raydium_key_last);
//*********************************************************************************************
//***************************************GESTION DES MOTEURS************************************
//*********************************************************************************************
GestionMoteurs();
//*********************************************************************************************
//********************************GESTION DE LA LUMIERE ET DES COULEURS*****************************
//*********************************************************************************************
//Gestion de la lumière et des couleurs
raydium_light_position[0][0]=100;
raydium_light_position[0][1]=100;
raydium_light_position[0][2]=100;
raydium_light_position[0][3]=1.0;
raydium_light_update_position(0);
raydium_background_color_change(light_color[0],light_color[1],light_color[2],light_color[3]);
raydium_clear_frame();
//*********************************************************************************************
//***************************************GESTION DE LA SOURIS************************************
//*********************************************************************************************
GestionSouris();
//*********************************************************************************************
//*********************************GESTION DES FORMES A AFFICHER**********************************
//*********************************************************************************************
//Affichage normal
raydium_ode_draw_all(0);
raydium_ode_draw_all(RAYDIUM_ODE_DRAW_NORMAL);
//Affichage en mode debug
//raydium_ode_draw_all(RAYDIUM_ODE_DRAW_DEBUG);
//*********************************************************************************************
//***************************************GESTION DE L'AFFICHAGE***********************************
//*********************************************************************************************
raydium_osd_printf(2,98,16,0.5,"font2.tga","- %3i FPS - Viewport demo %s for Raydium %s, CQFD Corp.",raydium_render_fps,version,raydium_version());
raydium_osd_printf(2,90,16,0.5,"font2.tga","px: %f py: %f pz: %f ax: %f ay: %f",cam_pos_x,cam_pos_y,cam_pos_z,cam_angle_x,cam_angle_y);
raydium_osd_printf(2,87,16,0.5,"font2.tga","axe1: %f° axe2 : %f° axe3 : %f° axe4 : %f°",angle_axe1,angle_axe2,angle_axe3,angle_axe4);
raydium_osd_printf(2,84,16,0.5,"font2.tga","axe5: %f° axe6 : %f°",angle_axe5,angle_axe6);
raydium_osd_printf(2,82,16,0.5,"font2.tga","x: %f° y : %f°",X,Y);
if(remote_mode == remote_on) portSerie = "oui";
if(remote_mode == remote_off) portSerie = "non";
raydium_osd_printf(2,80,16,0.5,"font2.tga","Autorisation port série : %s", portSerie);
//logo qui apparait en bas à droite de l'écran
raydium_osd_logo("logo.tga");
raydium_rendering_finish();
}
1/ Signification de l'affichage :
Dans la fonction affichage, on peut s'aperçevoir qu'il y a une gestion de l'affichage. Ce code permet entre autre l'affichage des lignes que l'on a pu voir en haut de la fenêtre à la création du bras. Voici la signification des lignes :
- 1ère ligne : vitesse des images en FPS (frames par seconde), et version du logiciel.
- 2ème ligne : position de la caméra en x, y et z (px, py, pz) et ses angles d'inclinaison en x et y (ax, ay).
- 3ème et 4ème ligne : angles des 6 axes du bras (axe1, axe2, axe3 axe4, axe5 et la pince).
- 5ème ligne : valeurs de certaines variable pour le débugage.
- 6ème ligne : autorisation ou non de la commande par le port série.
2/ Gestion du clavier :
Pour simplifier la lecture du programme, nous avons créé une fonction
GestionClavier? qui prend en paramètre la touche pressée par l'utilisateur. Voici comment le clavier est géré :
/*************************************************************************
Cette fonction sert à gérer le clavier. Elle fait réagir le système
selon la touche ayant été tapée.
@param : key -> touche ayant été tapée par l'utilisateur
@return : néant
**************************************************************************/
void GestionClavier(int key)
{
switch (key)
{
//Losqu'on appuie sur la barre espace, on réinitialise notre objet
case 1032 : simul_createBras();
//angles courants des différents axes du bras
angle_axe1 = 0,angle_axe2 = 90,angle_axe3 = 0,angle_axe4 = 0,angle_axe5 = 0,angle_axe6 = 0;
//angles voulus par l'utilisateur
comm_axe1 = 0, comm_axe2 = 90, comm_axe3 = 0 ,comm_axe4 = 0 ,comm_axe5 = 0 ,comm_axe6 = 0;
break;
//Losqu'on appuie sur la touche Echap, on quitte Raydium
case 1027 : exit(0);
break;
//***************************************************
//*********************axe1**************************
//***************************************************
//appuie sur la touche a => augmente l'axe1
case 1000+'a' : if(comm_axe1 < 90) comm_axe1 += 1;
break;
//appuie sur la touche q => diminue l'axe1
case 1000+'q' : if (comm_axe1 > -90) comm_axe1 -= 1;
break;
//***************************************************
//*********************axe2**************************
//***************************************************
//appuie sur la touche z => augmente l'axe2
case 1000+'z' : if(comm_axe2 < 90) comm_axe2 += 1;
break;
//appuie sur la touche s => augmente l'axe2
case 1000+'s' : if (comm_axe2 > 0) comm_axe2 -= 1;
break;
//***************************************************
//*********************axe3**************************
//***************************************************
//appuie sur la touche e => augmente l'axe3
case 1000+'e' : if(comm_axe3 < 40) comm_axe3 += 1;
break;
//appuie sur la touche d => augmente l'axe3
case 1000+'d' : if (comm_axe3 > -90) comm_axe3 -= 1;
break;
//***************************************************
//*********************axe4**************************
//***************************************************
//appuie sur la touche r => augmente l'axe4
case 1000+'r' : if(comm_axe4 < 90) comm_axe4 += 1;
break;
//appuie sur la touche f => augmente l'axe4
case 1000+'f' : if (comm_axe4 > -90) comm_axe4 -= 1;
break;
//***************************************************
//*********************axe5**************************
//***************************************************
//appuie sur la touche t => augmente l'axe5
case 1000+'t' : if(comm_axe5 < 90) comm_axe5 += 1;
break;
//appuie sur la touche g => augmente l'axe5
case 1000+'g' : if (comm_axe5 > -90) comm_axe5 -= 1;
break;
//***************************************************
//*********************axe6**************************
//***************************************************
//appuie sur la touche y => augmente l'axe6
case 1000+'y' : if(comm_axe6 < 45) comm_axe6 += 1;
break;
//appuie sur la touche h => augmente l'axe6
case 1000+'h' : if (comm_axe6 > -45) comm_axe6 -= 1;
break;
//Création d'une boite pour tester la pince
case 1000+'m':
{
int a;
char name[255];
a=raydium_ode_object_find("GLOBAL");
raydium_ode_name_auto("box",name);
raydium_ode_element_slip_name(name,dContactMu2);
raydium_ode_object_box_add(name,a,0.1,5,5,5,RAYDIUM_ODE_STANDARD,0,"crate.tri");
raydium_ode_element_move_name_3f(name,0,-22,2.5);
}
break;
//Commande des angles des axes pour placer la pince au niveau de la boite
case 1000 + 'n' :
{
comm_axe1 = 2;
comm_axe2 = 28;
comm_axe3 = -9;
comm_axe6 = 17;
}
break;
//touche pour quitter le programme
case 1000 + 'w' : exit(0);
break;
//autorisation de commander le bras par le port série
case 1000 + 'p' : if(remote_mode == remote_off) remote_mode = remote_on;
if(remote_mode == remote_on) remote_mode = remote_off;
break;
default : break;
}
}
3/ Gestion de la souris :
Une fonction
GestionSouris? a été programmée pour améliorer la lecture du code dans la fonction display.
Dans notre programme, la souris permet de gérer les mouvements de la caméra. Lorsque l'on bouge la souris, la caméra change son angle de vue suivant les mouvement de la souris. Et lorsque l'on appuie sur le clic droit ou gauche, la caméra avance ou recule. Pour bouger la caméra plus précisément, on peut utiliser la roulette vers le haut ou vers le bas.
/*************************************************************************
Cette fonction sert à gérer la souris.
@param : néant
@return : néant
**************************************************************************/
void GestionSouris()
{
//vitesse de la souris
static GLfloat speed = 0;
//angles de la caméra
int delta_x, delta_y;
delta_x = raydium_mouse_x - (raydium_window_tx/2);
delta_y = raydium_mouse_y - (raydium_window_ty/2);
raydium_mouse_move(raydium_window_tx/2, raydium_window_ty/2);
//si on clique sur le bouton gauche de la souris, on avance la caméra
if (raydium_mouse_button[0]) {
if (speed==0) speed+=0.5;
}
//si on clique sur le bouton droit de la souris, on recule la caméra
else if (raydium_mouse_button[1]) {
if (speed==0) speed-=0.5;
}
//si on fait rien, la caméra reste fixe
else speed=0;
//Mouvement précis de la caméra avec la roulette
if (raydium_mouse_click==4) speed=0.05;
if (raydium_mouse_click==5) speed=-0.05;
//calcul de l'angle de la caméra
cam_angle_x += (delta_x*3*0.1f);
cam_angle_y += (delta_y*3*0.1f);
//calcul de la position de la caméra
cam_pos_z += (raydium_trigo_sin(cam_angle_x+90)*speed*raydium_trigo_sin(90-cam_angle_y));
cam_pos_x += (raydium_trigo_cos(cam_angle_x+90)*speed*raydium_trigo_sin(90-cam_angle_y));
cam_pos_y += (raydium_trigo_cos(90-cam_angle_y)*speed);
//positionnement de la caméra
raydium_camera_place(cam_pos_x,cam_pos_y,cam_pos_z,cam_angle_x,cam_angle_y,0);
}
4/ Gestion des moteurs :
Lors de la création du bras, on a créer des moteurs pour chacun des axes. Cette gestion ne se borne pas simplement à commander les moteurs avec les variables que l'on a modifier au préalable. Car par exemple, si l'écart entre l'angle courant d'un axe et celui de la commande est trop grand, le bras bougera directement pour aller à la commande. Ce qui ne fera pas un mouvement très réel de l'axe. C'est pour celà que l'on utilise des variables pour les angles réels du bras, et pour ceux de la commande. Et on incrémente ou décrémente petit à petit le vrai angle pour se rapprocher de la commande
Voici la fonction pour commander ces moteurs :
/*************************************************************************
Cette fonction sert à calculer la différence entre l'angle courant du
moteur et la commande de l'utilisateur. Et elle commande ensuite le ou les
moteur(s) concerné(s)
@param : néant
@return : néant
**************************************************************************/
void GestionMoteurs()
{
/*Calcul des différences entre les angles courants des axes
et la commande de l'utilisateur*/
angle_diff1 = angle_axe1 - comm_axe1;
angle_diff2 = angle_axe2 - comm_axe2;
angle_diff3 = angle_axe3 - comm_axe3;
angle_diff4 = angle_axe4 - comm_axe4;
angle_diff5 = angle_axe5 - comm_axe5;
angle_diff6 = angle_axe6 - comm_axe6;
//Si la différence est inférieur à 0, on doit augmenter l'angle du moteur pour s'approcher de l'angle voulu
if(angle_diff1 < 0) angle_axe1 ++;
//Sinon, si l'angle est supérieur à 0, on doit diminuer l'angle du moteur pour s'approcher de l'angle voulu
else if(angle_diff1 > 0) angle_axe1 --;
//idem que pour l'axe 1
if(angle_diff2 < 0) angle_axe2 ++;
//idem que pour l'axe 1
else if(angle_diff2 > 0) angle_axe2 --;
//idem que pour l'axe 1
if(angle_diff3 < 0) angle_axe3 ++;
//idem que pour l'axe 1
else if(angle_diff3 > 0) angle_axe3--;
//réglage de l'angle de l'axe4 par rapport aux autres axes pour que la pince
//reste à l'horizontale
angle_axe4 = -(angle_axe2 + (90 - angle_axe3)) + 170;
//idem que pour l'axe 1
if(angle_diff5 < 0) angle_axe5 ++;
//idem que pour l'axe 1
else if(angle_diff5 > 0) angle_axe5--;
//idem que pour l'axe 1
if(angle_diff6 < 0) angle_axe6 ++;
//idem que pour l'axe 1
else if(angle_diff6 > 0) angle_axe6 --;
//Teste s'il n'y a pas de liaison avec le port série
//Sinon c'est le port série qui commande le bras
if (remote_mode==remote_off){
//commande axe1
raydium_ode_motor_angle_name("test_bras_mot_axe1",DegToRad(CorrecAngle(1, angle_axe1)));
//commande axe2
raydium_ode_motor_angle_name("test_bras_mot_axe2",DegToRad(CorrecAngle(2, angle_axe2)));
//commande axe3
raydium_ode_motor_angle_name("test_bras_mot_axe3",DegToRad(CorrecAngle(3, angle_axe3)));
//commande axe4
raydium_ode_motor_angle_name("test_bras_mot_axe4",DegToRad(CorrecAngle(4, angle_axe4)));
//commande axe5
raydium_ode_motor_angle_name("test_bras_mot_axe5",DegToRad(CorrecAngle(5, angle_axe5)));
//commande axe6
//on doit commander tout les objets constituants la pince
raydium_ode_motor_angle_name("test_bras_mot_axe6_1",DegToRad(CorrecAngle(6, angle_axe6)));
raydium_ode_motor_angle_name("test_bras_mot_axe6_2",-DegToRad(CorrecAngle(6, angle_axe6)));
raydium_ode_motor_angle_name("test_bras_mot_axe6_3",-DegToRad(CorrecAngle(6, angle_axe6)));
raydium_ode_motor_angle_name("test_bras_mot_axe6_4",DegToRad(CorrecAngle(6, angle_axe6)));
raydium_ode_motor_angle_name("test_bras_mot_axe6_5",-DegToRad(CorrecAngle(6, angle_axe6)));
raydium_ode_motor_angle_name("test_bras_mot_axe6_6",DegToRad(CorrecAngle(6, angle_axe6)));
raydium_ode_motor_angle_name("test_bras_mot_axe6_7",-DegToRad(CorrecAngle(6, angle_axe6)));
raydium_ode_motor_angle_name("test_bras_mot_axe6_8",DegToRad(CorrecAngle(6, angle_axe6)));
raydium_ode_motor_angle_name("test_bras_mot_axe6_9",-DegToRad(CorrecAngle(6, angle_axe6)));
raydium_ode_motor_angle_name("test_bras_mot_axe6_10",DegToRad(CorrecAngle(6, angle_axe6)));
}
}
On peut voir dans la commande des moteurs que l'on utilise 2 fonctions.
DegToRad? est une fonction qui prend en paramètre un angle en degré et qui retourne cet angle en radian. Car la fonction de commande du moteur de raydium prend en paramètre un angle en radian.
CorrecAngle? est une fonction qui corrige l'angle donné en paramètre selon l'axe que l'on veut commander. Car à la création du bras, les angles des axes sont différents du vrai bras. Il faut donc les corriger pour qu'ils soient les mêmes.
Code de la fonction "
CorrecAngle?" :
/**
Cette fonction corrige l'angle mis en paramètre selon l'axe que l'on veut commander.
Cette fonction a été programmé car à la création, l'angle des différents axes ne sont
pas les mêmes que le bras réel.
@param : axe est l'axe que l'on veut commander
angle est l'angle que l'on veut appliquer à l'axe
@return : on retourne alors l'angle réel que l'on doit appliquer à l'axe
**/
GLfloat CorrecAngle(int axe, int angle)
{
GLfloat angleReel;
//modification de l'angle si il s'agit de l'axe 2, 3, 4 ou 6
switch(axe)
{
case 2 : angleReel = -90+angle;
break;
case 3 : angleReel = -angle;
break;
case 4 : angleReel = angle + 10;
break;
case 6 : angleReel = angle + 45;
break;
default : angleReel = angle;
break;
}
return angleReel;
}
Retour