Modifications du simulateur
Les principaux changements du simulateur sont:
- modification du calcul des équations physiques
- rajout de l'affichage de certaines variables
- affichage des vecteurs appliqués sur le drone
- modification des angles de débattement (ceci n'a été fait qu'à des fins de tests)
- changement d'unités pour rendre les valeurs cohérentes avec les équations utilisées
- gestion des collisions plus poussée
- création de boites ODE (non-texturés)
Il est à noter que ce simulateur a été extrêmement linéarisé pour le simplifier, en effet, le temps accordé au projet n'était que d'une centaine d'heures, trop cours pour permettre de faire quelque chose de très pointu.
Modification du calcul des équations physiques
La fonction calcul(), comme son nom l'indique, se charge de calculer les forces appliquées sur le drone et les appliques.
Pour cela il faut d'abord récupérer quelques informations de l'ODE (moteur physique).
On récupère diverses valeurs du vecteur vitesse du drone grâce à dBodyVectorFromWorld(), qui fournis le résultat par rapport aux axes X, Y et Z.
void calculs(void)
{
{
dReal *v = dBodyGetLinearVel(bodycorp);
dBodyVectorFromWorld(bodycorp, v[0], v[1], v[2], localv);
}
dBodyVectorFromWorld renvois 3 valeurs dans un tableau, localv.
La 1ere valeur (localv[0]) correspond à la valeur du vecteur vitesse, il n'y a donc pas besoin de traitement.
{
vitesse = localv[0];
// calcul la vitesse globale du drone au carre
vitesse2 = vitesse * vitesse;
Localv[0] contenant la valeur du vecteur vitesse du drone, pour avoir l'angle du roulis du drone, on fais un arc tangente entre le vecteur vitesse et localv[2], qui corespond au à l'axe Z relatif au drone. Ceci nous donne un angle sur le plan X/Z, en radians.
alphaz = atan2(localv[2],localv[0]);
Pour avoir le cap, il suffit de calculer l'arc tangente par entre localv[1] et localv[0].
Ensuite on calcule et applique les différentes forces relatives au drone.
Par exemple, pour appliquer la force de traction au drone, induite par l'hélice, on doit effectuer la manipulation suivante.
Tout d'abord on calcule la force de cette traction.
Ici l'équation est linéarisée, et ne correspond donc pas exactement à ce que l'on peut trouver dans la littérature.
Ici, coef_moteur représente un nombre entre 0 et 1, d'une précision d'un millième, représentant la puissance désirée du moteur, et pondère donc la valeur de la traction.
Au final, il ne reste qu'a l'appliquer sur l'objet drone. Un coefficient de 1000 est ici appliqué pour respecter la cohérence des unités.
{
// si la traction doit etre appliquee effectuer les calculs de la force
if(mot == 1)
traction = ((1.3 * 0.7) * ( VITESSE_DRONE_MAX - (coef_moteur * vitesse)));
// si la traction ne doit pas etre appliquée elle vaut 0
else
traction = 0;
dBodyAddRelForce(bodytraction,traction*1000,0,0);
Rajout de l'affichage de certaines variables
La fonction display() affiche désormais de nouvelles informations:
- la vitesse au carré
- la vitesse
- l'angle du vecteur vitesse par rapport à l'axe y
- l'angle du vecteur vitesse par rapport à l'axe z
- le roulis
- le cap
- la force de traction appliquée
- la trainée appliquée
- la portance sur chacune des ailes
Affichage des vecteurs appliqués sur le drone
La fonction affich() permet également l'affichage des forces appliquées au drone.
Ici, pour l'exemple, voici l'affichage de la portance d'une des ailes du drone, ici, en rouge.
p=dBodyGetPosition(bodyaile1);
dBodyVectorToWorld(bodyaile1,0,0,portanceZaile1*3,vg);
raydium_draw_line(p[0],p[1],p[2],p[0]+vg[0],p[1]+vg[1],p[2]+vg[2],1.0f,0,0);
La fonction raydium_draw_line() est une fonction personnelle qui ne fais pas partie de l'ODE, permettant de dessiner des lignes.
Modification des angles de débattement
Les commandes reçues par la fonction periph_write() sont comprises entre 0 et 180 et correspondent à l'angle voulu du servomoteur associé à la gouverne. Il nous a donc suffit de les diviser pour réduire les débattements des gouvernes concernées.
Ici, les gouvernes des ailes varient entre -0.8° et 0.8°.
case 'D': //Commande des 2 Servos moteur lié
// au 2 volets
{
//pour mettre les angles a 0, la valeur d'entree doit etre de 80
if ( (x >= 70) && (x <= 90) )
{
alpha0aile2 = 0;
alpha0aile1 = 0;
}
//Les angles sont inversees pour permettre de faire virer
// l'avion correctement
if ( (x > 0) && (x < 160) && !( (x >= 75) && (x <= 85) ))
{
alpha0aile2 = -(((float)x-80)/100);
alpha0aile1 = (((float)x-80)/100);
}
break;
}
}
Des fourchettes vides ont étés crées afin, la encore, de réduire les erreurs de commandes liées au tremblement humain. Elles peuvent être enlevées sur des systèmes où les commandes sont peu sensibles, et peuvent être gardées sur des systèmes où les commandes sont très sensibles. Les valeurs de la fourchette devront par contre être réglées.
Changement d'unités
Les unités utilisées par nos prédécesseurs n'étaient pas cohérentes, et les calculs s'avéraient donc faux. Il nous a fallut vérifier toutes ces valeurs, afin de maintenir l'homogénéité des unités. Les mesures sont donc en mètres, les poids en grammes, et le temps en secondes.
Gestion des collisions plus poussée
Nous nous sommes aperçus que si l'échelle de poids utilisé par nos prédécesseur n'était pas bonne, c'était avant tout pour des raisons pratiques.
En effet, lorsque l'on applique un poid de 50 sur un objet celui ci traversait le sol et les autres surfaces.
50 n'étant que le poid relatif de la batterie du drone, celui ci se retrouvait donc a traverser le sol et à tomber dans le vide.
Afin de palier à ce problême, il faut paramétrer 2 coefficients gerp et gcfm.
float gerp=0.7;
float gcfm=1e-5;
Ces coefficients sont ensuite appliqués sur le drone lors de sa création, élement par élement, grâce à la fonction raydium_ode_element_material_name().
//Creation de l'aile droite du drone avec ses donnees physiques reelless
raydium_ode_object_box_add("aile1",objet_drone,POID_DEMI_AILE,LONGUEUR_AILE,
LARGEUR_DEMI_AILE,EPAISSEUR_AILE,RAYDIUM_ODE_STANDARD,TYPE_DRONE,"");
raydium_ode_element_slip_name("aile1",RAYDIUM_ODE_SLIP_DEFAULT/100.0f);
raydium_ode_element_material_name("aile1",gerp,gcfm);
Il faut également que le sol bénéficie de ces paramétres, sans quoi on le traverse toujours.
Dans la fonction main() on a donc:
raydium_ode_ground_set_name(piste);
raydium_ode_element_slip_name("ground",RAYDIUM_ODE_SLIP_DEFAULT/100.0f);
raydium_ode_element_material_name("ground",gerp,gcfm);
Création de boites ODE
Afin de régler le problème de poids et de collision, nous avons créés des boites non texturés, donc totalement invisibles, pour effectuer des tests.
Sous notre programme, il suffit d'appuyer sur "d" afin d'afficher les "box" de raydium, et nous pouvions donc voir ces fameuses boites.
Un simple appuis sur "b" permet de créer une boite, à une position définie.
Retour