Index: branch/REZKI/sp4a12/main.c
===================================================================
--- branch/REZKI/sp4a12/main.c	(revision 422)
+++ branch/REZKI/sp4a12/main.c	(revision 423)
@@ -1,10 +1,10 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <strings.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
 #include "trame.h"
-#include<math.h>
+#include <math.h>
 #define R 6370
-#define PI 3.14159265
+#define PI 3.14159265
 
 typedef struct {
     float lat;
@@ -15,27 +15,38 @@
     position rpos;
     float vitmax;
     }zone;
-
-//Trames de tests à modifier si nécessaire.
-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",
+
+zone zones[] = {
+    {{44.7887762, -3.012}, 50},
+    {{44.7891220, -3.013}, 70},
+    {{45.750000, 3.216700}, 110}, // zone route limitée à 110km/h vers Cournon d'Auvergne
+};
+
+char * t[]={"$GPGGA,141914.00,4545.0000,N,00306.6036,E,1,05,3.4,499.3,M,,M,,*7D"};
+
+position p1, p2, p3, p4, p5, p6, p7;
+float d;
+
+//Trames de tests à modifier si nécessaire.
+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",
                     0};
 
 int decode_int(char c)
 {
-    if((c-48<0)||(c-48>9)) //vérifie si le caracctère est un chiffre
+    if((c-48<0)||(c-48>9))  // vérifie si le caractère est un chiffre entre 0 et 9
         return -1;
     else
         return c-48;
 }
 
