// %flair:license{ // This file is part of the Flair framework distributed under the // CECILL-C License, Version 1.0. // %flair:license} // created: 2013/08/23 // filename: Gps.cpp // // author: Guillaume Sanahuja // Copyright Heudiasyc UMR UTC/CNRS 7253 // // version: $Id: $ // // purpose: objet integrant le recepteur gps mb800 // // /*********************************************************************/ #include "Gps.h" #include "geodesie.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include using std::string; using namespace Geodesie; using namespace flair::core; using namespace flair::gui; namespace flair { namespace sensor { Gps::Gps(const FrameworkManager *parent, string name, NMEAFlags_t NMEAFlags) : IODevice(parent, name) { this->NMEAFlags = NMEAFlags; nmea_zero_INFO(&info); nmea_parser_init(&parser); alt_ref = 0; if ((NMEAFlags & GGA) == 0) { Err("Enable at least GGA sentence\n"); } int index = 0; if ((NMEAFlags & GGA) != 0) { index += 3; } if ((NMEAFlags & VTG) != 0) { index += 2; } if ((NMEAFlags & GST) != 0) { index += 3; } cvmatrix_descriptor *desc = new cvmatrix_descriptor(index, 1); index = 0; if ((NMEAFlags & GGA) != 0) { desc->SetElementName(0, 0, "e"); desc->SetElementName(1, 0, "n"); desc->SetElementName(2, 0, "u"); index += 3; } if ((NMEAFlags & VTG) != 0) { desc->SetElementName(index, 0, "ve"); desc->SetElementName(index + 1, 0, "vn"); index += 2; } if ((NMEAFlags & GST) != 0) { desc->SetElementName(index, 0, "dev_lat"); desc->SetElementName(index + 1, 0, "dev_lon"); desc->SetElementName(index + 2, 0, "dev_elv"); index += 3; } output = new cvmatrix((IODevice *)this, desc, floatType); AddDataToLog(output); // station sol main_tab = new Tab(parent->GetTabWidget(), name); tab = new TabWidget(main_tab->NewRow(), name); sensor_tab = new Tab(tab, "Reglages"); GroupBox *reglages_groupbox = new GroupBox(sensor_tab->NewRow(), name); button_ref = new PushButton(reglages_groupbox->NewRow(), "set ref"); nb_sat_label = new Label(reglages_groupbox->NewRow(), "nb_sat"); fix_label = new Label(reglages_groupbox->LastRowLastCol(), "fix"); position = new GeoCoordinate((IODevice *)this, "position", 0, 0, 0); fix = FixQuality_t::Invalid; nb_sat = 0; take_ref = false; nb_sat_label->SetText("nb_sat: %i", nb_sat); fix_label->SetText("fix: %i", fix); } Gps::~Gps() { nmea_parser_destroy(&parser); delete main_tab; } void Gps::UseDefaultPlot(void) { int index = 0; plot_tab = new Tab(tab, "Mesures"); if ((NMEAFlags & GGA) != 0) { e_plot = new DataPlot1D(plot_tab->NewRow(), "e", -10, 10); e_plot->AddCurve(output->Element(index)); n_plot = new DataPlot1D(plot_tab->LastRowLastCol(), "n", -10, 10); n_plot->AddCurve(output->Element(index + 1)); u_plot = new DataPlot1D(plot_tab->LastRowLastCol(), "u", -10, 10); u_plot->AddCurve(output->Element(index + 2)); index += 3; } if ((NMEAFlags & VTG) != 0) { ve_plot = new DataPlot1D(plot_tab->NewRow(), "ve", -10, 10); ve_plot->AddCurve(output->Element(index)); vn_plot = new DataPlot1D(plot_tab->LastRowLastCol(), "vn", -10, 10); vn_plot->AddCurve(output->Element(index + 1)); index += 2; } Tab *map_tab = new Tab(tab, "carte"); map = new Map(map_tab->NewRow(), "map"); map->AddPoint(position, "drone"); } DataPlot1D *Gps::EPlot(void) const { if ((NMEAFlags & GGA) != 0) { return e_plot; } else { Err("GGA sentence not requested\n"); return NULL; } } DataPlot1D *Gps::NPlot(void) const { if ((NMEAFlags & GGA) != 0) { return n_plot; } else { Err("GGA sentence not requested\n"); return NULL; } } DataPlot1D *Gps::UPlot(void) const { if ((NMEAFlags & GGA) != 0) { return u_plot; } else { Err("GGA sentence not requested\n"); return NULL; } } DataPlot1D *Gps::VEPlot(void) const { if ((NMEAFlags & VTG) != 0) { return ve_plot; } else { Err("GGA sentence not requested\n"); return NULL; } } DataPlot1D *Gps::VNPlot(void) const { if ((NMEAFlags & VTG) != 0) { return vn_plot; } else { Err("GGA sentence not requested\n"); return NULL; } } Layout *Gps::GetLayout(void) const { return sensor_tab; } Tab *Gps::GetPlotTab(void) const { return plot_tab; } TabWidget *Gps::GetTab(void) const { return tab; } uint16_t Gps::NbSat(void) const { output->GetMutex(); uint16_t result = nb_sat; output->ReleaseMutex(); return result; } Gps::FixQuality_t Gps::FixQuality(void) const { output->GetMutex(); FixQuality_t result = fix; output->ReleaseMutex(); return result; } void Gps::SetRef(void) { take_ref = true; } void Gps::GetENUPosition(Vector3D *point) { output->GetMutex(); point->x = output->ValueNoMutex(0, 0); point->y = output->ValueNoMutex(1, 0); point->z = output->ValueNoMutex(2, 0); output->ReleaseMutex(); } void Gps::parseFrame(const char *frame, int frame_size) { int result; result = nmea_parse(&parser, frame, frame_size, &info); if (result != 1) { Warn("unrecognized nmea sentence\n"); Warn("%s\n", frame); } result = nmea_parse_GPGGA(frame, frame_size, &pack); if (result == 1) { // Printf("%s\n",frame); // Printf("nb:%i fix:%i lat:%f long:%f alt:%f vel:%f // angle:%f\n",pack.satinuse,pack.sig,info.lat,info.lon,info.elv,info.speed*1000./3600.,info.direction); // Printf("lat:%f long:%f\n",pos.lat,pos.lon); output->GetMutex(); // on utilise le mutex de l'output pour fix et nb_sat if ((int)fix != pack.sig) { fix = (FixQuality_t)pack.sig; fix_label->SetText("fix: %i", fix); } if (nb_sat != pack.satinuse) { nb_sat = pack.satinuse; nb_sat_label->SetText("nb_sat: %i", nb_sat); } output->ReleaseMutex(); nmea_info2pos(&info, &pos); position->SetCoordinates(Euler::ToDegree(pos.lat), Euler::ToDegree(pos.lon), info.elv); if ((info.sig == 2 && alt_ref == 0) || button_ref->Clicked() == true || take_ref == true) { Printf("prise pos ref\n"); lat_ref = pos.lat; long_ref = pos.lon; alt_ref = info.elv; take_ref = false; } // if(alt_ref!=0) { double x, y, z; double e, n, u; Geographique_2_ECEF(pos.lon, pos.lat, info.elv, x, y, z); ECEF_2_ENU(x, y, z, e, n, u, long_ref, lat_ref, alt_ref); // Printf("lon:%f lat:%f elv:%f\n",pos.lon,pos.lat,info.elv); // on prend une fois pour toute le mutex et on fait des accès directs output->GetMutex(); output->SetValueNoMutex(0, 0, e); output->SetValueNoMutex(1, 0, n); output->SetValueNoMutex(2, 0, u); int index = 3; if ((NMEAFlags & VTG) != 0) { output->SetValueNoMutex(index, 0, info.speed * 1000. / 3600. * sin(Euler::ToRadian(info.direction))); output->SetValueNoMutex(index + 1, 0, info.speed * 1000. / 3600. * cos(Euler::ToRadian(info.direction))); index += 2; } if ((NMEAFlags & GST) != 0) { // Thread::Printf("dev_lon:%f dev_lat:%f // dev_elv:%f\n",info.dev_lat,info.dev_lon,info.dev_elv); output->SetValueNoMutex(index, 0, info.dev_lat); output->SetValueNoMutex(index + 1, 0, info.dev_lon); output->SetValueNoMutex(index + 2, 0, info.dev_elv); index += 3; } output->ReleaseMutex(); output->SetDataTime(GetTime()); ProcessUpdate(output); } } } } // end namespace sensor } // end namespace framewor