Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 06/03/2014, à 11:51

zodd

libgpsmm - C++ class wrapper for the GPS daemon

Bonjour,

j'essaie de comprendre comment utiliser ce "wrapper" pour utiliser le daemon GPS dans un programme Qt.

Le manpage est très très "sec" je trouve:
http://manpages.ubuntu.com/manpages/pre … smm.3.html
http://www.justmanpage.com/man/libgpsmm.3

j'ai créé ceci dans le header de ma class:

private:
....
        gpsmm *m_gpsd;
        char hostName[10];
        char hostPort[5];

et ensuite dans mon construteur dans le cpp:

  strcpy(hostName, "localhost"); //pas très élégant 
  strcpy(hostPort, "2947");
  m_gpsd = new gpsmm(hostName, hostPort);

et dans une méthode j'appelle ceci:
m_gpsd->... le problème c'est qu'il n'y a pas open de proposé ....

comme on le voit ici:
   gps_data_t* data = m_gpsd.open();
inspiré par le code trouvé là:
http://code.ohloh.net/file?fid=I5jZy0nA … ed=true#L0


Si quelqu'un peut m'aider, merci

Dernière modification par zodd (Le 06/03/2014, à 12:24)

Hors ligne

#2 Le 06/03/2014, à 13:28

lann

Re : libgpsmm - C++ class wrapper for the GPS daemon

Et si tu met cette ligne, ça compile ?

Hors ligne

#3 Le 06/03/2014, à 15:17

zodd

Re : libgpsmm - C++ class wrapper for the GPS daemon

non j'ai ce message d'erreur:
error: 'class gpsmm' has no member named 'open'

Hors ligne

#4 Le 06/03/2014, à 17:35

lann

Re : libgpsmm - C++ class wrapper for the GPS daemon

Apparement en regardant le code du constructeur https://fossies.org/dox/gpsd-3.10/libgp … ource.html, la fonction open est directement lancée dans le constructeur

Hors ligne

#5 Le 08/03/2014, à 10:50

zodd

Re : libgpsmm - C++ class wrapper for the GPS daemon

c'est gps_inner_open qui est lancé par le constructeur. Du coup je me dis la man n'est pas à jour.. je l'avais remarqué cette fonction et elle est private d'ailleurs..

entre temps j'ai trouvé un script python peut être exploitable.... à voir..  mais l'idéal serait de voir comment créer un signal associé à ce wrapper C++ pour l'intégrer dans Qt avec le mécanisme des signaux/slot.

Dernière modification par zodd (Le 08/03/2014, à 10:51)

Hors ligne

#6 Le 08/03/2014, à 14:26

lann

Re : libgpsmm - C++ class wrapper for the GPS daemon

Je ne connais pas Qt. J'utilise, pour ma part, gtkmm.
J'ai déjà mis en place mes propres signaux avec cette bibliothèque. Ce n'est pas très compliqué et c'est très pratique.
Bonne chance

Hors ligne

#7 Le 10/03/2014, à 15:02

zodd

Re : libgpsmm - C++ class wrapper for the GPS daemon

Salut,

j'ai commencé à regarder où positionner les signaux.. tu pourrais expliquer comment tu t'y es pris s'il te plait?

Hors ligne

#8 Le 10/03/2014, à 18:24

lann

Re : libgpsmm - C++ class wrapper for the GPS daemon

Dans le fichier.h

public :
typedef sigc::signal<void, std::string, std::string> type_signal_on_click_modify_oe;
     type_signal_on_click_modify_oe signal_click_modify_oe(); 
protected:
 type_signal_on_click_modify_oe m_signal_click_modify_oe;

Dans le fichier.cpp pour envoyer le signal :

m_signal_click_modify_oe.emit(m_szspecialite, resultat[0][0]);

Puis dans une autre classe qui utilise le signal de cette classe, je créé une fonction qui démarrera lorsque ce signal sera émis.

