// ********************************************************************* // created: 20011/06/28 - 18:13 // filename: cptComponent.cpp // // author: Sergio Rodriguez // // version: $Id: $ // // purpose: Acquires SPAN CPT data // // ********************************************************************* #include "CPTComponent.h" #include #include "kernel/ComponentFactory.h" #include "kernel/DbiteFileTypes.h" #include "kernel/Log.h" #include "PacpusTools/geodesie.h" #include "PacpusTools/ShMem.h" using namespace pacpus; using namespace std; /// Construct the factory static ComponentFactory sFactory("CPTComponent"); static const size_t AllFramesSize = sizeof(TimestampedBestgpsposaFrame) + sizeof(TimestampedRawimusaFrame) + sizeof(TimestampedInspvaaFrame) + sizeof(TimestampedInscovFrame) ; DECLARE_STATIC_LOGGER("pacpus.base.CPTComponent"); void CPTComponent::addInputOutput() { ADD_OUTPUT("bestposegpsposa",CPTComponent,TimestampedBestgpsposaFrame); ADD_OUTPUT("rawimusa",CPTComponent,TimestampedRawimusaFrame); ADD_OUTPUT("inspvaaa",CPTComponent,TimestampedInspvaaFrame); ADD_OUTPUT("inscov",CPTComponent,TimestampedInscovFrame); ADD_OUTPUT("genericpose",CPTComponent,Pose3D); } ////////////////////////////////////////////////////////////////////////// /// Constructor of CPTComponent class CPTComponent::CPTComponent(QString name) : ComponentBase(name) { LOG_INFO("sizeof(TimestampedBestgpsposaFrame)=" << sizeof(TimestampedBestgpsposaFrame)); LOG_INFO("sizeof(TimestampedRawimusaFrame)=" << sizeof(TimestampedRawimusaFrame)); LOG_INFO("sizeof(TimestampedInspvaaFrame)=" << sizeof(TimestampedInspvaaFrame)); LOG_INFO("sizeof(TimestampedInscovFrame)=" << sizeof(TimestampedInscovFrame)); mVerbose = false; recording = false; enuRef_ = false; LAT_REF =0.0; LON_REF =0.0; HE_REF =0.0; currentRoadtime_ = 0; currentTimerange_ = 0; //decoding currentDataFrame =""; currentRoadtime = 0; currentTimerange = 0; frameToDecode = ""; timeOfFrameToDecode = 0; timerangeOfFrameToDecode = 0; restOfFrame = ""; newFrameToDecode = false; startOfFrame = false; sofIdx_ =0; endOfFrame = false; eofIdx_ =0; //ShMems allocation mShMem = new ShMem("SPAN_FRAMES", AllFramesSize); mAllFramesBuffer = new char[AllFramesSize]; addInputOutput(); } /// Destructor of the CPTComponent class CPTComponent::~CPTComponent() { delete mShMem; delete[] mAllFramesBuffer; } ComponentBase::COMPONENT_CONFIGURATION CPTComponent::configureComponent(XmlComponentConfig /*config*/) { setPortCOM( param.getProperty("port").toLatin1() ); if (!param.getProperty("recording").isNull()) { recording = (param.getProperty("recording") == "true" ? true : false); } // if (!param.getProperty("verbose").isNull()) { // mVerbose = (param.getProperty("verbose") == "true" ? true : false); // } if (!param.getProperty("ENUref").isNull()) { enuRef_ = (param.getProperty("ENUref") == "true" ? true : false); if (enuRef_) { LAT_REF = param.getProperty("LatRef").toDouble(); LON_REF = param.getProperty("LonRef").toDouble(); HE_REF = param.getProperty("HeRef").toDouble(); LOG_DEBUG("Reference Saint Mande:: Lat: " << LAT_REF << ", Lon: " << LON_REF << " Height: " << HE_REF); } } return ComponentBase::CONFIGURED_OK; } void CPTComponent::setPortCOM(const char * port) { portName = port; } /// Log function void CPTComponent::processing(int /*i*/) { if (!serialPort) { LOG_WARN("no serial port"); return; } //ShMem data variables TimestampedBestgpsposaFrame a; TimestampedRawimusaFrame b; TimestampedInspvaaFrame c; TimestampedInscovFrame d; //ShMem buffer allocation char * allFramesBuffer = new char[AllFramesSize]; //ShMem buffer initialization initBuffer(&a, &b, &c, &d); memcpy(allFramesBuffer, &a, sizeof(TimestampedBestgpsposaFrame)); memcpy(allFramesBuffer + sizeof(TimestampedBestgpsposaFrame), &b,sizeof(TimestampedRawimusaFrame)); memcpy(allFramesBuffer + sizeof(TimestampedBestgpsposaFrame) + sizeof(TimestampedRawimusaFrame), &c, sizeof(TimestampedInspvaaFrame)); memcpy(allFramesBuffer + sizeof(TimestampedBestgpsposaFrame)+sizeof(TimestampedRawimusaFrame)+sizeof(TimestampedInspvaaFrame), &d, sizeof(TimestampedInscovFrame)); memcpy(allFramesBuffer, mAllFramesBuffer, AllFramesSize); // get the frame and remove it in the list FRAME * currentFrame = serialPort->firstFrame(); char * currentDataFrame = new char[currentFrame->length]; memcpy(currentDataFrame, currentFrame->data, currentFrame->length); currentDataFrameLength_ = currentFrame->length; currentRoadtime_ = currentFrame->t; serialPort->removeFirstFrame(); setState(ComponentBase::MONITOR_OK); if (recording) { s8Data_.dataPos = dataFile_.tellp(); s8Data_.length = currentDataFrameLength_; LOG_DEBUG("data:" << currentDataFrame << "addr:" << s8Data_.dataPos << "l:" << s8Data_.length); size_t dataSize = sizeof(Stream8Position); raws8hdFile.writeRecord(currentRoadtime_, 0, reinterpret_cast(&s8Data_), dataSize); dataFile_.write(reinterpret_cast(currentDataFrame), currentDataFrameLength_); } // Decoding char * buffer = new char[currentDataFrameLength_ + 1]; memcpy(buffer, currentDataFrame, currentDataFrameLength_); buffer[currentDataFrameLength_] = '\0'; // add a \0 to convert for the conversion in QString currentDataFrame = buffer; currentRoadtime = currentRoadtime_; currentTimerange = currentRoadtime_; analyzeFrame(); if (newFrameToDecode) { LOG_DEBUG("got new frame to decode"); type = frameType(frameToDecode); LOG_DEBUG("frame type=" << type); if (-1 != type) { if (-1 == decodeFrame(type)) { LOG_WARN("cannot decode the dataframe"); } else { switch(type) { case TRAME_GGA_DBL: if (mVerbose) { cout << "[SPAN-GGA] Lat: " << ggaFrame_.lat<< " Lon: " << ggaFrame_.lon<< " Hgt: " << ggaFrame_.alt_msl << " Quality: " << ggaFrame_.ind_qualite << "\n";} break; case TRAME_BESTGPSPOSA: //ShMem buffer data copy memcpy(&a.frame, &bestgpsposaFrame_, sizeof(trame_bestgpsposa)); a.time=timeOfFrameToDecode; a.timerange=timerangeOfFrameToDecode; memcpy(allFramesBuffer, &a, sizeof(TimestampedBestgpsposaFrame)); if (recording) { size_t dataSize = sizeof(bestgpsposaFrame_); bestgpsposaFile_.writeRecord(timeOfFrameToDecode, timerangeOfFrameToDecode, reinterpret_cast(&bestgpsposaFrame_), dataSize); } LOG_DEBUG("[SPAN-BESTGPSPOSA]" << "\t" << "Lat=" << bestgpsposaFrame_.Lat << "\t" << "Lon=" << bestgpsposaFrame_.Lon << "\t" << "Hgt=" << bestgpsposaFrame_.Hgt << "\t" << "E=" << bestgpsposaFrame_.e << "\t" << "N=" << bestgpsposaFrame_.n << "\t" << "U=" << bestgpsposaFrame_.u) ; mShMem->write(allFramesBuffer, AllFramesSize); GET_OUTPUT("bestposegpsposa",CPTComponent,TimestampedBestgpsposaFrame)->send(a); break; case TRAME_RAWIMUSA: //ShMem buffer data copy memcpy(&b.frame, &rawimuFrame_, sizeof(trame_rawimusa)); b.time=timeOfFrameToDecode; b.timerange=timerangeOfFrameToDecode; memcpy(allFramesBuffer+ sizeof(TimestampedBestgpsposaFrame),&b,sizeof(TimestampedRawimusaFrame)); if (recording) { size_t dataSize = sizeof(rawimuFrame_); rawimuFile_.writeRecord(timeOfFrameToDecode, timerangeOfFrameToDecode, reinterpret_cast(&rawimuFrame_), dataSize); } LOG_DEBUG("[SPAN-RAWIMUSA]"); //ShMem refresh mShMem->write(allFramesBuffer, sizeof(TimestampedBestgpsposaFrame) +sizeof(TimestampedRawimusaFrame) +sizeof(TimestampedInspvaaFrame) +sizeof(TimestampedInscovFrame)); GET_OUTPUT("rawimusa",CPTComponent,TimestampedRawimusaFrame)->send(b); break; case TRAME_INSPVAA: //ShMem buffer data copy memcpy(&c.frame, &inspvaFrame_, sizeof(trame_inspvaa)); c.time=timeOfFrameToDecode; c.timerange=timerangeOfFrameToDecode; memcpy(allFramesBuffer+ sizeof(TimestampedBestgpsposaFrame)+sizeof(TimestampedRawimusaFrame), &c,sizeof(TimestampedInspvaaFrame)); if (recording) { size_t dataSize = sizeof(inspvaFrame_); inspvaFile_.writeRecord(timeOfFrameToDecode, timerangeOfFrameToDecode, reinterpret_cast(&inspvaFrame_), dataSize); } LOG_DEBUG("[SPAN-INSPVAA]:" << "\t" << "Lat: " << inspvaFrame_.Lat << "\t" << "Lon: " << inspvaFrame_.Lon << "\t" << "Roll: "<< inspvaFrame_.Roll << "\t" << "Pitch: " << inspvaFrame_.Azimuth << "\t" << "E: " << inspvaFrame_.e << "\t" << "N: " << inspvaFrame_.n << "\t" << "U: " << inspvaFrame_.u); //ShMem refresh mShMem->write(allFramesBuffer, sizeof(TimestampedBestgpsposaFrame) +sizeof(TimestampedRawimusaFrame) +sizeof(TimestampedInspvaaFrame) +sizeof(TimestampedInscovFrame)); GET_OUTPUT("inspvaaa",CPTComponent,TimestampedInspvaaFrame)->send(c); genericEnuPose_.time = c.time; genericEnuPose_.timerange = c.timerange; genericEnuPose_.position = QVector3D(inspvaFrame_.e, inspvaFrame_.n, inspvaFrame_.u); genericEnuPose_.angle = QVector3D((inspvaFrame_.Azimuth+90.0)*(M_PI/180.0),inspvaFrame_.Pitch*(M_PI/180.0),inspvaFrame_.Roll*(M_PI/180.0)); // for (int i=0;i<3;i++) { // for(int j=0;j<3;j++) { // pose.posconv[i][j] = d.frame.PosCov[i][j]; // pose.angcov[i][j] = d.frame.AttCov[i][j]; // } // } GET_OUTPUT("genericpose",CPTComponent,Pose3D)->send(genericEnuPose_); break; case TRAME_INSCOV: //ShMem data copy memcpy(&d.frame, &inscovFrame_, sizeof(trame_inscov)); d.time=timeOfFrameToDecode; d.timerange=timerangeOfFrameToDecode; memcpy(allFramesBuffer+ sizeof(TimestampedBestgpsposaFrame)+sizeof(TimestampedRawimusaFrame)+sizeof(TimestampedInspvaaFrame), &d,sizeof(TimestampedInscovFrame)); if (recording) { size_t dataSize = sizeof(inscovFrame_); inscovFile_.writeRecord(timeOfFrameToDecode, timerangeOfFrameToDecode, reinterpret_cast(&inscovFrame_), dataSize); // FIXED: was inscovFile_ instead of inscovFrame_ given as buffer } LOG_DEBUG("[SPAN-INSCOV] CovXX: " << inscovFrame_.PosCov[0][0] << " CovYY: " << inscovFrame_.PosCov[1][1] << " CovZZ: "<< inscovFrame_.PosCov[2][2]); //ShMem refresh mShMem->write(allFramesBuffer, sizeof(TimestampedBestgpsposaFrame) +sizeof(TimestampedRawimusaFrame) +sizeof(TimestampedInspvaaFrame) +sizeof(TimestampedInscovFrame)); GET_OUTPUT("inscov",CPTComponent,TimestampedInscovFrame)->send(d); break; default: break; } } } type = -1; newFrameToDecode = false; frameToDecode = ""; } delete[] buffer; delete[] currentDataFrame; memcpy(mAllFramesBuffer, allFramesBuffer, AllFramesSize); delete[] allFramesBuffer; } /************************************************************************/ /* Method to stop the thread */ /************************************************************************/ void CPTComponent::stopActivity() { serialPort->THREAD_ALIVE = false; if (!serialPort->wait(2000)) { serialPort->terminate(); LOG_WARN("The SerialPort thread blocks anormally, it has been killed !!"); } if ( !serialPort->closePort() ) { LOG_ERROR("Failed to close the port"); } else LOG_INFO("The port is closed"); delete serialPort; serialPort = NULL; if (recording) { bestgpsposaFile_.close(); rawimuFile_.close(); inspvaFile_.close(); inscovFile_.close(); raws8hdFile.close(); dataFile_.close(); } } /************************************************************************/ /* Method to start the thread */ /************************************************************************/ void CPTComponent::startActivity() { type = -1; #if WIN32 serialPort = new Win32SerialPort(portName.toLatin1()); // Asynchrone serialPort->setMode(FILE_FLAG_OVERLAPPED); // Synchrone //serialPort->setMode(0); #else serialPort = new PosixSerialPort(portName.toLatin1()); #endif if (!serialPort->openPort(portName.toLatin1())) { LOG_ERROR("cannot open the port " << portName); LOG_INFO("cannot start SPAN CPT Component '" << componentName << "'"); return; } serialPort->configurePort(param.getProperty("baudrate").toLong(), param.getProperty("bytesize").toUInt(), param.getProperty("parity").toShort(), param.getProperty("stopbits").toUInt() - 1); if (recording) { bestgpsposaFile_.open("SPAN_bestgpsposa.dbt", WriteMode, TRAME_BESTGPSPOSA, sizeof(trame_bestgpsposa)); rawimuFile_.open("SPAN_rawimusa.dbt", WriteMode, TRAME_RAWIMUSA, sizeof(trame_rawimusa)); inspvaFile_.open("SPAN_inspvaa.dbt", WriteMode, TRAME_INSPVAA, sizeof(trame_inspvaa)); inscovFile_.open("SPAN_inscov.dbt", WriteMode, TRAME_INSCOV, sizeof(trame_inscov)); // raw data file: Dbt header + binary data stream raws8hdFile.open((ComponentBase::componentName + ".dbt").toStdString(), WriteMode, STREAM8POSITION, sizeof(Stream8Position)); // FIXME: use ofstream // open the file with C function to be sure that it will exist FILE * stream = NULL; if ( ( stream = fopen((ComponentBase::componentName + ".utc").toLatin1().data(),"a+") ) == NULL ) { LOG_FATAL("Error while opening the stream utc file\n press a ENTER to exit"); getchar(); ::exit(-1); } else { fclose(stream); } dataFile_.open((ComponentBase::componentName + ".utc").toLatin1().data(), ios_base::out|ios_base::binary|ios_base::app); if (!dataFile_) { LOG_ERROR("Error while opening the file alasca_data.utc\n press a ENTER to exit\n"); getchar(); ::exit(0); } } if (!connect(serialPort,SIGNAL(newDataAvailable(int)),this, SLOT(processing(int)))) { LOG_WARN("cannot connect SIGNAL(newDataAvailable(int)) with SLOT(unlockProcessing(int)"); } LOG_INFO("started component '" << componentName << "'"); serialPort->THREAD_ALIVE = true; serialPort->start(); } int CPTComponent::analyzeFrame() { // SOF = start of frame // EOF = end of frame // PPS case //if (currentDataFrame == "PPS") //{ // frameToDecode = currentDataFrame; // newFrameToDecode = true; // timeOfFrameToDecode = currentRoadtime; // timerangeOfFrameToDecode = currentTimerange; // return 1; //} currentDataFrame = restOfFrame + currentDataFrame; restOfFrame = ""; if (currentDataFrame.indexOf(QRegExp("[$#%]"),0)!=-1) { sofIdx_ = currentDataFrame.indexOf(QRegExp("[$#%]"),0); startOfFrame = true; timeOfFrameToDecode = currentRoadtime; if (currentDataFrame.indexOf("\n",sofIdx_)!=-1) { eofIdx_ = currentDataFrame.indexOf("\n",sofIdx_); endOfFrame = true; timerangeOfFrameToDecode = currentTimerange; } else restOfFrame = currentDataFrame; } else restOfFrame = currentDataFrame; if ( (startOfFrame) && (endOfFrame) ) { newFrameToDecode = true; for (int i=sofIdx_;itime=0; a->timerange=0; a->frame.Status=INSUFFICIENT_OBS; a->frame.posType=NONE; a->frame.Lat=0.0; a->frame.Lon=0.0; a->frame.Hgt=0.0; a->frame.Undulation=0.0; a->frame.LatStd=0.0; a->frame.LonStd=0.0; a->frame.HgtStd=0.0; a->frame.e=0.0; a->frame.n=0.0; a->frame.u=0.0; b->time=0; b->timerange=0; b->frame.Week=0; b->frame.Seconds=0.0; b->frame.ZAccel=0.0; b->frame.YAccel=0.0; b->frame.XAccel=0.0; b->frame.ZGyro=0.0; b->frame.YGyro=0.0; b->frame.XGyro=0.0; c->time=0; c->timerange=0; c->frame.Week =0; c->frame.Seconds=0.0; c->frame.Lat=0.0; c->frame.Lon=0.0; c->frame.Hgt=0.0; c->frame.NorthVel=0.0; c->frame.EastVel=0.0; c->frame.UpVel=0.0; c->frame.Roll=0.0; c->frame.Pitch=0.0; c->frame.Azimuth=0.0; c->frame.Status=INS_INACTIVE; c->frame.e=0.0; c->frame.n=0.0; c->frame.u=0.0; d->time=0; d->timerange=0; d->frame.Week=0; d->frame.Seconds=0.0; for (register int i=0;i<3;i++) { for (register int j=0;j<3;j++) { d->frame.PosCov[i][j]=0.0; d->frame.AttCov[i][j]=0.0; d->frame.VelCov[i][j]=0.0; } } }