root/branch/moisan/sp4a12/main.c @ 771
347 | mamoisan | /*SP4_TP12
|
|
MOISAN Maxence ge3A groupe 5
|
|||
date rendu : 19/05/2021
|
|||
*/
|
|||
1 | jalaffon | #include <stdio.h>
|
|
#include <stdlib.h>
|
|||
128 | mamoisan | #include <strings.h>
|
|
#include <math.h>
|
|||
270 | mamoisan | #include "trame.h"
|
|
#define M_PI 3.14159265358979323846
|
|||
347 | mamoisan | ||
//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;
|
|||
1 | jalaffon | ||
347 | mamoisan | //Trames et zones de tests
|
|
1 | jalaffon | 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",
|
|||
"$GPGLL,4545.6424,N,00306.6036,E,141914.00,A*0E",
|
|||
"$GPGGA,141914.00,4545.0000,N,00306.6036,E,1,05,3.4,499.3,M,,M,,*7D",
|
|||
"$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",
|
|||
347 | mamoisan | 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},
|
|||
};
|
|||
3 | jalaffon | ||
347 | mamoisan | 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
|
|||
112 | mamoisan | int trame_cmp(char * trame, char * type)
|
|
{
|
|||
347 | mamoisan | 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
|
|||
112 | mamoisan | {
|
|
347 | mamoisan | if(trame[i+1]!=type[i])//si les caract?res de trame et type sont identique
|
|
112 | mamoisan | {
|
|
347 | mamoisan | result = 0;//le resultat passe ? 0
|
|
112 | mamoisan | }
|
|
347 | mamoisan | i++;//+1 au compteur
|
|
112 | mamoisan | }
|
|
347 | mamoisan | 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
|
|
3 | jalaffon | }
|
|
112 | mamoisan | ||
347 | mamoisan | //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
|
|||
112 | mamoisan | int decode_int(char a)
|
|
{
|
|||
347 | mamoisan | if((a>='0') && (a<='9')) //on veut d?coder que les chiffres (de 0 ? 9)
|
|
112 | mamoisan | {
|
|
347 | mamoisan | 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
|
|
112 | mamoisan | } else
|
|
{
|
|||
347 | mamoisan | return -1;//si le caract?re n'est pas entre '0' et '9' on retourne -1
|
|
112 | mamoisan | }
|
|
}
|
|||
347 | mamoisan | //fonction test unitaire qui teste si decode_int fonctionne
|
|
112 | mamoisan | void test_decode_int(void)
|
|
{
|
|||
if (decode_int('0')!=0){
|
|||
printf ("Erreur Test decode_int.\n");
|
|||
exit(-1);
|
|||
}
|
|||
if (decode_int('5')!=5){
|
|||
printf ("Erreur Test decode_int.\n");
|
|||
exit(-1);
|
|||
}
|
|||
if (decode_int('A')!=-1){
|
|||
printf ("Erreur Test decode_int.\n");
|
|||
exit(-1);
|
|||
}
|
|||
}
|
|||
347 | mamoisan | //fonction qui renvoie la valeur d?cimale des n premiers caract?res de la cha?ne de caract?res ch
|
|
112 | mamoisan | int decode_nombre(char * ch,int n)
|
|
{
|
|||
347 | mamoisan | 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
|
|||
112 | mamoisan | {
|
|
347 | mamoisan | 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
|
|
112 | mamoisan | }
|
|
347 | mamoisan | return res;//on retourne le resultat
|
|
112 | mamoisan | }
|
|
347 | mamoisan | //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
|
|||
270 | mamoisan | {
|
|
347 | mamoisan | 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
|
|||
270 | mamoisan | {
|
|
347 | mamoisan | 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
|
|
270 | mamoisan | }
|
|
347 | mamoisan | return res;//on retourne le resultat
|
|
270 | mamoisan | }
|
|
347 | mamoisan | //test unitaire pour savoir si decode_nombre fonctionne
|
|
112 | mamoisan | void test_decode_nombre(void)
|
|
{
|
|||
if (decode_nombre("7541",2)!=75){
|
|||
printf ("Erreur Test decode_nombre.\n");
|
|||
exit(-1);
|
|||
}
|
|||
if (decode_nombre("7541",3)!=754){
|
|||
printf ("Erreur Test decode_nombre.\n");
|
|||
exit(-1);
|
|||
}
|
|||
if (decode_nombre("123",3)!=123){
|
|||
printf ("Erreur Test decode_nombre.\n");
|
|||
exit(-1);
|
|||
}
|
|||
if (decode_nombre("987654321",2)!=98){
|
|||
printf ("Erreur Test decode_nombre.\n");
|
|||
exit(-1);
|
|||
}
|
|||
}
|
|||
128 | mamoisan | ||
347 | mamoisan | //test unitaire pour savoir si decode_nombre2 fonctionne
|
|
270 | mamoisan | void test_decode_nombre2(void)
|
|
{
|
|||
if (decode_nombre2("7541",2)!=75){
|
|||
printf ("Erreur Test decode_nombre.\n");
|
|||
exit(-1);
|
|||
}
|
|||
if (decode_nombre2("7541",3)!=754){
|
|||
printf ("Erreur Test decode_nombre.\n");
|
|||
exit(-1);
|
|||
}
|
|||
if (decode_nombre2("123",3)!=123){
|
|||
printf ("Erreur Test decode_nombre.\n");
|
|||
exit(-1);
|
|||
}
|
|||
if (decode_nombre2("987654321",2)!=98){
|
|||
printf ("Erreur Test decode_nombre.\n");
|
|||
exit(-1);
|
|||
}
|
|||
}
|
|||
347 | mamoisan | //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
|
|||
128 | mamoisan | {
|
|
347 | mamoisan | 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
|
|||
128 | mamoisan | }
|
|
640 | mamoisan | long latDMStoDec2(char * lat_DMS)//lat_DMS est sous la forme : 3723.2475
|
|
{
|
|||
long deg = decode_nombre2(lat_DMS,2)*10000;//les degr?s de la latitude sont les 2 premiers chiffres on les d?code ainsi avec decode_nombre pour les convertir en flottant
|
|||
long min = decode_int(lat_DMS[2])*100000+(decode_int(lat_DMS[3])*10000)+(1*decode_int(lat_DMS[5])*1000)+(0.01*decode_int(lat_DMS[6])*100)+(10*decode_int(lat_DMS[7]))+decode_int(lat_DMS[8]);//on d?compose les minutes en d?codant chiffre apr?s chiffre ? l'aide de decode_int
|
|||
long latDec = deg*60+min;//la latitude en d?cimal est le nombre de degr?s + le nombre de minutes divis? par 60
|
|||
return latDec;//on retourne cette valeur
|
|||
}
|
|||
347 | mamoisan | //test unitaire permettant de voir si latDMStoDec fonctionne (il peut y avoir une erreur de pr?cision)
|
|
128 | mamoisan | void test_latDMStoDec(void)
|
|
{
|
|||
640 | mamoisan | if (latDMStoDec("3723.2475")!= 37.387459){
|
|
printf ("Erreur Test latDMStoDec. \n");
|
|||
347 | mamoisan | latDMStoDec("3723.2475");
|
|
128 | mamoisan | exit(-1);
|
|
}
|
|||
}
|
|||
640 | mamoisan | void test_latDMStoDec2(void)
|
|
{
|
|||
if (latDMStoDec2("3723.2475")!= 37.387459){
|
|||
printf ("Erreur Test latDMStoDec. \n");
|
|||
latDMStoDec("3723.2475");
|
|||
exit(-1);
|
|||
}
|
|||
}
|
|||
347 | mamoisan | //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
|
|||
128 | mamoisan | float lonDMStoDec(char * lon_DMS)
|
|
{
|
|||
float deg = decode_nombre(lon_DMS,3);
|
|||
float min = decode_int(lon_DMS[3])*10+decode_int(lon_DMS[4])+(0.1*decode_int(lon_DMS[6]))+(0.01*decode_int(lon_DMS[7]))+(0.001*decode_int(lon_DMS[8]))+(0.0001*decode_int(lon_DMS[9]));
|
|||
float lonDec = deg+(min/60);
|
|||
return lonDec;
|
|||
}
|
|||
262 | mamoisan | ||
640 | mamoisan | long lonDMStoDec2(char * lon_DMS)
|
|
{
|
|||
long deg = decode_nombre(lon_DMS,3)*10000;
|
|||
long min = (100000*decode_int(lon_DMS[3])*10)+(10000*decode_int(lon_DMS[4]))+(1000*decode_int(lon_DMS[6]))+(100*decode_int(lon_DMS[7]))+(10*decode_int(lon_DMS[8]))+decode_int(lon_DMS[9]);
|
|||
long lonDec = deg*60+min;
|
|||
return lonDec;
|
|||
}
|
|||
347 | mamoisan | //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){
|
|||
640 | mamoisan | printf ("Erreur Test latDMStoDec.\n");
|
|
347 | mamoisan | exit(-1);
|
|
}
|
|||
}
|
|||
640 | mamoisan | void test_lonDMStoDec2(void)
|
|
{
|
|||
if (latDMStoDec2("00306.6036")!= 3.11006){
|
|||
printf ("Erreur Test latDMStoDec.\n");
|
|||
exit(-1);
|
|||
}
|
|||
}
|
|||
347 | mamoisan | //on rassemble les deux derni?res fonctions pour n'en faire qu'une seule
|
|
262 | mamoisan | float lontlatDMStoDec(char * coord)
|
|
{
|
|||
347 | mamoisan | if(decode_nombre(coord,3)>=100)//si il y a 5 chiffres avant la virgule on retourne une longitude
|
|
{
|
|||
262 | mamoisan | return lonDMStoDec(coord);
|
|
347 | mamoisan | } else //sinon on retourne une latitude
|
|
{
|
|||
262 | mamoisan | return latDMStoDec(coord);
|
|
}
|
|||
}
|
|||
270 | mamoisan | ||
347 | mamoisan | //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
|
|||
270 | mamoisan | int decode_trame(char *trame, Position *p)
|
|
{
|
|||
347 | mamoisan | if(trame_cmp(trame,"GPGGA")==1)//si la trame commence par les 5 premiers caract?res que l'on souhaite
|
|
270 | mamoisan | {
|
|
640 | mamoisan | char lat[8];
|
|
char lon[9];
|
|||
270 | mamoisan | int i;
|
|
for(i=0;i<=7;i++){
|
|||
lat[i]=trame[i+17];
|
|||
}
|
|||
for(i=0;i<=8;i++){
|
|||
lon[i]=trame[i+29];
|
|||
}
|
|||
640 | mamoisan | p->longitude = lonDMStoDec(lon);// on fait de m?me avec la longitude
|
|
p->latitude = latDMStoDec(lat);//on "traduit" la latitude de char ? flottant pour pouvoir les utiliser
|
|||
270 | mamoisan | if((p->latitude>=0)&&(p->latitude<=90)){
|
|
347 | mamoisan | 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
|
|||
270 | mamoisan | } else{
|
|
347 | mamoisan | return 0;// la trame n'est pas valid?e
|
|
270 | mamoisan | }
|
|
} else{
|
|||
347 | mamoisan | return 0;// la trame n'est pas valid?e
|
|
270 | mamoisan | }
|
|
} else {
|
|||
347 | mamoisan | return 0;// la trame n'est pas valid?e
|
|
270 | mamoisan | }
|
|
}
|
|||
347 | mamoisan | // test unitaire pour savoir si decode_trame fonctionne
|
|
270 | mamoisan | void test_decode_trame(void)
|
|
{
|
|||
347 | mamoisan | Position p;
|
|
if (decode_trame("$GPGLL,4545.6419,N,00306.6043,E,141921.00,A*04",&p)!= 0){
|
|||
270 | mamoisan | printf ("Erreur Test decode_trame.\n");
|
|
exit(-1);
|
|||
}
|
|||
347 | mamoisan | if (decode_trame("$GPGGA,141922.00,4545.1810,N,00306.6046,E,1,05,3.4,500.6,M,,M,,*74",&p)!= 1){
|
|
270 | mamoisan | printf ("Erreur Test decode_trame.\n");
|
|
exit(-1);
|
|||
}
|
|||
}
|
|||
347 | mamoisan | ||
640 | mamoisan | //petite fonction permettant de transform? les degr?s en radian
|
|
270 | mamoisan | float deg2rad(deg)
|
|
{
|
|||
return deg * (M_PI/180);
|
|||
}
|
|||
347 | mamoisan | //fonction qui calcul la distance entre 2 position
|
|
270 | mamoisan | float calcule_distance(Position p_1, Position p_2){
|
|
347 | mamoisan | float lonP1 = deg2rad(p_1.longitude);//on convertit en radian les longitudes et latitudes
|
|
270 | mamoisan | float lonP2 = deg2rad(p_2.longitude);
|
|
float latP1 = deg2rad(p_1.latitude);
|
|||
float latP2 = deg2rad(p_2.latitude);
|
|||
347 | mamoisan | 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
|
|||
270 | mamoisan | }
|
|
347 | mamoisan | //on calcul la vitesse correspondant au parcours de la distance entre les points p_1 et p_2 pendant 1s
|
|
270 | mamoisan | float calcule_vitesse(Position p_1, Position p_2)
|
|
{
|
|||
347 | mamoisan | 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
|
|||
270 | mamoisan | }
|
|
347 | mamoisan | ||
//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
|
|||
}
|
|||
}
|
|||
1 | jalaffon | ||
//Fonction ? modifier !!!!!
|
|||
347 | mamoisan | 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.
|
|
112 | mamoisan | {
|
|
347 | mamoisan | 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++;
|
|||
112 | mamoisan | if(trame_cmp(trame,"GPGGA")==1)
|
|
{
|
|||
printf ("> %s\n",trame);
|
|||
347 | mamoisan | 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
|
|||
1 | jalaffon | }
|
|
}
|
|||
128 | mamoisan | ||
//Ajouter vos tests unitaires dans cette fonction.
|
|||
347 | mamoisan | //On ex?cute les test unitaire pour sacoir si on a fait des erreurs
|
|
128 | mamoisan | void tests_unitaires(void){
|
|
if (5!=5){
|
|||
printf ("Erreur Test unitaire basique.\n");
|
|||
exit(-1);
|
|||
}
|
|||
if (trame_cmp("$GPGGA suite chaine","GPGGA")!=1){
|
|||
printf ("Erreur Test unitaire trame_cmp.\n");
|
|||
exit(-1);
|
|||
}
|
|||
if (trame_cmp("$GPRMC suite chaine","GPGGA")!=0){
|
|||
printf ("Erreur Test unitaire trame_cmp.\n");
|
|||
exit(-1);
|
|||
}
|
|||
if (trame_cmp("$GPRMC... ", "GPRMC" )!=1){
|
|||
printf ("Erreur Test unitaire trame_cmp.\n");
|
|||
exit(-1);
|
|||
}
|
|||
if (trame_cmp("$APRMC...", "GPGGA")!=0){
|
|||
printf ("Erreur Test unitaire trame_cmp.\n");
|
|||
exit(-1);
|
|||
}
|
|||
test_decode_nombre();
|
|||
test_decode_int();
|
|||
test_latDMStoDec();
|
|||
347 | mamoisan | test_lonDMStoDec();
|
|
640 | mamoisan | test_latDMStoDec2();
|
|
test_lonDMStoDec2();
|
|||
270 | mamoisan | test_decode_nombre2();
|
|
347 | mamoisan | test_decode_trame();
|
|
128 | mamoisan | }
|
|
1 | jalaffon | ||
// Ne pas modifier cette fonction
|
|||
int main(int argc,char ** argv)
|
|||
{
|
|||
tests_unitaires();
|
|||
// Affichage des trames definies dans la table trames.
|
|||
printf ("Trames de tests tableau trames:\n");
|
|||
int i=0;
|
|||
while (trames[i])
|
|||
traitement(trames[i++]);
|
|||
if (!trame_init())
|
|||
exit(-1);
|
|||
// Affichage des trames du fichier gps.log
|
|||
char *trame;
|
|||
printf ("Trames de tests du fichier gps.log\n");
|
|||
while ((trame = trame_suivante()))
|
|||
traitement(trame);
|
|||
return 0;
|
|||
}
|