J'ai adapté mon code à partir de cette page http://fr.openclassrooms.com/informatiq … partie-1-2

Hors ligne

#9 Le 11/03/2014, à 11:37

zodd

Re : libgpsmm - C++ class wrapper for the GPS daemon

Question bête, tu émets ton signal lorsque tu cliques sur quelque-chose? merci pour le lien, je vais consulter ça ^^

Hors ligne

#10 Le 11/03/2014, à 11:55

lann

Re : libgpsmm - C++ class wrapper for the GPS daemon

Tu émets ton signal lorsque tu considères que l'action attendue est atteinte dans une fonction que tu as toi même programmée

Hors ligne

#11 Le 11/03/2014, à 12:34

zodd

Re : libgpsmm - C++ class wrapper for the GPS daemon

oui mais c'est là le problème que j'ai. Je ne sais pas quand l'action attendue est atteinte. Les trames AIS arrivent de manières totalement aléatoires car elles dépendent des bateaux sur zone. Donc il faudrait que ce soit le démon qui émettent le signal en question.. non?

Hors ligne

#12 Le 11/03/2014, à 12:46

lann

Re : libgpsmm - C++ class wrapper for the GPS daemon

Je ne sais absolument pas ce que tu veux faire.
Il faudrait que tu expliques en détail ton projet et le matériel utilisé

Merci

Hors ligne

#13 Le 11/03/2014, à 16:31

zodd

Re : libgpsmm - C++ class wrapper for the GPS daemon

alors en fait  pour résumer ce que je veux faire^^ Le PC est sensé recevoir des trames GPS et AIS (donc de type NMEA). Hors l' AIS est un système d'identification automatique: des trames sont envoyées par les bateaux et contiennent un certain nombre d'information (position, vitesse, cap, etc..) ; elles sont envoyées plus ou moins souvent selon la vitesses des bateaux, et peuvent être segmentées, .. etc.. leur décodage est donc assez complexe. Hors le daemon gpsd est capable de les décoder.

Mon but es donct de me servir de GPSD pour interpréter les trames NMEA reçut..
Quelqu'un a fait un truc en python pour les trames AIS qui correspond exactement à ce que je veux faire pour les trames NMEA AIS (AIVDM):
https://github.com/IvanSanchez/gpsd-ais-viewer

