// ********************************************************************* // created: 20011/06/28 - 18:13 // filename: cptComponent.cpp // // author: Sergio Rodriguez // // version: $Id: $ // // purpose: Acquires SPAN CPT data // // ********************************************************************* #include "CPTComponent.h" #include #include #include #include #include #include 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"); ////////////////////////////////////////////////////////////////////////// /// 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; setRecording( false ); enuRef_ = false; LAT_REF =0.0; LON_REF =0.0; HE_REF =0.0; currentRoadtime_ = 0; currentTimerange_ = 0; //decoding currentDataFrame_ =""; 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]; } /// Destructor of the CPTComponent class CPTComponent::~CPTComponent() { delete mShMem; delete[] mAllFramesBuffer; } ComponentBase::COMPONENT_CONFIGURATION CPTComponent::configureComponent(XmlComponentConfig /*config*/) { setPortCOM( xmlParameters().getProperty("port").toLatin1() ); if (!xmlParameters().getProperty("recording").isNull()) { setRecording ( (xmlParameters().getProperty("recording") == "true" ? true : false) ); } if (!xmlParameters().getProperty("verbose").isNull()) { mVerbose = (xmlParameters().getProperty("verbose") == "true" ? true : false); } if (!xmlParameters().getProperty("ENUref").isNull()) { enuRef_ = (xmlParameters().getProperty("ENUref") == "true" ? true : false); if (enuRef_) { LAT_REF = xmlParameters().getProperty("LatRef").toDouble(); LON_REF = xmlParameters().getProperty("LonRef").toDouble(); HE_REF = xmlParameters().getProperty("HeRef").toDouble(); if (mVerbose) { LOG_DEBUG("Reference Saint Mande:: Lat: " << LAT_REF << ", Lon: " << LON_REF << " Height: " << HE_REF); } } } return ComponentBase::CONFIGURED_OK; } void CPTComponent::addOutputs() { // must inherit from QObject to use addOutput addOutput("position2DENU"); } 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->getNextFrame(); char * currentDataFrame = new char[currentFrame->length]; memcpy(currentDataFrame, currentFrame->data, currentFrame->length); currentDataFrameLength_ = currentFrame->length; currentRoadtime_ = currentFrame->t; // free memory delete currentFrame; setState(ComponentBase::MONITOR_OK); if (isRecording()) { s8Data_.dataPos = dataFile_.tellp(); s8Data_.length = currentDataFrameLength_; if (mVerbose) { 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_ = QString::fromAscii(buffer); delete[] buffer; delete[] currentDataFrame; 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 (isRecording()) { size_t dataSize = sizeof(bestgpsposaFrame_); bestgpsposaFile_.writeRecord(timeOfFrameToDecode, timerangeOfFrameToDecode, reinterpret_cast(&bestgpsposaFrame_), dataSize); } if (mVerbose) { cout << "[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); if (position2DENUOutput_ && position2DENUOutput_->hasConnection()) { // send ENU 2D position QPointF pt( bestgpsposaFrame_.e, bestgpsposaFrame_.n); position2DENUOutput_->send(pt); } 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 (isRecording()) { size_t dataSize = sizeof(rawimuFrame_); rawimuFile_.writeRecord(timeOfFrameToDecode, timerangeOfFrameToDecode, reinterpret_cast(&rawimuFrame_), dataSize); } if (mVerbose) { cout << "[SPAN-RAWIMUSA]"<< endl; } //ShMem refresh mShMem->write(allFramesBuffer, sizeof(TimestampedBestgpsposaFrame) +sizeof(TimestampedRawimusaFrame) +sizeof(TimestampedInspvaaFrame) +sizeof(TimestampedInscovFrame)); 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 (isRecording()) { size_t dataSize = sizeof(inspvaFrame_); inspvaFile_.writeRecord(timeOfFrameToDecode, timerangeOfFrameToDecode, reinterpret_cast(&inspvaFrame_), dataSize); } if (mVerbose) { cout << "[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 << endl; } //ShMem refresh mShMem->write(allFramesBuffer, sizeof(TimestampedBestgpsposaFrame) +sizeof(TimestampedRawimusaFrame) +sizeof(TimestampedInspvaaFrame) +sizeof(TimestampedInscovFrame)); 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 (isRecording()) { size_t dataSize = sizeof(inscovFrame_); inscovFile_.writeRecord(timeOfFrameToDecode, timerangeOfFrameToDecode, reinterpret_cast(&inscovFrame_), dataSize); // FIXED: was inscovFile_ instead of inscovFrame_ given as buffer } if (mVerbose) { cout << "[SPAN-INSCOV] CovXX: " << inscovFrame_.PosCov[0][0] << " CovYY: " << inscovFrame_.PosCov[1][1] << " CovZZ: "<< inscovFrame_.PosCov[2][2] << endl; } //ShMem refresh mShMem->write(allFramesBuffer, sizeof(TimestampedBestgpsposaFrame) +sizeof(TimestampedRawimusaFrame) +sizeof(TimestampedInspvaaFrame) +sizeof(TimestampedInscovFrame)); break; default: break; } } } type = -1; newFrameToDecode = false; frameToDecode = ""; } memcpy(mAllFramesBuffer, allFramesBuffer, AllFramesSize); delete[] allFramesBuffer; } /************************************************************************/ /* Method to stop the thread */ /************************************************************************/ void CPTComponent::stopActivity() { serialPort->THREAD_ALIVE = false; if (!serialPort->wait(2000)) { serialPort->terminate(); qDebug("The Win32SerialPort thread blocks anormally, it has been killed !!"); } if ( !serialPort->closePort() ) qDebug("Failed to close the port"); else qDebug("The port is closed"); delete serialPort; serialPort = NULL; if (isRecording()) { 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 '" << name() << "'"); return; } serialPort->configurePort(xmlParameters().getProperty("baudrate").toLong(), xmlParameters().getProperty("bytesize").toUInt(), xmlParameters().getProperty("parity").toShort(), xmlParameters().getProperty("stopbits").toUInt() - 1); if (isRecording()) { 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((name() + ".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((name() + ".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((name() + ".utc").toLatin1().data(), ios_base::out|ios_base::binary|ios_base::app); if (!dataFile_) { printf("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 '" << name() << "'"); position2DENUOutput_ = getTypedOutput("position2DENU"); 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; } } } } // namespace pacpus