// %flair:license{ // This file is part of the Flair framework distributed under the // CECILL-C License, Version 1.0. // %flair:license} // created: 2014/05/26 // filename: SimuGps.cpp // // author: Guillaume Sanahuja // Copyright Heudiasyc UMR UTC/CNRS 7253 // // version: $Id: $ // // purpose: Class for a simulation GPS // // /*********************************************************************/ #include "SimuGps.h" #include #include #include #include #include #include #include #include #include #include "geodesie.h" using std::string; using std::ostringstream; using namespace flair::core; using namespace flair::gui; using namespace Geodesie; namespace flair { namespace sensor { SimuGps::SimuGps(string name, NmeaGps::NMEAFlags_t NMEAFlags, uint32_t modelId,uint32_t deviceId,uint8_t priority) : NmeaGps(name, NMEAFlags),Thread(getFrameworkManager(), name, priority) { dataRate = new SpinBox(GetGroupBox()->NewRow(), "data rate", " Hz", 1, 500, 1, 200); latitudeRef = new DoubleSpinBox(GetGroupBox()->NewRow(), "latitude ref", " deg", -90, 90, 1, 6,49.402313); longitudeRef = new DoubleSpinBox(GetGroupBox()->LastRowLastCol(), "longitude ref", " deg", -180, 180, 1, 6,2.795463); altitudeRef= new DoubleSpinBox(GetGroupBox()->LastRowLastCol(), "altitude ref", " m", 0, 6000, 100, 1,0); fixQuality = new SpinBox(GetGroupBox()->NewRow(), "fix quality", 1, 8, 1, 1); numberOfSatellites = new SpinBox(GetGroupBox()->NewRow(), "number of satellites", 1, 15, 1, 5); magneticDeclination= new DoubleSpinBox(GetGroupBox()->NewRow(), "magnetic declination", " deg", -180, 180, .1, 2,0); shmem = new SharedMem((Thread *)this, ShMemName(modelId, deviceId), sizeof(gps_states_t)); SetIsReady(true); } SimuGps::~SimuGps() { SafeStop(); Join(); } string SimuGps::ShMemName(uint32_t modelId,uint32_t deviceId) { ostringstream dev_name; dev_name << "simu" << modelId << "_gps_" << deviceId; return dev_name.str().c_str(); } void SimuGps::Run(void) { gps_states_t state; char buf[512]; nmeaGPGGA gga; nmeaGPVTG vtg; nmeaPOS pos; nmeaINFO info; vtg.dir_t='T'; vtg.dec_m='M'; vtg.spk_k='K'; vtg.spn_n='N'; gga.elv_units='M'; gga.diff_units='M'; SetPeriodUS((uint32_t)(1000000. / dataRate->Value())); WarnUponSwitches(true); while (!ToBeStopped()) { WaitPeriod(); if (dataRate->ValueChanged() == true) { SetPeriodUS((uint32_t)(1000000. / dataRate->Value())); } shmem->Read((char *)&state, sizeof(gps_states_t)); double x, y, z; ENU_2_ECEF(state.e, state.n, state.u, x,y,z, Euler::ToRadian(longitudeRef->Value()), Euler::ToRadian(latitudeRef->Value()), altitudeRef->Value()); ECEF_2_Geographique( x, y, z,pos.lon, pos.lat, gga.elv); nmea_pos2info(&pos,&info); if(pos.lat>0) { gga.ns='N'; gga.lat=info.lat; } else { gga.ns='S'; gga.lat=-info.lat; } if(pos.lon>0) { gga.ew='E'; gga.lon=info.lon; } else { gga.ew='W'; gga.lon=-info.lon; } gga.sig=fixQuality->Value(); gga.satinuse=numberOfSatellites->Value(); int size=nmea_gen_GPGGA(buf,sizeof(buf),&gga); parseFrame(buf,size); vtg.dir=90-Euler::ToDegree(atan2f(state.vn,state.ve)); vtg.spk=sqrtf(state.ve*state.ve+state.vn*state.vn)*3600./1000.; size=nmea_gen_GPVTG(buf,sizeof(buf),&vtg); parseFrame(buf,size); } WarnUponSwitches(false); } } // end namespace sensor } // end namespace flair