diff options
| -rw-r--r-- | CMakeLists.txt | 3 | ||||
| -rw-r--r-- | Main.qml | 127 | ||||
| -rw-r--r-- | QmlCustomPlot.cpp | 12 | ||||
| -rw-r--r-- | QmlCustomPlot.h | 1 | ||||
| -rw-r--r-- | main.cpp | 56 |
5 files changed, 154 insertions, 45 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 61c0414..2923a7b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,6 +3,9 @@ cmake_minimum_required(VERSION 3.16) project(eurydice VERSION 0.1 LANGUAGES CXX) set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_STANDARD 23) +set(CMAKE_CXX20_STANDARD_COMPILE_OPTION "-std:c++latest") +set(CMAKE_CXX20_EXTENSION_COMPILE_OPTION "-std:c++latest") find_package(Qt6 6.5 REQUIRED COMPONENTS Widgets @@ -6,6 +6,8 @@ import QmlCustomPlot 1.0 import "request.js" as XHR +import eurydice + ApplicationWindow { id: mainWindowRoot @@ -13,7 +15,8 @@ ApplicationWindow { height: 480 visible: true // visibility: Window.Maximized - visibility: ApplicationWindow.Maximized + // visibility: ApplicationWindow.Maximized + visibility: ApplicationWindow.FullScreen title: qsTr("Hello World") @@ -122,6 +125,23 @@ ApplicationWindow { }, JSON.stringify(json)); } + function resetEncoder() { + var url = apiRoot + "/commands/resetEncoder"; + console.log("resetEncoder:", url); + + XHR.sendRequest("POST", url, function(response) { + + if (response.status != "200") { + console.log("response status: ", response.status); + return; + } + + // console.log("resetEncoder result:", response.content); + + // var json = JSON.parse(response.content); + }); + } + RowLayout { id: horizontalLayout @@ -219,6 +239,28 @@ ApplicationWindow { } Label { + Layout.fillWidth: true + Layout.alignment: Qt.AlignTop + + text: "Pos: " + (parseFloat(encoderPosition) / 200.).toFixed(3) + } + + Label { + Layout.fillWidth: true + Layout.alignment: Qt.AlignTop + + text: "Measurement: " + measurementCounter + } + + Label { + Layout.fillWidth: true + Layout.alignment: Qt.AlignTop + + text: "Timestamp (ms): " + + (parseFloat(timestampUs % (1000 * 1000 * 1000)) / 1000.).toFixed(1) + } + + Label { text: qsTr("Exposure time (us):") } @@ -232,7 +274,7 @@ ApplicationWindow { stepSize: 100 editable: true - value: 200 + value: 1000 onValueChanged: writeParams() } @@ -258,50 +300,75 @@ ApplicationWindow { onCheckedChanged: writeParams() } + Button { + text: qsTr("Reset encoder") + onClicked: resetEncoder() + } + Item { Layout.fillHeight: true } } } - ImageViewer { - id: image + ColumnLayout { - Layout.fillHeight: true - Layout.fillWidth: true - Layout.minimumWidth: 200 - } + TabBar { + id: tabBar - Item { + Layout.fillWidth: true - Layout.fillHeight: true - Layout.fillWidth: true - Layout.minimumWidth: 900 - Layout.minimumHeight: 600 + currentIndex: 0 + + Shortcut { + sequence: "alt+1" + onActivated: tabBar.currentIndex = 0 + } + + Shortcut { + sequence: "alt+2" + onActivated: tabBar.currentIndex = 1 + } - Rectangle { - color: "red" - opacity: 0.1 - z: 101 + TabButton { + text: qsTr("Image") + } + + TabButton { + text: qsTr("Pixels") + } } - QmlCustomPlot { - id: qmlPlot + SwipeView { + Layout.fillHeight: true + Layout.fillWidth: true + Layout.minimumWidth: mainWindowRoot.width * 0.8 - anchors.fill: parent + currentIndex: tabBar.currentIndex + clip: true + interactive: false - Label { - anchors { - top: parent.top - topMargin: 8 * 2 - horizontalCenter: parent.horizontalCenter - } - text: qmlPlot.fps - color: Material.color(Material.accent) + ImageViewer { + id: image } - plot: myPlot - // Component.onCompleted: initCustomPlot() + QmlCustomPlot { + id: qmlPlot + + Label { + anchors { + top: parent.top + topMargin: 8 * 2 + horizontalCenter: parent.horizontalCenter + } + text: qmlPlot.fps + color: Material.accent + } + + plot: myPlot + // Component.onCompleted: setRange(Qt.rect(-640, 0, 1280, 800)) + // Component.onCompleted: initCustomPlot() + } } } } diff --git a/QmlCustomPlot.cpp b/QmlCustomPlot.cpp index 48ec917..ef30b3f 100644 --- a/QmlCustomPlot.cpp +++ b/QmlCustomPlot.cpp @@ -58,6 +58,8 @@ void QmlCustomPlot::setPlot(QCustomPlot *plot) m_plot->yAxis->setLabel("y"); m_plot->xAxis->setRange(-50, 50); m_plot->yAxis->setRange(0, 100); + m_plot->xAxis->setRange(-640, 640); + m_plot->yAxis->setRange(0, 800); m_plot ->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectPlottables | @@ -73,11 +75,13 @@ void QmlCustomPlot::setPlot(QCustomPlot *plot) m_profileGraph->setPen(QPen(QColor(Qt::red))); } - startTimer(1000 / 24); + startTimer(std::chrono::milliseconds(1000/60)); connect(m_plot, &QCustomPlot::afterReplot, this, &QmlCustomPlot::onCustomReplot); m_plot->replot(); + + // m_plot->setPlottingHints(QCP::phNone); } void QmlCustomPlot::setPoints(const QVector<QVector2D> points) @@ -333,3 +337,9 @@ void QmlCustomPlot::onCustomReplot() m_fpsCounter++; update(); } + +void QmlCustomPlot::setRange(const QRectF &range) +{ + m_plot->xAxis->setRange(range.left(), range.right()); + m_plot->yAxis->setRange(range.bottom(), range.top()); +} diff --git a/QmlCustomPlot.h b/QmlCustomPlot.h index c56038c..3354619 100644 --- a/QmlCustomPlot.h +++ b/QmlCustomPlot.h @@ -34,6 +34,7 @@ public slots: void setLines(const QVector<QLineF> lines); void setContours(const QVector<Points2D> contours); void setFps(int fps); + void setRange(const QRectF &range); signals: void plotChanged(); @@ -8,6 +8,12 @@ #include "QmlCustomPlot.h" +template <typename T> +T& median3(const T& a, const T& b, const T& c) { + using namespace std; + return max(min(a,b), min(max(a,b),c)); +} + int main(int argc, char *argv[]) { QApplication app(argc, argv); @@ -38,7 +44,7 @@ int main(int argc, char *argv[]) auto graph = plot->addGraph(); graph->setPen(QPen(QBrush(Qt::red), 2)); - graph->setLineStyle(QCPGraph::lsLine); + graph->setLineStyle(QCPGraph::lsNone); graph->setScatterStyle(QCPScatterStyle::ssDot); graph->setData(x_profile, y_profile); @@ -46,7 +52,7 @@ int main(int argc, char *argv[]) auto manager = new QNetworkAccessManager(&app); QTimer pixelsAutoRestartTimer(&app); - pixelsAutoRestartTimer.setInterval(1000); + pixelsAutoRestartTimer.setInterval(500); pixelsAutoRestartTimer.setSingleShot(false); QObject::connect(&pixelsAutoRestartTimer, &QTimer::timeout, [&](){ @@ -61,17 +67,19 @@ int main(int argc, char *argv[]) return; } - auto jsonPixels = QJsonDocument::fromJson(reply->readAll()) - .object()["pixels"].toArray(); + auto json = QJsonDocument::fromJson(reply->readAll()) + .object(); + auto jsonPixels = json["pixels"].toArray(); + auto encoderPosition = json["encoderPosition"].toInteger(); + auto measurementCounter = json["measurementCounter"].toInteger(); + auto timestampUs = json["timestampUs"].toInteger(); // y_profile.clear(); for (int i = 0; i < jsonPixels.count(); ++i) { - y_profile[i] = jsonPixels[i].toDouble(); + y_profile[i] = jsonPixels.at(i).toDouble(); } - graph->setData(x_profile, y_profile); - QVector<qreal> y_diff(y_profile.count()); qreal max_diff { 0. }; qreal min_diff { 1000000. }; @@ -80,19 +88,19 @@ int main(int argc, char *argv[]) qreal avg_diff { 0. }; for (size_t i = 0; i < y_profile.count(); ++i) { - y_diff[i] = y_profile[i] - prev_y_profile[i]; + y_diff[i] = y_profile.at(i) - prev_y_profile.at(i); - if (y_diff[i] > max_diff) { - max_diff = y_diff[i]; + if (y_diff.at(i) > max_diff) { + max_diff = y_diff.at(i); max_diff_idx = i; } - if (y_diff[i] < min_diff) { - min_diff = y_diff[i]; + if (y_diff.at(i) < min_diff) { + min_diff = y_diff.at(i); min_diff_idx = i; } - avg_diff += fabs(y_diff[i]); + avg_diff += fabs(y_diff.at(i)); } avg_diff /= y_diff.size(); @@ -104,7 +112,24 @@ int main(int argc, char *argv[]) // // const auto max_diff = std::max_element(y_diff.begin(), y_diff.end()); // const auto avg_diff = std::accumulate(y_diff.begin(), y_diff.end(), 0.0) / y_diff.size(); std::sort(y_diff.begin(), y_diff.end()); - const auto median_diff = y_diff[y_diff.size() * 3 / 4]; + const auto median_diff = y_diff.at(y_diff.size() * 3 / 4); + + // if (qFuzzyIsNull(max_diff)) { + // qDebug() << "max_diff is null"; + + // static bool done = [&]() -> bool { + // for (const auto & y : y_profile) { + // qDebug() << y; + // } + // return true; + // }(); + + // manager->get(request); + + // return; + // } + + graph->setData(x_profile, y_profile); engine.rootContext()->setContextProperty("max_diff", max_diff); engine.rootContext()->setContextProperty("max_diff_idx", int(max_diff_idx)); @@ -112,6 +137,9 @@ int main(int argc, char *argv[]) engine.rootContext()->setContextProperty("min_diff_idx", int(min_diff_idx)); engine.rootContext()->setContextProperty("avg_diff", avg_diff); engine.rootContext()->setContextProperty("median_diff", median_diff); + engine.rootContext()->setContextProperty("encoderPosition", encoderPosition); + engine.rootContext()->setContextProperty("measurementCounter", measurementCounter); + engine.rootContext()->setContextProperty("timestampUs", timestampUs); manager->get(request); pixelsAutoRestartTimer.start(); |
