2017-02-07 2 views
0

Récemment, je travaille sur la communication voiture-X et j'utilise deux unités embarquées (OBU). Il est possible de lire et de surveiller les données GPS sur les deux modules avec les clients gpsd, gpsd et aussi de mesurer les performances du réseau avec iPerf. Pour ce faire, un appareil agit en tant que serveur et l'autre agit en tant que client. Maintenant, je voudrais connecter ces deux appareils avec deux ordinateurs portables différents et mesurer les performances du réseau ainsi que lire les données GPS en dehors des OBU. De plus, j'ai besoin de synchroniser les données GPS et la sortie iPerf pour pouvoir détecter le TPV (temps, position, vitesse), le temps de latence, etc. Maintenant, je dois synchroniser les données GPS et iPerf afin de pouvoir les stocker fichier et traiter les données plus tard. Est-ce que n'importe qui peut m'aider avec l'idée comment faire cela. J'ai déjà essayé une solution qui est - Horodatage à la fois GPS & données iperf, et stocker dans les journaux. J'ai la 2ème solution qui consiste à envoyer des données GPS en tant que charge utile iperf, en utilisant l'option -f. Je voudrais essayer le 2ème, mais je ne sais pas exactement comment le faire. L'aide de quiconque est vraiment appréciée.Besoin d'une solution pour synchroniser les données reçues de l'iPerf et du GPS

Répondre

0

Vous ne mentionnez pas les langages de script ou les langages de programmation que vous connaissez. Il y a plusieurs façons de le faire, d'un simple script python ou bash, à des programmes C++ plus complexes. Je ne voulais pas écrire un logiciel de démonstration complet pour vous ne sachant pas précisément ce que vous cherchiez, mais j'ai été capable de prendre des parties de ce sample c++ gpsd client et de le modifier afin qu'il fonctionne aussi iperf et la sortie en tant que csv (qui vous pouvez ensuite diriger vers un enregistreur ou comme vous voulez le faire).

#include <iostream> 
#include <iomanip> 
#include <ctime> 
#include <sstream> 
#include <memory> 

#include <libgpsmm.h> 

std::string exec(const char *cmd) { 
    std::array<char, 128> buffer; 
    std::string result; 
    std::shared_ptr<FILE> pipe(popen(cmd, "r"), pclose); 

    if (!pipe) throw std::runtime_error("popen() failed!"); 

    while (!feof(pipe.get())) { 
    if (fgets(buffer.data(), 128, pipe.get()) != NULL) result += buffer.data(); 
    } 
    return result; 
} 

int main(int argc, char **argv) 
{ 
    if (argc < 2) { 
    std::cout << "Please execute command with a remote iperf server. Exiting." << 
    "\n"; 
    return 1; 
    } 

    gpsmm gps_rec("localhost", DEFAULT_GPSD_PORT); 

    if (gps_rec.stream(WATCH_ENABLE | WATCH_JSON) == NULL) { 
    std::cerr << "No GPSD running.\n"; 
    return 1; 
    } 

    for (;;) { 
    // run iperf and get output in a string (note: needs error checking!) 
    // the cut portion is there to remove the first column from the csv output 
    // which is time, as we'll take the gps time instead. 
    std::stringstream iperfCmd; 
    iperfCmd << "iperf -c " << argv[1] << " -ey C | cut -d , -f 2-9"; 
    const std::string& tmp = iperfCmd.str(); 
    const char *iperfCmdArr = tmp.c_str(); 
    std::string iperfOutput = exec(iperfCmdArr); 

    struct gps_data_t *newdata; 

    if (!gps_rec.waiting(50000000)) continue; 

    if ((newdata = gps_rec.read()) == NULL) { 
     std::cerr << "Read error.\n"; 
     return 1; 
    } else { 
     while (((newdata = gps_rec.read()) == NULL) || 
      (newdata->fix.mode < 1)) { 
     // Do nothing; don't want to output wrong initial time 
     } 
     timestamp_t ts = newdata->fix.time; 
     double latitude = newdata->fix.latitude; 
     double longitude = newdata->fix.longitude; 

     // convert GPSD's timestamp_t into time_t 
     time_t seconds; 
     seconds = (time_t)ts; 
     auto tm = *std::localtime(&seconds); 

     std::ostringstream oss; 
     oss << std::put_time(&tm, "%d-%m-%Y %H:%M:%S"); 
     auto time_str = oss.str(); 

     // set decimal precision 
     std::cout.precision(6); 
     std::cout.setf(std::ios::fixed, std::ios::floatfield); 
     std::cout << time_str << "," << 
     latitude << "," << 
     longitude << "," << iperfOutput; 

     // uncomment below to break out of for loop (will only output 1 iteration) 
     // return 0; 
    } 
    } 
    return 0; 
} 

Vous pouvez modifier la variable iperfCmd pour modifier la commande iperf. Par exemple, vous pouvez le remplacer par "-rey C" si vous souhaitez exécuter un test bidirectionnel. Regardez iperf - help pour ce dont vous avez besoin, mais vous devrez garder le drapeau "-y C" pour la sortie CSV. Si vous avez gpsd (et parfois les bibliothèques libgps-dev nécessaires), vous pouvez compiler le code en tant que tel:

g++ -Wall -std=c++14 -pedantic $(pkg-config --cflags --libs libgps) gpsd-iperf-example.cpp -o gpsd-iperf-example 

Ensuite, il suffit d'exécuter (Appuyez sur CTRL-C pour arrêter):

gpsd-iperf-example servername 

En supposant gpsd fonctionne correctement, et que vous utilisez v2 iperf, la sortie devrait ressembler à ceci:

07-05-2017 19:05:10,45.3XXXXX,-75.8XXXXX,192.168.2.36,40466,192.168.2.28,5001,4,0.0-10.0,286785536,228615722 
07-05-2017 19:05:11,45.3XXXXX,-75.8XXXXX,192.168.2.36,40468,192.168.2.28,5001,4,0.0-10.0,328859648,261792317 
07-05-2017 19:05:12,45.3XXXXX,-75.8XXXXX,192.168.2.36,40470,192.168.2.28,5001,4,0.0-10.0,293601280,234307789 

qui vous pouvez continuer à analyser ou simplement ajuster C++ programme. Je ne sais pas si c'est ce que vous cherchiez, mais encore une fois, de nombreuses façons de le faire, il suffit de chercher des bribes de code et de s'adapter à vos besoins.