Projet

Général

Profil

« Précédent | Suivant » 

Révision 347

Ajouté par mamoisan il y a presque 4 ans

finalisation du TP1 et 2

Voir les différences:

branch/moisan/sp4a12/main.c
/*SP4_TP12
MOISAN Maxence ge3A groupe 5
date rendu : 19/05/2021
*/
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <math.h>
#include "trame.h"
#define M_PI 3.14159265358979323846
//Diff?rentes structures : position et zone
typedef struct
{
float latitude;
float longitude;
} Position;
Position p_prec; // position du point pr?c?dent (utilis? dans le traitement)
typedef struct
{
Position rpos;
float vitmax;
} Zone;
//Trames de tests ? modifier si n?cessaire.
//Trames et zones de tests
char * trames[]= {"$GPGSV,3,2,10,15,03,077,,18,04,041,42,19,85,271,,20,08,214,*7C",
"$GPGSV,3,3,10,22,39,053,50,28,15,320,*7E",
"$GPRMC,141914.00,A,4545.6424,N,00306.6036,E,0.4,99.4,010206,,*0C",
......
"$GPGSA,A,3,,03,,22,14,,01,,18,,,,3.9,3.4,1.9*39",
"$GPVTG,99.4,T,,M,0.4,N,0.7,K*57",
"$GPZDA,141914.00,01,02,2006,00,00*69",
0};
0};
Zone zones[]={
{{44.7887762, -3.012}, 50}, /* Descripteur de la premi?re zone */
{{44.7891220, -3.013}, 70},
{{45.7896227, -3.014}, 70},
{{45.8791420, -3.014}, 70},
{{46.2971220, -3.011}, 70},
{{45.75, 3.110000}, 70},
{{45.752018, 3.110060}, 70},
{{45.754017, 3.110077}, 70},
};
int nbre_zone = 8; // nombre de zones dans le tableau de zone test
//fonction comparant 2 chaines de caract?res
//pr?condition : trame et type 2 chaines de caract?re, longueur de type < longueur de trame
//postcondition : renvoie 1 si la trame commence par la cha?ne de caract?re type et 0 dans les autres cas
int trame_cmp(char * trame, char * type)
{
int i = 0;
int result = 1;
while (type[i]!='\0')
int i = 0; //compteur de la boucle
int result = 1; //valeur de retour
while (type[i]!='\0') //tant que la chaine type n'est pas termin?e on ex?cute le code suivant
{
if(trame[i+1]!=type[i])
if(trame[i+1]!=type[i])//si les caract?res de trame et type sont identique
{
result = 0;
result = 0;//le resultat passe ? 0
}
i++;
i++;//+1 au compteur
}
return result;
return result;//si les caract?res de trame et type sont identiques jusqu'? la fin de type on retourne la valeur 0 sinon on retourne la valeur par d?faut : 1
}
//fonction qui renvoie la valeur d?cimale associ?e ? un caract?re donn? en param?tre
//ici on veut que le '0' ASCII soit identique au 0 d?cimal
int decode_int(char a)
{
if((a>='0') && (a<='9'))
if((a>='0') && (a<='9')) //on veut d?coder que les chiffres (de 0 ? 9)
{
return (a-48);
return (a-48);//le '0' ASCII correspond ? la valeur 48 en d?cimal donc on soustrait juste 48 au caract?re que l'on veut d?coder
} else
{
return -1;
return -1;//si le caract?re n'est pas entre '0' et '9' on retourne -1
}
}
//fonction test unitaire qui teste si decode_int fonctionne
void test_decode_int(void)
{
if (decode_int('0')!=0){
......
}
}
//fonction qui renvoie la valeur d?cimale des n premiers caract?res de la cha?ne de caract?res ch
int decode_nombre(char * ch,int n)
{
int i;
int res=0;
for (i=0;i<n;i++)
int i;//le compteur, curseur pour savoir o? l'on est dans ch
int res=0; //initialisation du r?sultat
for (i=0;i<n;i++)//on parcours ch
{
res += pow(10,(n-i-1))*decode_int(ch[i]);
res += pow(10,(n-i-1))*decode_int(ch[i]);//chaque chiffre est d?cod? avec decode_int puis multipli? par la puissance de 10 selon la place o? il est dans ch et on ajoute ?a au resultat
}
return res;
return res;//on retourne le resultat
}
int decode_nombre2(char * ch,int n)
//fonction alternative ? la premi?re du m?me nom
int decode_nombre2(char * ch,int n)//n est le chiffre auquel on doit s'arr?ter
{
int i;
int res=0;
for (i=0;i<n;i++)
int i;//le compteur, curseur pour savoir o? l'on est dans ch
int res=0;//initialisation du r?sultat
for (i=0;i<n;i++)//on parcours ch jusqu'au n-i?me charact?re
{
res = 10*res + decode_int(ch[i]);
res = 10*res + decode_int(ch[i]);//on multiplie le resultat par 10 puis on ajoute le chiffre d'apr?s pr?alablement d?cod? par decode_int
}
return res;
return res;//on retourne le resultat
}
//test unitaire pour savoir si decode_nombre fonctionne
void test_decode_nombre(void)
{
if (decode_nombre("7541",2)!=75){
......
}
}
//test unitaire pour savoir si decode_nombre2 fonctionne
void test_decode_nombre2(void)
{
if (decode_nombre2("7541",2)!=75){
......
}
}
float latDMStoDec(char * lat_DMS)
//fonction convertissant la cha?ne de caract?re contenant la latitude en nombre flottant
float latDMStoDec(char * lat_DMS)//lat_DMS est sous la forme : 3723.2475
{
float deg = decode_nombre(lat_DMS,2);
float min = decode_int(lat_DMS[2])*10+decode_int(lat_DMS[3])+(0.1*decode_int(lat_DMS[5]))+(0.01*decode_int(lat_DMS[6]))+(0.001*decode_int(lat_DMS[7]))+(0.0001*decode_int(lat_DMS[8]));
float latDec = deg+(min/60);
return latDec;
float deg = decode_nombre(lat_DMS,2);//les degr?s de la latitude sont les 2 premiers chiffres on les d?code ainsi avec decode_nombre pour les convertir en flottant
float min = decode_int(lat_DMS[2])*10+decode_int(lat_DMS[3])+(0.1*decode_int(lat_DMS[5]))+(0.01*decode_int(lat_DMS[6]))+(0.001*decode_int(lat_DMS[7]))+(0.0001*decode_int(lat_DMS[8]));//on d?compose les minutes en d?codant chiffre apr?s chiffre ? l'aide de decode_int
float latDec = deg+(min/60);//la latitude en d?cimal est le nombre de degr?s + le nombre de minutes divis? par 60
return latDec;//on retourne cette valeur
}
//test unitaire permettant de voir si latDMStoDec fonctionne (il peut y avoir une erreur de pr?cision)
void test_latDMStoDec(void)
{
if (latDMStoDec("3723.2475")!= 37.387458){
printf ("%f Erreur Test latDMStoDec.\n", latDMStoDec("3723.2475"));
printf ("Erreur Test latDMStoDec.%f\n", latDMStoDec("3723.2475"));
latDMStoDec("3723.2475");
exit(-1);
}
}
//fonction convertissant la cha?ne de caract?re contenant la longitude en nombre flottant
//on effectue le m?me raisonnement sauf que lon_DMS est sous la forme 00306.6036 c'est-?-dire un charact?re de plus que lat_DMS
float lonDMStoDec(char * lon_DMS)
{
float deg = decode_nombre(lon_DMS,3);
......
return lonDec;
}
//test unitaire permettant de voir si lonDMStoDec fonctionne (il peut y avoir une erreur de pr?cision)
void test_lonDMStoDec(void)
{
if (latDMStoDec("00306.6036")!= 3.11006){
printf ("Erreur Test latDMStoDec. %f\n",latDMStoDec("00306.6036"));
exit(-1);
}
}
//on rassemble les deux derni?res fonctions pour n'en faire qu'une seule
float lontlatDMStoDec(char * coord)
{
if(decode_nombre(coord,3)>=100){
if(decode_nombre(coord,3)>=100)//si il y a 5 chiffres avant la virgule on retourne une longitude
{
return lonDMStoDec(coord);
} else {
} else //sinon on retourne une latitude
{
return latDMStoDec(coord);
}
}
typedef struct
{
float latitude;
float longitude;
} Position;
//fonction qui d?code la trame, la d?composant en un ensemble de chaine de caract?re "GPGGA" et de position avec la structure d?finie avant
//si la trame est valid?e alors on retourne 1 sinon on retourne 0
int decode_trame(char *trame, Position *p)
{
if(trame_cmp(trame,"GPGGA")==1)
if(trame_cmp(trame,"GPGGA")==1)//si la trame commence par les 5 premiers caract?res que l'on souhaite
{
//d?finition des variable
char *lon;
char *lat;
int i;
......
for(i=0;i<=8;i++){
lon[i]=trame[i+29];
}
p->latitude = latDMStoDec(*lat);
p->longitude = lonDMStoDec(*lon);
p->latitude = latDMStoDec(*lat);//on "traduit" la latitude de char ? flottant pour pouvoir les utiliser
p->longitude = lonDMStoDec(*lon);// on fait de m?me avec la longitude
if((p->latitude>=0)&&(p->latitude<=90)){
if((p->longitude>=0)&&(p->longitude<=180)){
return 1;
if((p->longitude>=0)&&(p->longitude<=180))//v?rification dut format de la longitude et de la latitude
{
return 1;// la trame est valid?e
} else{
return 0;
return 0;// la trame n'est pas valid?e
}
} else{
return 0;
return 0;// la trame n'est pas valid?e
}
} else {
return 0;
return 0;// la trame n'est pas valid?e
}
}
// test unitaire pour savoir si decode_trame fonctionne
void test_decode_trame(void)
{
struct Position *p1;
if (decode_trame("$GPGLL,4545.6419,N,00306.6043,E,141921.00,A*04",p1)!= 0){
Position p;
if (decode_trame("$GPGLL,4545.6419,N,00306.6043,E,141921.00,A*04",&p)!= 0){
printf ("Erreur Test decode_trame.\n");
exit(-1);
}
struct Position *p2;
if (decode_trame("$GPGGA,141922.00,4545.1810,N,00306.6046,E,1,05,3.4,500.6,M,,M,,*74",p2)!= 1){
if (decode_trame("$GPGGA,141922.00,4545.1810,N,00306.6046,E,1,05,3.4,500.6,M,,M,,*74",&p)!= 1){
printf ("Erreur Test decode_trame.\n");
exit(-1);
} else {
struct Position *p3;
decode_trame("$GPGGA,141922.00,4545.1810,N,00306.6046,E,1,05,3.4,500.6,M,,M,,*74",p3);
//printf("longitude : %f \n latitude : %f \n",p3->latitude, p3->longitude);
}
}
//petite fonction permettant de transform? les degr?s en radiant
float deg2rad(deg)
{
return deg * (M_PI/180);
}
//fonction qui calcul la distance entre 2 position
float calcule_distance(Position p_1, Position p_2){
float lonP1 = deg2rad(p_1.longitude);
float lonP1 = deg2rad(p_1.longitude);//on convertit en radian les longitudes et latitudes
float lonP2 = deg2rad(p_2.longitude);
float latP1 = deg2rad(p_1.latitude);
float latP2 = deg2rad(p_2.latitude);
float r=6371;
float d = r * acos(sin(latP1)*sin(latP2)+cos(latP1)*cos(latP2)*cos(lonP1-lonP2));
return d;
float r=6371; //rayon de la terre
float d = r * acos(sin(latP1)*sin(latP2)+cos(latP1)*cos(latP2)*cos(lonP1-lonP2));//on applique la formule
return d; //on retourne la distance en km
}
//on calcul la vitesse correspondant au parcours de la distance entre les points p_1 et p_2 pendant 1s
float calcule_vitesse(Position p_1, Position p_2)
{
float d = calcule_distance(p_1, p_2);
return d*3600;
float d = calcule_distance(p_1, p_2);//on utilise la fonction pr?c?dente pour calculer la distance
return d*3600;//on multiplie cette distance par le nombre de seconde dans une heure car on veut la distance en km/h
}
//fonction qui renvoie le num?ro de la zone la plus proche du point p ainsi que sa distance
int distance_a_la_proche_zone(Position p, Zone r[],int nb_zones, float *d)
{
int i,res = 0; //curseur pour se d?placer dans le tableau des zones et initialisation du r?sultat
if (nb_zones == 0) //s'il n'y a pas de zones dangereuses
{
return -1;//on revoie -1
} else
{
*d = calcule_distance(p,r[0].rpos);//on initialise la distance la plus proche ? la distance entre le point p et la premi?re position
for (i=1;i<nb_zones;i++)//on parcours les zones
{
if(calcule_distance(p,r[i].rpos)<*d)//on estime la valeur de la distance et si elle est plus petite on entre dans cette boucle
{
*d = calcule_distance(p,r[i].rpos);//nouvelle distance plus petite
res = i;// resultat devient le num?ro de la zone la plus proche
}
}
return res;//on retourne ce num?ro
}
}
//Fonction ? modifier !!!!!
void traitement(char * trame)
void traitement(char * trame) //traitement qui accepte ou non la trame, calcul la vitesse et la distance ? la zone la plus proche et, si cette distance est inf?rieure ? un seuil et que la vitesse du v?hicule est sup?rieure ? celle d?finie pour cette zone, de d?clencher une alarme.
{
int res;
float v,d,seuil = 50;//initialisation des variables utiles v(vitesse), d(distance) et du seuil ? ne pas d?passer
Position p;//position ? l'instant pr?sent, ? l'instant pr?c?dent p_prec
static int cpt=0;
cpt++;
if(trame_cmp(trame,"GPGGA")==1)
{
printf ("> %s\n",trame);
res = decode_trame(trame,&p);
if (res==1)//si la trame est valid?e
{
printf("Votre position est est de : %f en longitude et %f en latitude\n",p.longitude,p.latitude);//on ?crit la position de la voiture
v = calcule_vitesse(p,p_prec);//calcul de la vitesse
printf("Vous roulez ? %f\n",v);//on indique sa vitesse
res = distance_a_la_proche_zone(p, zones, nbre_zone,&d);//on indique le num?ro de la zone la plus proche
if ((d<seuil)&&(v>zones[res].vitmax))//si la distance de la zone dangereuse est plus faible que le seuil et que l'on roule ? une vitesse sup?rieur ? celle indiqu?e par la zone
{
printf("Alarme ON au niveau de la zone %d \n",res);//Alarme ON
} else
{
printf("Alarme OFF");//Alarme OFF
}
}
p_prec.longitude = p.longitude;//le point prec?dent devient le point que l'on vient de traiter
p_prec.latitude = p.latitude;//le point prec?dent devient le point que l'on vient de traiter
}
}
//Ajouter vos tests unitaires dans cette fonction.
//On ex?cute les test unitaire pour sacoir si on a fait des erreurs
void tests_unitaires(void){
if (5!=5){
printf ("Erreur Test unitaire basique.\n");
......
test_decode_nombre();
test_decode_int();
test_latDMStoDec();
test_lonDMStoDec();
test_decode_nombre2();
test_decode_trame();
}
// Ne pas modifier cette fonction

Formats disponibles : Unified diff