void xRawLogViewerFrame::OnMenuCompactRawlog(wxCommandEvent& event) { WX_START_TRY bool onlyOnePerLabel = (wxYES==wxMessageBox( _("Keep only one observation of each label within each sensoryframe?"), _("Compact rawlog"),wxYES_NO, this )); int progress_N = static_cast<int>(rawlog.size()); int progress_i=progress_N; wxProgressDialog progDia( wxT("Compacting rawlog"), wxT("Processing..."), progress_N, // range this, // parent wxPD_CAN_ABORT | wxPD_APP_MODAL | wxPD_SMOOTH | wxPD_AUTO_HIDE | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME | wxPD_REMAINING_TIME); wxTheApp->Yield(); // Let the app. process messages CActionRobotMovement2DPtr lastAct; CSensoryFramePtr lastSF; // = NULL; unsigned counter_loops = 0; unsigned nActionsDel = 0; unsigned nEmptySFDel = 0; CRawlog::iterator it=rawlog.begin(); for (progress_i=0 ;it!=rawlog.end();progress_i--) { if (counter_loops++ % 50 == 0) { if (!progDia.Update( progress_N-progress_i )) break; wxTheApp->Yield(); // Let the app. process messages } bool deleteThis = false; if (it.getType()==CRawlog::etActionCollection) { // Is this a part of multiple actions? if (lastAct) { // Remove this one and add it to the first in the series: CActionRobotMovement2DPtr act = CActionCollectionPtr(*it)->getMovementEstimationByType( CActionRobotMovement2D::emOdometry ); ASSERT_(act); lastAct->computeFromOdometry( lastAct->rawOdometryIncrementReading + act->rawOdometryIncrementReading, lastAct->motionModelConfiguration); deleteThis=true; nActionsDel++; } else { // This is the first one: lastAct = CActionCollectionPtr(*it)->getMovementEstimationByType( CActionRobotMovement2D::emOdometry ); ASSERT_(lastAct); // Before leaving the last SF, leave only one observation for each sensorLabel: if (onlyOnePerLabel && lastSF) { CSensoryFramePtr newSF = CSensoryFrame::Create(); set<string> knownLabels; for (CSensoryFrame::const_iterator o=lastSF->begin();o!=lastSF->end();++o) { if (knownLabels.find((*o)->sensorLabel)==knownLabels.end()) newSF->insert(*o); knownLabels.insert((*o)->sensorLabel); } *lastSF = *newSF; } // Ok, done: lastSF.clear_unique(); } } else if (it.getType()==CRawlog::etSensoryFrame) { // Is this a part of a series? if (lastSF) { // remove this one and accumulate in the first in the serie: lastSF->moveFrom( * CSensoryFramePtr(*it) ); deleteThis = true; nEmptySFDel++; } else { // This is the first SF: CSensoryFramePtr sf = CSensoryFramePtr(*it); // Only take into account if not empty! if (sf->size()) { lastSF = sf; ASSERT_(lastSF); lastAct.clear_unique(); } else { deleteThis = true; nEmptySFDel++; } } } else THROW_EXCEPTION("Unexpected class found!") if (deleteThis) { it = rawlog.erase(it); progress_i--; // Extra count } else it++; } progDia.Update( progress_N ); string str= format( "%u actions deleted\n%u sensory frames deleted", nActionsDel, nEmptySFDel ); ::wxMessageBox( _U( str.c_str() ) ); rebuildTreeView(); WX_END_TRY }
/* ------------------------------------------------------------ reloadFromRawlog ------------------------------------------------------------ */ void CRawlogTreeView::reloadFromRawlog( int hint_rawlog_items ) { // Recompute the total height of the scroll area: // We also compute a list for each index with: // - Pointer to data // - level in the hierarchy (0,1,2) // -------------------------------------------------------- if (m_rawlog) { if (hint_rawlog_items<0) m_tree_nodes.reserve( m_rawlog->size()+100 ); else m_tree_nodes.reserve( hint_rawlog_items+100 ); } // Create a "tree node" for each element in the rawlog: // --------------------------------------------------------- m_tree_nodes.clear(); m_rawlog_start = INVALID_TIMESTAMP; m_rawlog_last = INVALID_TIMESTAMP; // Root: m_tree_nodes.push_back( TNodeData() ); TNodeData &d = m_tree_nodes.back(); d.level = 0; // CVectorDouble tims; if (m_rawlog) { CRawlog::iterator end_it = m_rawlog->end(); size_t rawlog_index = 0; for (CRawlog::iterator it=m_rawlog->begin();it!=end_it;it++,rawlog_index++) { m_tree_nodes.push_back( TNodeData() ); TNodeData &d = m_tree_nodes.back(); d.level = 1; d.data = (*it); d.index = rawlog_index; // For containers, go recursively: if ( (*it)->GetRuntimeClass()==CLASS_ID(CSensoryFrame)) { CSensoryFramePtr sf = CSensoryFramePtr( *it ); for (CSensoryFrame::iterator o=sf->begin();o!=sf->end();++o) { m_tree_nodes.push_back( TNodeData() ); TNodeData &d = m_tree_nodes.back(); d.level = 2; d.data = (*o); if ((*o)->timestamp!=INVALID_TIMESTAMP) { m_rawlog_last = (*o)->timestamp; if (m_rawlog_start == INVALID_TIMESTAMP) m_rawlog_start = (*o)->timestamp; } } } else if ( (*it)->GetRuntimeClass()==CLASS_ID(CActionCollection)) { CActionCollectionPtr acts = CActionCollectionPtr( *it ); for (CActionCollection::iterator a=acts->begin();a!=acts->end();++a) { m_tree_nodes.push_back( TNodeData() ); TNodeData &d = m_tree_nodes.back(); d.level = 2; d.data = (*a); if ((*a)->timestamp!=INVALID_TIMESTAMP) { m_rawlog_last = (*a)->timestamp; if (m_rawlog_start == INVALID_TIMESTAMP) m_rawlog_start = (*a)->timestamp; } } } else if ( (*it)->GetRuntimeClass()->derivedFrom( CLASS_ID(CObservation) )) { CObservationPtr o = CObservationPtr(*it); if (o->timestamp!=INVALID_TIMESTAMP) { m_rawlog_last = o->timestamp; if (m_rawlog_start == INVALID_TIMESTAMP) m_rawlog_start = o->timestamp; //tims.push_back( mrpt::system::timeDifference(m_rawlog_start, o->timestamp)); } } } } // mrpt::system::vectorToTextFile(tims,"tims.txt"); // Set new size: int ly = m_tree_nodes.size(); SetScrollbars(ROW_HEIGHT, ROW_HEIGHT, 50, ly); }
void xRawLogViewerFrame::OnMenuRegenerateGPSTimestamps(wxCommandEvent& event) { WX_START_TRY wxBusyCursor waitCursor; vector_string the_labels = AskForObservationByLabelMultiple("Choose the GPS(s) to consider:"); vector_double time_changes; // all the shifts std::map<std::string,double> DeltaTimes; // First, build an ordered list of "times"->"indexes": // ------------------------------------------------------ std::map<TTimeStamp,size_t> ordered_times; size_t i, n = rawlog.size(); for (i=0;i<n;i++) { switch ( rawlog.getType(i) ) { default: wxMessageBox(_("Error: this command is for rawlogs without sensory frames.")); return; break; case CRawlog::etSensoryFrame: { CSensoryFramePtr sf = rawlog.getAsObservations(i); for (CSensoryFrame::iterator it=sf->begin();it!=sf->end();++it) { if ( (*it)->GetRuntimeClass()==CLASS_ID(CObservationGPS) && find_in_vector( (*it)->sensorLabel, the_labels)!=string::npos ) { CObservationGPSPtr obs = CObservationGPSPtr(*it); fixGPStimestamp(obs, time_changes, DeltaTimes); } } } break; case CRawlog::etObservation: { CObservationPtr o = rawlog.getAsObservation(i); if (IS_CLASS(o,CObservationGPS) && find_in_vector( o->sensorLabel, the_labels)!=string::npos) { CObservationGPSPtr obs = CObservationGPSPtr(o); fixGPStimestamp(obs, time_changes, DeltaTimes); } } break; } // end switch type } // end for i unsigned int nChanges = time_changes.size(); double average_time_change = 0, std_time_change = 0; mrpt::math::meanAndStd(time_changes,average_time_change, std_time_change ); if (wxYES==wxMessageBox( wxString::Format(_("%u changes, average/std time shift is: %f/%f sec. Do you want to re-order by timestamp?"),nChanges, average_time_change, std_time_change ), _("Done"),wxYES_NO, this )) { OnMenuResortByTimestamp(event); } WX_END_TRY }