détecter un excès de vitesse avec un GPS

Bonjour,

je travail actuellement sur un système de prévention et d'alerte en cas d'accident dans une voiture, le projet comptera pour le Bac.
On ma donc confié la tâche de détecter un excès de vitesse dans une voiture grâce à un GPS. le GPS que j'ai à disposition est un grove gps et j'ai une arduino mega 2560.

A proprement parler, je ne dois pas dire quand la voiture roule a 130 km/h sur une route à 90 ( se serrait bien trop dur ^^' ) mais plutôt dire lorsque la vitesse du véhicule augmente trop brusquement par rapport à une vitesse initiale.
Donc, je suis parti du principe qu'il fallait que je calcule 2 vitesses et que je fasse la différence des 2 pour dire lorsque la voiture à une vitesse trop importante.

n'ayant pas de grosses compétences en arduino, j'ai pris un programme GPS permettant de calculer une distance par rapport à 2 points et je l'ai modifié.

int i = 1;
int message[100];
int inByte;
String str = "";
int index;

///// DISTANCE /////
///// Latitude A/////
int Degre;
int Minute;
int Seconde;
///// Longitude A/////
int Degre1;
int Minute1;
int Seconde1;

///// Latitude B/////
int Degre2;
int Minute2;
int Seconde2;
///// Longitude B/////
int Degre3;
int Minute3;
int Seconde3;

//// DISTANCE 1 ////
///// Latitude A/////
int Degre4;
int Minute4;
int Seconde4;
///// Longitude A/////
int Degre5;
int Minute5;
int Seconde5;

///// Latitude B/////
int Degre6;
int Minute6;
int Seconde6;
///// Longitude B/////
int Degre7;
int Minute7;
int Seconde7;

float Rayon_Geo = 6372.8;
const float pi = 3.14;

void setup()
{
  // Lancement serial port
  Serial.begin(9600);
  Serial1.begin(9600);

}

void loop()
{
   
  //Lire sur port 1, Envoyer sur port 0
  if (Serial1.available() > 0)
  {
    str = Serial1.readStringUntil('\n');
    i = 0;

    index = str.indexOf("GPGGA");

    if (index >= 0)
    {

      ///////////////////////////////    DISTANCE    //////////////////////////////
      
      ///// Position GPS DMS Latitude A /////
     

      Degre = (str.substring(18, 20).toInt()); 
      Minute = (str.substring(20, 22).toInt()); 
      Seconde = (str.substring(23, 27).toInt()); 

      ///// Position GPS DMS Longitude A /////
 
      Degre1 = (str.substring(32, 33).toInt()); 
      Minute1 = (str.substring(33, 35).toInt()); 
      Seconde1 = (str.substring(36, 40).toInt()); 
      
      delay(4000); //delay entre le point A et le point B qui nous permet par la suite de calculer la vitesse 
      
      ///// Position GPS DMS Latitude B /////
      

      Degre2 = (str.substring(18, 20).toInt());  
      Minute2 = (str.substring(20, 22).toInt()); 
      Seconde2 = (str.substring(23, 27).toInt()); 

      ///// Position GPS DMS Longitude B /////
      
      Degre3 = (str.substring(32, 33).toInt()); 
      Minute3 = (str.substring(33, 35).toInt()); 
      Seconde3 = (str.substring(36, 40).toInt()); 

      delay(5000); // le temps d'écart entre DISTANCE et DISTANCE 1 //

        ///////////////////////////////    DISTANCE 1   //////////////////////////////
        
        ///// Position GPS DMS Latitude A /////
     
      Degre4 = (str.substring(18, 20).toInt()); 
      Minute4 = (str.substring(20, 22).toInt()); 
      Seconde4 = (str.substring(23, 27).toInt()); 

      ///// Position GPS DMS Longitude A /////
 
      Degre5 = (str.substring(32, 33).toInt()); 
      Minute5 = (str.substring(33, 35).toInt()); 
      Seconde5 = (str.substring(36, 40).toInt()); 
      
      delay(4000); //delay entre le point A et le point B qui nous permet par la suite de calculer la vitesse 
      
      ///// Position GPS DMS Latitude B /////
      

      Degre6 = (str.substring(18, 20).toInt());  
      Minute6 = (str.substring(20, 22).toInt()); 
      Seconde6 = (str.substring(23, 27).toInt()); 

      ///// Position GPS DMS Longitude B /////
      
      Degre7 = (str.substring(32, 33).toInt()); 
      Minute7 = (str.substring(33, 35).toInt()); 
      Seconde7 = (str.substring(36, 40).toInt());

    }
  
  }
  ///// Conversion DMS vers DD  Latitude A /////

  float pos_Lat_A = (((Degre) + (Minute / 60)) + ((Seconde / 100) / 3600));

  ///// Conversion DMS vers DD  Longitude A /////
  float pos_Longi_A = ((((Degre1) + (Minute1 / 60)) + ((Seconde1 / 100) / 3600)))*(-1);

  ///// Conversion DMS vers DD  Longitude B /////
  float pos_Lat_B = (((Degre2) + (Minute2 / 60)) + ((Seconde2 / 100) / 3600));

  ///// Conversion DMS vers DD  Longitude B /////
  float pos_Longi_B = ((((Degre3) + (Minute3 / 60)) + ((Seconde3 / 100) / 3600)))*(-1);


  ///// Calcul de distance entre deux points A et B/////
  int Distance = (Rayon_Geo * acos(sin(pos_Lat_A) * sin(pos_Lat_B) + cos(pos_Lat_A) * cos(pos_Lat_B) * cos(pos_Longi_A - pos_Longi_B)));

  ///// Calcul de la vitesse /////
  int Speed = Distance / 4;

  ///// Conversion DMS vers DD  Latitude A /////

  float pos_Lat_A1 = (((Degre4) + (Minute4 / 60)) + ((Seconde4 / 100) / 3600));

  ///// Conversion DMS vers DD  Longitude A /////
  float pos_Longi_A1 = ((((Degre5) + (Minute5 / 60)) + ((Seconde5 / 100) / 3600)))*(-1);

  ///// Conversion DMS vers DD  Longitude B /////
  float pos_Lat_B1 = (((Degre6) + (Minute6 / 60)) + ((Seconde6 / 100) / 3600));

  ///// Conversion DMS vers DD  Longitude B /////
  float pos_Longi_B1 = ((((Degre7) + (Minute7 / 60)) + ((Seconde7 / 100) / 3600)))*(-1);

  
 ///// Calcul de distance entre deux points A et B///// 
 int Distance1 = (Rayon_Geo * acos(sin(pos_Lat_A1) * sin(pos_Lat_B1) + cos(pos_Lat_A1) * cos(pos_Lat_B1) * cos(pos_Longi_A1 - pos_Longi_B1)));

 ///// Calcul de la vitesse /////
  int Speed1 = Distance1 / 4;


  int Difference = Speed - Speed1;

  if (Difference <= -10);

  { 
    Serial.print("Le vehicule va trop vite");
    Serial.println();
  }
}

Comme vous pouvez le voir, le programme est long, sans doute dû au fait que je répète plusieurs passages pour avoir 2 vitesses distinctes.

Au début, rien de spéciale , je déclare toute les valeurs nécessaires et je mets en place 2 liaisons séries.
Ensuite, comme le GPS affiche plusieurs ligne de caractères, il faut les filtrer pour seulement prendre les informations qui m'intéresse en l’occurrence la latitude et la longitude.
Je laisse un temps de 4 secondes entre les 2 points ( A et B ) pour ensuite appliquer la fameuse formule V = D/T

comme la latitude et la longitude sont en Dixième de milliseconde, je les converties en degrés décimale et ensuite j 'applique une formule trouvé sur internet pour calculer une distance par rapport à 2 points dans un plan ovale ( la terre en gros ). Le reste est facile à comprendre mais vous aurez sans doute remarqué que je répète plusieurs fois les même parties du programme. C'est la seul solution que j'ai trouvé pour avoir une distance 1 et une distance 2 qui ne soit pas identique.

Concrètement, je ne sais pas si mon programme marche, bien que je me doute qu'il y ait des erreurs.
Pour le tester, je me suis baladé dans mon jardin avec mon ordinateur portable+arduino+ GPS mais la distance ne devait pas être assez grande car je n'avait que des valeurs nuls. Pouvoir tester le programme en temps réel est un des problèmes.

Le deuxième étant que je me suis compliqué la tâche et ça se voit :confused: c'est pour ce la que j'aimerai donc savoir s'il était possible de simplifier mon programme ou si d'autres méthodes auquel je n’aurait pas pensé étaient envisageable avec le matériel que j'ai à disposition.

Franchement j'ai pas lu tout le code, mais il me semble que le GPS envoie via un certains type de trame la vitesse en clair.

Quelle modèle GPS as tu ?

avec la librairie tinyGPS, et les bonne trames GPs, tu peux connaitre la vitesse exact de ton GPS. le tout en km/h.

-La trame : VTG

$GPVTG,054.7,T,034.4,M,005.5,N,010.2,K

010.2,K = Vitesse du déplacement par rapport au sol en Kilomètres heure. (K)

mais dans la librairie tinyGPS tu as deja une fonction toute faite:

Serial.println(gps.speed.kmph()); // Speed in kilometers per hour (double)

avec la librairie adequat tu gagneras des lignes de codes...

regarde ici pour plus d'infos
http://arduiniana.org/libraries/tinygps/

bonjour,
pas claire ton histoire.
tu ne veux pas dire si une vitesse est supérieure à la vitesse normale, ok.
mais tu veux avoir une alerte si trop forte accélération.
cette différence se fait par rapport à quoi?
temps, distance?
si temps, c'est pas trop compliqué, tu prends une 1ere vitesse avec millis()
tu en prends une autre X millis() après
si l'écart que tu as fixé entre les deux vitesse par rapport au temps, tu alerte.
sinon, la deuxième vitesse prends la place de la première
etc...

donc change ton titre dans ce cas :wink:

Merci pour vos réponses,

Comme je l'ai dit au début, mon gps est un grove, comme celui-ci http://www.seeedstudio.com/wiki/Grove_-_GPS

Effectivement, c'est la trame VTG qui doit donner la vitesse, quand j'ai étudié les trames de mon GPS, je ne m'en était pas rendu compte. ça rend mon programme obsolète mais c'est pas plus mal car il sera beaucoup plus court. Merci pour le lien :wink: .

Sinon, oui j'ai un peu de mal à m'expliquer mais tu as compris ce que je voulais dire.
Pour faire simple, j 'ai 2 vitesses, je fais : Vitesse1 - Vitesse2 et si le nombre obtenu est négatif et qu'il dépasse un certain pallié défini par exemple 10m/s alors il y a message d'alerte et je vais faire une différence par rapport au temps, ça me semble le plus simple :wink: .