-int decode_nombre(char *ch,int i,int n)
+int decode_nombre(char *ch,int i,int n) // converti un nombre type chaîne de caractère en type entier
 {
     int res=0;
     int j;
@@ -46,60 +57,59 @@
 
 float latitude(char *ch)
 {
-    float res, res1, res2, res3;
-    res1 = decode_nombre(ch,17,2);          //retrouve les degrés en sexagesimal dans la trame
-    res2 = decode_nombre(ch,19,2);          //retrouver les minutes en sexagesimal dans la trame
-    res3 = decode_nombre(ch,22,4);          //retrouver les secondes en sexagesimal dans la trame
-    res = res1 + (res2 + res3/10000)/60;    //conversion sexagesimal à degrés
-    if(ch[27]=='S')                         //identifie si la latitude est nord ou sud
-        res = -res;
-    return res;
+    float r, r1, r2, r3;
+    r1 = decode_nombre(ch,17,2);    //décode les degrés en sexagesimal dans la trame
+    r2 = decode_nombre(ch,19,2);    //décode les minutes en sexagesimal dans la trame
+    r3 = decode_nombre(ch,22,4);    //décode les secondes en sexagesimal dans la trame
+    r = r1 + (r2 + r3/10000)/60;    //conversion sexagesimal à degrés
+    if(ch[27]=='S')                 //identifie la polarité de la latitude
+        r = -r;
+    return r;
 }
 
 float longitude(char *ch)
 {
-    float res, res1, res2, res3;
-    res1 = decode_nombre(ch,29,3);
-    res2 = decode_nombre(ch,32,2);
-    res3 = decode_nombre(ch,35,4);
-    res = res1 + (res2 + res3/10000)/60;
+    float r, r1, r2, r3;
+    r1 = decode_nombre(ch,29,3);    //décode les degrés en sexagesimal dans la trame
+    r2 = decode_nombre(ch,32,2);    //décode les minutes en sexagesimal dans la trame
+    r3 = decode_nombre(ch,35,4);    //décode les secondes en sexagesimal dans la trame
+    r = r1 + (r2 + r3/10000)/60;
     if(ch[40]=='W')
-        res = -res;
-    return res;
+        r = -r;
+    return r;
 }
 
-/*
-struct position decode_trame(char *ch, float latitud, float longitud)
+float decode_trame_latitude(char *ch)   // une position est donnée par deux fonctions : decode_trame_latitude() et decode_trame_longitude()
 {
-    position pos;
-    pos.latitud=latitude(ch);
-    pos.longitud=longitude(ch);
-    return pos;
-}
-*/
-
-float decode_trame_latitude(char *ch)
-{
     position p1;
     p1.lat = latitude(ch);
     return p1.lat;
 }
 
-float decode_trame_longitude(char *ch)
+float decode_trame_longitude(char *ch)  // une position est donnée par deux fonctions : decode_trame_latitude() et decode_trame_longitude()
 {
-    position p2;
-    p2.lon = longitude(ch);
-    return p2.lon;
+    position p1;
+    p1.lon = longitude(ch);
+    return p1.lon;
 }
 
 
-float calcul_distance(position p1, position p2)
+float calcul_distance(position p1, position p2) // Etablie une distance en km entre deux positions
 {
     float a;
+    a = sqrt(pow((p2.lat-p1.lat)*PI*R/180.0,2)+pow(((p2.lon-p1.lon)*(cos(((p2.lat+p1.lat)/2.0)*PI/180.0)*PI*R/180.0)),2));
+    //a=R*sqrt(pow(p1.lat*PI/180-p2.lat*PI/180,2)+pow(sin(p1.lat*PI/180-p2.lat*PI/180),2)*pow(p1.lon*PI/180-p2.lon*PI/180,2));
+    return a;
 }
 
+float calcul_vitesse(position p1, position p2)  // Etablie une vitesse en km/h entre deux positions en prenant en compte 1 seconde comme fréquence d'échantillonage des trames
+{
+    float v;
+    v=calcul_distance(p1,p2)*3600;
+    return v;
+}
 
-int trame_cmp(char * trame,char * type)
+int trame_cmp(char * trame,char * type) // Verification du format GPGGA d'une trame GPS
 {
     int i;
     for (i=0;i<5;i++)
@@ -108,21 +118,71 @@
     return 1;
 }
 
-
-//Fonction à modifier !!!!!
-void traitement(char * trame)
+int distance_a_la_plus_proche_zone(position p, zone r[], int nb_zones, float *d) // Renvoie l'indice de la zone la plus proche dans le tableau zones connu à l'avance à partir d'une position
 {
-    static int cpt=0;
+    int i,j=0;
+    float min = calcul_distance(p,r[0].rpos);
+    for (i=0;i<nb_zones;i++)
+    {
+        if (calcul_distance(p,r[i].rpos) <= min)
+            {
+            min = calcul_distance(p,r[i].rpos);
+            j=i;
+            }
+    }
+    return j;
+}
+
+void afficher_alarme(int alarme)
+{
+    if (alarme == 1)
+        printf("Alarme : ON\n");    // l'alarme s'active lorsque la fonction alarme() renvoie 1
+        else                        // sinon renvoie 0 elle ne s'active pas
+            printf("Alarme : OFF\n");
+}
+
+int alarme(char *trame) // On veut activer l'alarme lorsque la distance est inférieur à seuil = 0.1km et v > vmax correspondant au tableau zones
+{
+    static int i=0;
+    int a,j, alarme;
+    float v, vmax, d, seuil = 0.1;  // seuil défini à 0.1km arbitrairement
+    position p1, p2;
+    p1.lat = decode_trame_latitude(trame);  // récupère la position de la première trame reçu
+    p1.lon = decode_trame_longitude(trame);
+    p2.lat = decode_trame_latitude(&t);             // récupère la position de la trame reçu juste après
+    p2.lon = decode_trame_longitude(&t);
+    v = calcul_vitesse(p1,p2);              // récupère la vitesse maximale autorisée dans une zone dangereuse
+    vmax = zones[i].vitmax;
+    j=distance_a_la_plus_proche_zone(p2,zones,3,&d);    // récupère l'indice de la zone dangereuse la plus proche
+    d=calcul_distance(p2,zones[j].rpos);
+    i++;
+    if ((d < seuil) && (v > vmax))  // si on est trop proche de la zone avec une vitesse au-delà de la limitation l'alarme s'active (état 1);
+        alarme = 1;
+        else
+            alarme = 0;             // sinon l'alarme ne s'active pas (état 0)
+    return alarme;
+}
+
+
+
+//Fonction à modifier !!!!!
+void traitement(char * trame)
+{
+    static int cpt=0, k=0;
     cpt++;
     if(trame_cmp(trame,"GPGGA")==1)//verifie le bon format de la trame
     {
         printf("> %s\n",trame);
         printf("La latitude est %f.\nLa longitude est %f.\n",decode_trame_latitude(trame),decode_trame_longitude(trame));
+        t[k+1]=trame; // on stock dans un tableau t les trames reçu pour pouvoir prendre 2 trames consécutives et faire les calculs
+        k++;
+        afficher_alarme(alarme(trame));
     }
-}
-
-//Ajouter vos tests unitaires dans cette fonction.
-void tests_unitaires(void){
+}
+
+
+//Ajoutez vos tests unitaires dans cette fonction.
+void tests_unitaires(void){
     if (5!=5)
     {
         printf ("Erreur Test unitaire basique.\n");
@@ -160,29 +220,76 @@
         exit(-1);
     }
     if(fabs(longitude("$GPGGA,141914.00,4545.0000,N,00306.6036,E,1,05,3.4,499.3,M,,M,,*7D")-3.11006) > 10e-6)
-	{
+    {
         printf ("Erreur Test unitaire longitude.\n");
         exit(-1);
     }
-}
+    p1.lat = 48.856614; // Paris
+    p1.lon = 2.352221;
+    p2.lat = 43.296482; // Marseille
+    p2.lon = 5.369780;
+    p3.lat = 45.774838; // Clermont
+    p3.lon = 3.084583;
+    p4.lat = 45.762011; // Lyon
+    p4.lon = 4.834542;
+    p5.lat = 47.3215806; // dijon
+    p5.lon = 5.0414701;
+    p6.lat = 45.750000; // trame énoncé (préparation séance 2 question 6)
+    p6.lon = 3.110060;
+    p7.lat = 45.750403; // trame énoncé (préparation séance 2 question 6)
+    p7.lon = 3.110065;
+    if (calcul_distance(p1,p2)<=660 && calcul_distance(p1,p2)>= 661) // Test distance Paris - Marseille qui doit être 660,X km.
+    {
+        printf("Erreur test unitaire calcul_distance1");
+        exit(-1);
+    }
+    if (calcul_distance(p3,p5)<=227 && calcul_distance(p3,p5)>= 228) // Test distance Clermont - Dijon qui doit être de 227,X km.
+    {
+        printf("Erreur test unitaire calcul_distance2");
+        exit(-1);
+    }
+    if (calcul_distance(p3,p4)<=135 && calcul_distance(p3,p4)>= 136) // Test distance Lyon - Clermont-Ferrand qui doit être de 135,X km.
+    {
+        printf("Erreur test unitaire calcul_distance3");
+        exit(-1);
+    }
+    if (calcul_distance(p6,p7)<=0.0500 && calcul_distance(p6,p7)>= 0.0499)  // Test distance entre les deux trames de l'énoncé qui doit être de 44,9XX mètres
+    {
+        printf("Erreur test unitaire calcul_distance4");
+        exit(-1);
+    }
+    if (calcul_vitesse(p6,p7)<=161 && calcul_vitesse(p6,p7)>= 162) // Test calcul vitesse des trames de l'énonce qui doit être de 161,XXX km/h
+    {
+        printf("Erreur test unitaire calcul_vitesse");
+        exit(-1);
+    }
+    if (distance_a_la_plus_proche_zone(p7,zones,3,&d)!=2) // La 3ème zone doit être la plus proche.
+    {
+        printf("Erreur test unitaire calcul_distance_a_la_plus_proche_zone");
+        exit(-1);
+    }
+}
 
-
-// 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);
-}
 
 
+
+// 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;
+}
+
+
