Log viewer improvements (#3442)

* Added:
 * max altitude
 * two cursors for time/altitude measurement

* Fix if multiple altitude related telemetry items are selected (only put cursors on the first one)
This commit is contained in:
Damjan Adamic
2016-04-29 18:59:39 +02:00
committed by Bertrand Songis
parent bd87028fd5
commit c6f13de505
3 changed files with 333 additions and 133 deletions
+159 -3
View File
@@ -10,7 +10,11 @@
LogsDialog::LogsDialog(QWidget *parent) :
QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint),
ui(new Ui::LogsDialog)
ui(new Ui::LogsDialog),
tracerMaxAlt(0),
cursorA(0),
cursorB(0),
cursorLine(0)
{
csvlog.clear();
@@ -78,7 +82,7 @@ LogsDialog::LogsDialog(QWidget *parent) :
// connect slot that ties some axis selections together (especially opposite axes):
connect(ui->customPlot, SIGNAL(selectionChangedByUser()), this, SLOT(selectionChanged()));
// connect slots that takes care that when an axis is selected, only that direction can be dragged and zoomed:
connect(ui->customPlot, SIGNAL(mousePress(QMouseEvent*)), this, SLOT(mousePress()));
connect(ui->customPlot, SIGNAL(mousePress(QMouseEvent*)), this, SLOT(mousePress(QMouseEvent*)));
connect(ui->customPlot, SIGNAL(mouseWheel(QWheelEvent*)), this, SLOT(mouseWheel()));
// make left axes transfer its range to right axes:
@@ -419,7 +423,7 @@ void LogsDialog::on_mapsButton_clicked()
ui->logTable->setDisabled(false);
}
void LogsDialog::mousePress()
void LogsDialog::mousePress(QMouseEvent * event)
{
// if an axis is selected, only allow the direction of that axis to be dragged
// if no axis is selected, both directions may be dragged
@@ -430,6 +434,74 @@ void LogsDialog::mousePress()
axisRect->setRangeDrag(axisRect->axis(QCPAxis::atLeft)->orientation());
else
axisRect->setRangeDrag(Qt::Horizontal | Qt::Vertical);
if (event->button() == Qt::RightButton) {
double x = axisRect->axis(QCPAxis::atBottom)->pixelToCoord(event->pos().x());
placeCursor(x, event->modifiers() & Qt::ShiftModifier);
}
}
void LogsDialog::placeCursor(double x, bool second)
{
QCPItemTracer * cursor = second ? cursorB : cursorA;
if (cursor) {
cursor->setGraphKey(x);
cursor->updatePosition();
cursor->setVisible(true);
}
if (cursorA && cursorB) {
updateCursorsLabel();
}
}
void LogsDialog::updateCursorsLabel()
{
QString text = QString("Max Altitude: %1 m\n").arg(tracerMaxAlt->position->value(), 0, 'f', 1);
if (cursorA->visible() ) {
text += tr("Cursor A: %1 m").arg(cursorA->position->value(), 0, 'f', 1) + "\n";
}
if (cursorB->visible() ) {
text += tr("Cursor B: %1 m").arg(cursorB->position->value(), 0, 'f', 1) + "\n";
}
if (cursorA->visible() && cursorB->visible()) {
cursorLine->setVisible(true);
// calc deltas
double deltaX = cursorB->position->key() - cursorA->position->key();
double deltaY = cursorB->position->value() - cursorA->position->value();
double slope = 0;
if (deltaX != 0) {
slope = deltaY / deltaX;
}
qDebug() << "Cursors: dt:" << formatTimeDelta(deltaX) << "dy:" << deltaY << "rate:" << slope;
text += tr("Time delta: %1").arg(formatTimeDelta(deltaX)) + "\n";
text += tr("Climb rate: %1 m/s").arg(slope, 0, 'f', 1) + "\n";
}
ui->labelCursors->setText(text);
}
QString LogsDialog::formatTimeDelta(double timeDelta)
{
if (abs(timeDelta) < 10) {
return QString("%1 s").arg(timeDelta, 1, 'f', 1);
}
int seconds = (int)round(abs(timeDelta));
int hours = seconds / 3600;
seconds %= 3600;
int minutes = seconds / 60;
seconds %= 60;
if (hours) {
return QString("%1h:%2:%3").arg(hours).arg(minutes, 2, 10, QChar('0')).arg(seconds, 2, 10, QChar('0'));
}
else if (minutes) {
return QString("%1m:%2").arg(minutes).arg(seconds, 2, 10, QChar('0'));
}
else {
return QString("%1 s").arg(seconds);
}
}
void LogsDialog::mouseWheel()
@@ -453,6 +525,7 @@ void LogsDialog::mouseWheel()
void LogsDialog::removeAllGraphs()
{
ui->customPlot->clearGraphs();
ui->customPlot->clearItems();
ui->customPlot->legend->setVisible(false);
rightLegend->clearItems();
rightLegend->setVisible(false);
@@ -466,6 +539,11 @@ void LogsDialog::removeAllGraphs()
axisRect->axis(QCPAxis::atRight, 1)->setSelectedParts(QCPAxis::spNone);
axisRect->axis(QCPAxis::atBottom)->setSelectedParts(QCPAxis::spNone);
ui->customPlot->replot();
tracerMaxAlt = 0;
cursorA = 0;
cursorB = 0;
cursorLine = 0;
ui->labelCursors->setText("");
}
void LogsDialog::on_fileOpen_BT_clicked()
@@ -904,6 +982,17 @@ void LogsDialog::plotLogs()
plots.coords.at(i).y);
pen.setColor(colors.at(i % colors.size()));
ui->customPlot->graph(i)->setPen(pen);
if (!tracerMaxAlt && (plots.coords.at(i).name.endsWith("(m)") ||
plots.coords.at(i).name.endsWith(" Alt") ||
plots.coords.at(i).name.endsWith("(ft)"))) {
addMaxAltitudeMarker(plots.coords.at(i), ui->customPlot->graph(i));
countNumberOfThrows(plots.coords.at(i), ui->customPlot->graph(i));
addCursor(&cursorA, ui->customPlot->graph(i), Qt::blue);
addCursor(&cursorB, ui->customPlot->graph(i), Qt::red);
addCursorLine(&cursorLine, ui->customPlot->graph(i), Qt::black);
updateCursorsLabel();
}
}
ui->customPlot->legend->setVisible(true);
@@ -951,3 +1040,70 @@ void LogsDialog::yAxisChangeRanges(QCPRange range)
yAxesRanges[firstLeft].max = range.upper;
}
}
void LogsDialog::addMaxAltitudeMarker(const coords & c, QCPGraph * graph) {
// find max altitude
int positionIndex = 0;
double maxAlt = -100000;
for(int i=0; i<c.x.count(); ++i) {
double alt = c.y.at(i);
if (alt > maxAlt) {
maxAlt = alt;
positionIndex = i;
// qDebug() << "max alt: " << maxAlt << "@" << result;
}
}
// qDebug() << "max alt: " << maxAlt << "@" << positionIndex;
// add max altitude marker
tracerMaxAlt = new QCPItemTracer(ui->customPlot);
ui->customPlot->addItem(tracerMaxAlt);
tracerMaxAlt->setGraph(graph);
tracerMaxAlt->setInterpolating(true);
tracerMaxAlt->setStyle(QCPItemTracer::tsSquare);
tracerMaxAlt->setPen(QPen(Qt::blue));
tracerMaxAlt->setBrush(Qt::NoBrush);
tracerMaxAlt->setSize(7);
tracerMaxAlt->setGraphKey(c.x.at(positionIndex));
tracerMaxAlt->updatePosition();
}
void LogsDialog::countNumberOfThrows(const coords & c, QCPGraph * graph) {
// find all launches
// TODO
double startTime = c.x.at(0);
for(int i=0; i<c.x.count(); ++i) {
double alt = c.y.at(i);
double time = c.x.at(i);
}
}
void LogsDialog::addCursor(QCPItemTracer ** cursor, QCPGraph * graph, const QColor & color) {
QCPItemTracer * c = new QCPItemTracer(ui->customPlot);
ui->customPlot->addItem(c);
c->setGraph(graph);
c->setInterpolating(false);
c->setStyle(QCPItemTracer::tsCrosshair);
QPen pen(color);
pen.setStyle(Qt::DashLine);
c->setPen(pen);
c->setBrush(color);
c->setSize(7);
c->setVisible(false);
*cursor = c;
}
void LogsDialog::addCursorLine(QCPItemStraightLine ** line, QCPGraph * graph, const QColor & color) {
QCPItemStraightLine * l = new QCPItemStraightLine(ui->customPlot);
ui->customPlot->addItem(l);
l->point1->setParentAnchor(cursorA->position);
l->point2->setParentAnchor(cursorB->position);
QPen pen(color);
pen.setStyle(Qt::DashLine);
l->setPen(pen);
l->setVisible(false);
*line = l;
}
+15 -1
View File
@@ -53,7 +53,7 @@ private slots:
void axisLabelDoubleClick(QCPAxis* axis, QCPAxis::SelectablePart part);
void legendDoubleClick(QCPLegend* legend, QCPAbstractLegendItem* item);
void selectionChanged();
void mousePress();
void mousePress(QMouseEvent * event);
void mouseWheel();
void removeAllGraphs();
void plotLogs();
@@ -76,6 +76,11 @@ private:
double yAxesRatios[AXES_LIMIT];
minMax yAxesRanges[AXES_LIMIT];
QCPItemTracer * tracerMaxAlt;
QCPItemTracer * cursorA;
QCPItemTracer * cursorB;
QCPItemStraightLine * cursorLine;
bool cvsFileParse();
QList<QStringList> filterGePoints(const QList<QStringList> & input);
void exportToGoogleEarth();
@@ -83,6 +88,15 @@ private:
QString generateDuration(const QDateTime & start, const QDateTime & end);
void setFlightSessions();
void addMaxAltitudeMarker(const coords & c, QCPGraph * graph);
void countNumberOfThrows(const coords & c, QCPGraph * graph);
void addCursor(QCPItemTracer ** cursor, QCPGraph * graph, const QColor & color);
void addCursorLine(QCPItemStraightLine ** line, QCPGraph * graph, const QColor & color);
void placeCursor(double x, bool second);
QString formatTimeDelta(double timeDelta);
void updateCursorsLabel();
};
#endif // _LOGSDIALOG_H_
+159 -129
View File
@@ -16,32 +16,78 @@
<property name="sizeGripEnabled">
<bool>true</bool>
</property>
<layout class="QGridLayout" name="gridLayout" rowstretch="0,1,0,0,0,0,0,0">
<item row="0" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout">
<layout class="QGridLayout" name="gridLayout" rowstretch="0,0,0,0,0,0,0,0,0,0,0,0,0,0">
<item row="4" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Filename</string>
<string>Fly sessions</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="FileName_LE">
<property name="readOnly">
<bool>true</bool>
<widget class="QComboBox" name="sessions_CB">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="fileOpen_BT">
<property name="text">
<string>Open LogFile</string>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="1" column="0" rowspan="12">
<widget class="QTableWidget" name="FieldsTW">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>120</width>
<height>16777215</height>
</size>
</property>
<property name="autoScrollMargin">
<number>0</number>
</property>
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="showGrid">
<bool>false</bool>
</property>
<property name="sortingEnabled">
<bool>false</bool>
</property>
<property name="columnCount">
<number>0</number>
</property>
<attribute name="horizontalHeaderStretchLastSection">
<bool>true</bool>
</attribute>
<attribute name="verticalHeaderVisible">
<bool>false</bool>
</attribute>
</widget>
</item>
<item row="1" column="1">
<widget class="QFrame" name="frame_2">
<property name="sizePolicy">
@@ -127,121 +173,7 @@
</item>
</layout>
</item>
<item row="3" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Fly sessions</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="sessions_CB">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="4" column="1" rowspan="4">
<widget class="QTableWidget" name="logTable">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="showDropIndicator" stdset="0">
<bool>false</bool>
</property>
<property name="dragDropOverwriteMode">
<bool>false</bool>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="textElideMode">
<enum>Qt::ElideNone</enum>
</property>
<property name="rowCount">
<number>0</number>
</property>
<property name="columnCount">
<number>0</number>
</property>
<attribute name="verticalHeaderVisible">
<bool>false</bool>
</attribute>
<attribute name="verticalHeaderDefaultSectionSize">
<number>18</number>
</attribute>
<attribute name="verticalHeaderHighlightSections">
<bool>true</bool>
</attribute>
<attribute name="verticalHeaderStretchLastSection">
<bool>false</bool>
</attribute>
</widget>
</item>
<item row="1" column="0" rowspan="6">
<widget class="QTableWidget" name="FieldsTW">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>120</width>
<height>16777215</height>
</size>
</property>
<property name="autoScrollMargin">
<number>0</number>
</property>
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="showGrid">
<bool>false</bool>
</property>
<property name="sortingEnabled">
<bool>false</bool>
</property>
<property name="columnCount">
<number>0</number>
</property>
<attribute name="horizontalHeaderStretchLastSection">
<bool>true</bool>
</attribute>
<attribute name="verticalHeaderVisible">
<bool>false</bool>
</attribute>
</widget>
</item>
<item row="7" column="0">
<item row="13" column="0">
<widget class="QPushButton" name="mapsButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
@@ -276,6 +208,106 @@
</property>
</widget>
</item>
<item row="0" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Filename</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="FileName_LE">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="fileOpen_BT">
<property name="text">
<string>Open LogFile</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="6" column="1" rowspan="8">
<layout class="QHBoxLayout" name="horizontalLayout_4" stretch="5,1">
<item>
<widget class="QTableWidget" name="logTable">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="showDropIndicator" stdset="0">
<bool>false</bool>
</property>
<property name="dragDropOverwriteMode">
<bool>false</bool>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="textElideMode">
<enum>Qt::ElideNone</enum>
</property>
<property name="rowCount">
<number>0</number>
</property>
<property name="columnCount">
<number>0</number>
</property>
<attribute name="verticalHeaderVisible">
<bool>false</bool>
</attribute>
<attribute name="verticalHeaderDefaultSectionSize">
<number>18</number>
</attribute>
<attribute name="verticalHeaderHighlightSections">
<bool>true</bool>
</attribute>
<attribute name="verticalHeaderStretchLastSection">
<bool>false</bool>
</attribute>
</widget>
</item>
<item>
<widget class="QLabel" name="labelCursors">
<property name="minimumSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::Panel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Sunken</enum>
</property>
<property name="lineWidth">
<number>1</number>
</property>
<property name="text">
<string/>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<layoutdefault spacing="6" margin="11"/>
@@ -289,14 +321,12 @@
</customwidgets>
<tabstops>
<tabstop>FileName_LE</tabstop>
<tabstop>fileOpen_BT</tabstop>
<tabstop>FieldsTW</tabstop>
<tabstop>mapsButton</tabstop>
<tabstop>ZoomX_ChkB</tabstop>
<tabstop>ZoomY_ChkB</tabstop>
<tabstop>Reset_PB</tabstop>
<tabstop>sessions_CB</tabstop>
<tabstop>logTable</tabstop>
</tabstops>
<resources>
<include location="companion.qrc"/>