j'aimerai réussir à faire la même chose en C++ et mettre à jour automatiquement une partie de ma fenêtre (mon application fait d'autres choses que recevoir ces trames). Je souhaiterai faire cela de façon non bloquante.. je ne peux donc pas faire boucler mon programme sur la sortie du daemon, d'où le faite que j'essaie de voir comment émettre un signal approprié.. j'ai pensé aussi à utiliser un autre thread.. mais j'ai vu aussi ici:
http://manpages.ubuntu.com/manpages/pre … smm.3.html
qu'il y a une fonction de callback.. je me demande donc comment m'en servir ( à la place d'utiliser un thread)..je suis tombé sur ceci dans la doc  http://qt-project.org/wiki/Threads_Events_QObjects   :
“If you need to use a library or other code that doesn’t offer a non-blocking API (by means of signals and slots, or events, or callbacks, etc.)”
par contre j'ai l'impression que ces fonctions ne sont la que dans la version pour precise 12.04 ...  donc je ne sais pas quoi penser..

j'espère être plus clair..^^

Dernière modification par zodd (Le 11/03/2014, à 16:34)

Hors ligne

#14 Le 11/03/2014, à 18:00

lann

Re : libgpsmm - C++ class wrapper for the GPS daemon

Oui c'est plus clair
De ce que je comprends et ça se voit dans le code https://fossies.org/dox/gpsd-3.10/libgp … tml#l00062, gpsmm est une surcouche en C++ pour pouvoir utiliser libgps
Par contre libQgpsmm utilise la bibliothèque et daemon gpsd

La connection au récepteur GPS se fait via le constructeur pour libgpsmm.
Malheureusement, je n'ai pas vu de fonction callback te permettant de mettre à jour ton affichage lorsque les données sont diffusées.
Par contre, ce que tu peux faire c'est de mettre à jour l'affichage toutes les N secondes. La bibliothèque gtkmm permet de faire cela facilement :

Dans fichier.h, tu créés une fonction de ce type

bool on_timeout(int valeur);

puis dans fichier.cpp qui gère l'affichage, tu ajoutes ceci dans le constructeur :

sigc::slot<bool> timer_slot=sigc::bind(sigc::mem_fun(*this,&Ma_classe::on_timeout),m_valeur_rien);
     sigc::connection conn=Glib::signal_timeout().connect_seconds(timer_slot,60);

avec m_valeur_rien=0
La valeur 60, dans la deuxième ligne, correspond à 60 secondes

Toujours dans le fichier.cpp, tu ajoutes la fonction on_timeout de cette façon :

bool Ma_classe::on_timeout(int valeur)
{
     // Faire un appel vers la fonction read de libgpsmm
   // Mettre à jour ton affichage avec les valeurs récupérées
     return true;
}

De cette manière, ton affichage sera cohérent des dernières données fourni par le GPS sans bloquer la boucle principale de ton programme

Dernière modification par lann (Le 11/03/2014, à 18:03)

Hors ligne

#15 Le 12/03/2014, à 12:04

zodd

Re : libgpsmm - C++ class wrapper for the GPS daemon

Salut,

merci pour ta réponse, c'est sympa de pas se sentir tout seul^^
En fait, le fait de mettre à jour l'affichage toutes les N seconde convient bien avec le GPS. Mais avec l'AIS, si on ne veux pas louper de trames, ce n'est pas possible de procéder comme ça.

J'ai même pensé à faire logguer les trames décodées par le démon avec un script python (un truc inspiré du srcipt d'affichage dont j'ai mis le lien) mais qui loggue à la place dans un fichier et aller consulter ce fichier avec mon programme toutes les N seconde. mais ça n'est pas très élégant..

Je trouve quand même bizarre que le manpage de libQgpsmm soit "faux" ..l 'ouverture se faisant dans le constructeur avec une méthode privée gps_iner_open et non pas avec la méthode open par exemple, ou l’absence de fonction callback alors qu'elle apparait sur le man ...

Hors ligne

#16 Le 12/03/2014, à 14:45

lann

Re : libgpsmm - C++ class wrapper for the GPS daemon

Un autre petit code qui te permet de faire un thread. Il est lancé lorsque tu le souhaites puis il est constamment parcouru jusqu'à ce que tu arrêtes le thread

Dans le fichier.h

int Analyse(void);
sigc::connection pthread;  //Handle thread analyse
 

Dans le fichier.cpp

int Ma_classe::Analyse(void)
{
   gps_data_t* lus;
   lus=gpsmm.read();

   if (lus!=0)
   {
       Mise à jour de l'affichage

   }

  return true;
}

Dans le fichier.cpp

//Pour démarrer le thread
pthread=Glib::signal_idle().connect( sigc::mem_fun(*this, &Ma_classe::Analyse),Glib::PRIORITY_HIGH_IDLE + 20  /*Glib::PRIORITY_DEFAULT_IDLE*/); 

Dans le fichier.cpp

if (pthread.connected()) //If thread exist
    {
        pthread.disconnect();
   }

//pour arrêter le thread

Je pense que ça te conviendra mieux car il ne devrait pas avoir de messages perdus

Hors ligne

#17 Le 12/03/2014, à 19:25

zodd

Re : libgpsmm - C++ class wrapper for the GPS daemon

effectivement, c'est bien ça que je dois réaliser.  L'utilisation d'un thread semble être la seule solution. Merci pour ton aide wink

Je suppose que tes exemples sont valables pour gtk+, ça  doit être assez facile à adapter à du Qt je suppose.

Je mettrai le résultat dès que j'aurai pu tester (je suis dans le jus sur un autre truc là.. :s )

edit: j'ai trouvé ceci:
http://gpsd.berlios.de/client-howto.html

on voit bien la table 1  ce qui est utilisable comme méthodes et que open de la lib C correspond au constructeur.

Un dernier truc ^^ je n'ai jamais touché à python mais dans le script que j'ai trouvé, je me demande où est qu'il convertit les données NMEA brute en données humainement compréhensible.. il y a un petit truc qui m'échappe encore. en effet une trame AIVDM a cette "tête":
!AIVDM,1,1,,B,177KQJ5000G?tO`K>RA1wUbN0TKH,0*5C

177KQJ5000G?tO`K>RA1wUbN0TKH étant ce qu'on appelle le payload (une suite de bits à interpréter) et je ne vois pas où le script python traite ce payload et le daemon sort la trame AIVDM brute sur le port 2947 ..

Dernière modification par zodd (Le 12/03/2014, à 19:40)

Hors ligne

#18 Le 12/03/2014, à 21:20

lann

Re : libgpsmm - C++ class wrapper for the GPS daemon

C'est gpsd qui transforme en données humainement compréhensible : (dans applicable standard en bas de la page)
http://catb.org/gpsd/gpsd.html

Dernière modification par lann (Le 12/03/2014, à 21:20)

Hors ligne

#19 Le 13/03/2014, à 01:02

zodd

Re : libgpsmm - C++ class wrapper for the GPS daemon

ok, en fait sur le port 2947, il ne fait "que" transférer les données brutes alors que si j'y accède avec gpsmm.read(), si je comprends bien,  il renvoie les données interprétés alors.. je vais essayer ça dès que possible^^

Hors ligne

#20 Le 28/05/2014, à 16:15

zodd

Re : libgpsmm - C++ class wrapper for the GPS daemon

Salut,

je peux enfin me remettre sur ce projet , ouf ^^
Alors j'ai mis en place un thread dédié sur Qt (je détaillerai plus tard ce point quand tout marchera pour ceux que ça intéresse).

Néanmoins, je rencontre toujours des problème pour faire fonctionner liggpsmm.

Alors déjà j'ai bien mon démon gpsd qui tourne et j'ai bien des trames NMEA (!AIVDM) qui sont envoyées sur le port 2947. (je les visualise bien avec openCPN).

Mais je n'arrive toujours pas à afficher quoi que ce soit dans mon programme.

Finalement j'ai fait un truc tout bête qui ne fait que ça. Voilà ce que je fait:

Dans mon constructeur:

  strcpy(hostName, "localhost");
  strcpy(hostPort, "2947");
  m_gpsd = new gpsmm(hostName, hostPort);

et ensuite j'ai une boucle infinit: dans un slot lancé lorsque l'on clique sur un bouton:

    gps_data_t* lus;
   while(1)
    {
        lus=m_gpsd->read();
        if(lus!=0)
        nbreBateauxTextdit->append(QString::number(lus->ais.mmsi));
   }

voilà j'essaie juste d'afficher le numéro mmsi du bateau ayant émis la trame (je suis certain d'en recevoir car je les affiche dan sopenCPN... ) mais le problème c'est que je n'affiche rien du tout, comme si aucune trame n'était reçut..

EDIT:
Bon je m'auto répond car avec la doc de la libC j'ai trouvé une solution qui fonctionne :
http://www.justmanpage.com/man/libgps.3
(voir tout en bas code example)

        m_gpsd->stream(WATCH_ENABLE | WATCH_JSON);
        while(1)
        {
        if(m_gpsd->waiting(500))
        {
            lus=m_gpsd->read();
            if(lus)
            {
              //affichage
            }
        }
        }

Dernière modification par zodd (Le 28/05/2014, à 16:57)

Hors ligne