summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Kostovsky <nikita@kostovsky.me>2026-03-06 20:40:29 +0100
committerNikita Kostovsky <nikita@kostovsky.me>2026-03-06 20:40:29 +0100
commit05f0938a65c4f8c330791097680e1e094260bb60 (patch)
treed11e48c96eed6de03c51b793081310d96dee8618
parent051cb23a807a6914e2cda7e3b08d69ed29f347dd (diff)
refactoring
-rw-r--r--src/calibration.cpp73
-rw-r--r--src/calibration.h13
-rw-r--r--src/camera/icamera.h46
-rw-r--r--src/camera/veyeimx287m.cpp76
-rw-r--r--src/camera/veyeimx287m.h17
-rw-r--r--src/constants.h7
-rw-r--r--src/image.cpp3
-rw-r--r--src/iscanner.cpp5
-rw-r--r--src/iscanner.h11
-rw-r--r--src/main.cpp95
-rw-r--r--src/pixels.cpp2
-rw-r--r--src/printerclient.cpp38
-rw-r--r--src/printerclient.h16
-rw-r--r--src/profile.cpp39
-rw-r--r--src/protocols/httpserver.cpp47
-rw-r--r--src/protocols/httpserver.h5
-rw-r--r--src/protocols/iprotocol.cpp4
-rw-r--r--src/protocols/iprotocol.h7
-rw-r--r--src/protocols/pixelsudpstreamer.cpp4
-rw-r--r--src/protocols/pixelsudpstreamer.h2
-rw-r--r--src/scanner.cpp15
-rw-r--r--src/scanner.h9
22 files changed, 389 insertions, 145 deletions
diff --git a/src/calibration.cpp b/src/calibration.cpp
index 6cc85a1..05aed58 100644
--- a/src/calibration.cpp
+++ b/src/calibration.cpp
@@ -207,6 +207,7 @@ QList<Pixels> filter(
Pixels sum = *it;
size_t count{1};
+ qDebug() << "\t" << __func__ << "enc pos:" << it->counters.encoderPosition;
++it;
while (it != rawProfiles.constEnd()
@@ -214,6 +215,7 @@ QList<Pixels> filter(
sum += *it;
++count;
++it;
+ qDebug() << "\t\t" << __func__ << "enc pos:" << it->counters.encoderPosition;
}
sum /= float(count);
@@ -356,12 +358,13 @@ CalibrationTablePtr calibrateX(
return result;
}
-void dumpCalibrationPixels(
- std::vector<Pixels>&& calibrationPixels)
+void dumpCalibrationPixels(const std::vector<std::shared_ptr<Pixels> > &calibrationPixels,
+ const DumpFormat format)
{
- std::vector<Pixels> rawProfiles;
+ const auto &rawProfiles = calibrationPixels;
+ // std::vector<Pixels> rawProfiles;
- std::swap(rawProfiles, calibrationPixels);
+ // std::swap(rawProfiles, calibrationPixels);
const QString dumpSubdir{
QDateTime::currentDateTime().toString("yyyy.MM.dd_hh.mm.ss")};
@@ -375,47 +378,53 @@ void dumpCalibrationPixels(
for (const auto& rawProfile : rawProfiles) {
const auto filename = QLatin1String("raw_profile_meas_%1_enc_%2")
- .arg(QString::number(
- rawProfile.counters.measurementCounter))
- .arg(rawProfile.counters.encoderPosition);
+ .arg(QString::number(rawProfile->counters.measurementCounter))
+ .arg(rawProfile->counters.encoderPosition);
const auto filepath = dumpPath.path() + "/" + filename;
- QFile f{filepath};
+ // TODO: move out of `for` loop
+ // TODO: use switch, or remove enum and create a separate function
+ if (format == DumpFormat::Json) {
+ QFile f{filepath};
- if (!f.open(QFile::WriteOnly)) {
- qWarning() << "cannot open dump dump file" << f.fileName();
- qWarning() << "error is:" << f.errorString();
+ if (!f.open(QFile::WriteOnly)) {
+ qWarning() << "cannot open dump dump file" << f.fileName();
+ qWarning() << "error is:" << f.errorString();
- return;
- }
+ return;
+ }
- QJsonObject jsonCounters{
- {"timestampUs", qint64(rawProfile.counters.timestampUs)},
- {"measurementCounter",
- qint64(rawProfile.counters.measurementCounter)},
- {"encoderPosition", qint64(rawProfile.counters.encoderPosition)},
- };
+ QJsonObject jsonCounters{
+ {"timestampUs", qint64(rawProfile->counters.timestampUs)},
+ {"measurementCounter", qint64(rawProfile->counters.measurementCounter)},
+ {"encoderPosition", qint64(rawProfile->counters.encoderPosition)},
+ };
- QJsonObject json;
+ QJsonObject json;
- json["counters"] = jsonCounters;
+ json["counters"] = jsonCounters;
- QJsonArray jsonPixels;
+ QJsonArray jsonPixels;
- for (const auto& pixel : rawProfile.pixels) {
- jsonPixels << pixel;
- }
+ for (const auto &pixel : rawProfile->pixels) {
+ jsonPixels << pixel;
+ }
- json["pixels"] = jsonPixels;
+ json["pixels"] = jsonPixels;
- if (!f.write(QJsonDocument(json).toJson())) {
- qWarning() << "cannot write file" << f.fileName();
- qWarning() << "error is" << f.errorString();
+ if (!f.write(QJsonDocument(json).toJson())) {
+ qWarning() << "cannot write file" << f.fileName();
+ qWarning() << "error is" << f.errorString();
- return;
- }
+ return;
+ }
- qDebug() << "file written: " << f.fileName();
+ qDebug() << "file written: " << f.fileName();
+ } else if (format == DumpFormat::Binary) {
+ if (!rawProfile->save(filepath)) {
+ return;
+ }
+ }
}
qDebug() << "dump finished";
diff --git a/src/calibration.h b/src/calibration.h
index c2e5d73..4eee441 100644
--- a/src/calibration.h
+++ b/src/calibration.h
@@ -2,8 +2,6 @@
#include <array>
-#include "fuck_intel.h"
-
#include <QSharedPointer>
#include "constants.h"
@@ -18,7 +16,10 @@ constexpr auto calibrationColumnHeight = std::tuple_size<CalibrationColumn>();
bool openCalibrationTable(const QString &filename, CalibrationTablePtr &table);
-void dumpCalibrationPixels(std::vector<Pixels> &&calibrationPixels);
+// void dumpCalibrationPixels(std::vector<Pixels> &&calibrationPixels);
+enum class DumpFormat { Json, Binary };
+void dumpCalibrationPixels(const std::vector<std::shared_ptr<Pixels> > &calibrationPixels,
+ const DumpFormat format = DumpFormat::Json);
bool dump(const CalibrationTablePtr &table, const QString &filename);
QList<Pixels> filter(const QList<Pixels> &rawProfiles);
@@ -31,3 +32,9 @@ QImage calibrationTableToImage(const CalibrationTablePtr &calibrationTable);
void interpolate(CalibrationTablePtr &table);
void interpolate(CalibrationColumn &column);
+
+// TODO: remove from this file
+namespace {
+static CalibrationTablePtr calibrationTableZ;
+static CalibrationTablePtr calibrationTableX;
+} // namespace
diff --git a/src/camera/icamera.h b/src/camera/icamera.h
index d6a2e9a..94408b6 100644
--- a/src/camera/icamera.h
+++ b/src/camera/icamera.h
@@ -1,24 +1,26 @@
#pragma once
-#ifdef emit
-#define emit_backup emit
-#undef emit
-#endif
+#include <QObject>
-#ifdef slots
-#define slots_backup slots
-#undef slots
-#endif
+// #ifdef emit
+// #define emit_backup emit
+// #undef emit
+// #endif
-#include <libcamera/base/signal.h>
+// #ifdef slots
+// #define slots_backup slots
+// #undef slots
+// #endif
-#ifdef emit_backup
-#define emit emit_backup
-#endif
+// // #include <libcamera/base/signal.h>
-#ifdef slots_backup
-#define slots slots_backup
-#endif
+// #ifdef emit_backup
+// #define emit emit_backup
+// #endif
+
+// #ifdef slots_backup
+// #define slots slots_backup
+// #endif
// cpp
#include <chrono>
@@ -26,12 +28,24 @@
// orpheus
#include "image.h"
-class ICamera
+class IStand;
+
+class ICamera : public QObject
{
+ Q_OBJECT
+
public:
virtual ~ICamera() = default;
+signals:
+ void moveMm(double Mm);
+
+public slots:
+ virtual void onMoveFinished() = 0;
+
public:
+ virtual void startCalibration(std::shared_ptr<IStand> stand, double zRangeMm) = 0;
+
[[nodiscard]] virtual bool set_autoExposure(const bool enable) = 0;
/*!
diff --git a/src/camera/veyeimx287m.cpp b/src/camera/veyeimx287m.cpp
index 1fd57f6..1d64395 100644
--- a/src/camera/veyeimx287m.cpp
+++ b/src/camera/veyeimx287m.cpp
@@ -14,8 +14,10 @@
#include <QElapsedTimer>
// orpheus
+#include "calibration.h"
#include "camera/veye_i2c.h"
#include "constants.h"
+#include "pixels.h"
#include "protocols/httpserver.h"
#include "veyeimx287m_types.h"
@@ -238,6 +240,12 @@ VeyeIMX287m::~VeyeIMX287m()
std::cout << "camera closed" << std::endl;
}
+void VeyeIMX287m::onMoveFinished()
+{
+ qDebug() << __func__;
+ m_isMoving = false;
+}
+
std::vector<std::shared_ptr<ICamera> > VeyeIMX287m::search()
{
// FIXME: use saved params, get rid of hardcode
@@ -248,11 +256,11 @@ std::vector<std::shared_ptr<ICamera> > VeyeIMX287m::search()
if (!cam->init())
return {};
- // if (!cam->set_autoExposure(false))
- if (!cam->set_autoExposure(true))
+ if (!cam->set_autoExposure(false))
+ // if (!cam->set_autoExposure(true))
return {};
- if (!cam->set_exposureTime(std::chrono::microseconds(30)))
+ if (!cam->set_exposureTime(std::chrono::microseconds(18)))
return {};
if (!cam->set_autoGain(false))
@@ -292,6 +300,22 @@ bool VeyeIMX287m::startStream()
return true;
}
+void VeyeIMX287m::startCalibration(std::shared_ptr<IStand> stand, double zRangeMm)
+{
+ m_calibrationPixels.clear();
+ m_zRangeMm = zRangeMm;
+ m_stand = stand;
+
+ // auto standObj = dynamic_cast<Esp32Stand *>(stand.get());
+
+ // if (standObj) {
+ // standObj->moveToThread(QThread::currentThread());
+ // }
+
+ m_stand->resetPosSteps();
+ m_isCalibrating = true;
+}
+
bool VeyeIMX287m::init()
{
if (!openCam())
@@ -361,6 +385,7 @@ std::optional<bool> VeyeIMX287m::get_autoGain()
bool VeyeIMX287m::set_exposureTime(const std::chrono::microseconds us)
{
using namespace veye::imx287m;
+ std::cout << __func__ << ": " << us << std::endl;
return m_i2c->write(static_cast<uint16_t>(Register::ME_Time), us.count());
}
@@ -652,6 +677,8 @@ void VeyeIMX287m::rotateFrameLoop(std::stop_token stopToken)
void VeyeIMX287m::calcPixelsLoop(std::stop_token stopToken)
{
+ uint8_t collectedInPos{0};
+
while (!stopToken.stop_requested()) {
// const auto idx = m_sync.rotSemQueue.dequeue();
const auto image = m_sync.rotSemQueue.dequeue();
@@ -661,6 +688,49 @@ void VeyeIMX287m::calcPixelsLoop(std::stop_token stopToken)
std::lock_guard l{m_lastImageMtx};
m_lastProcessedImage = image;
}
+
+ if (m_isCalibrating) {
+ // if (m_ignoreFrames) {
+ if (m_isMoving) {
+ continue;
+ } else {
+ pixels->counters.encoderPosition = m_stand->posSteps();
+ constexpr uint8_t neededCount{8};
+
+ if (collectedInPos < neededCount) {
+ m_calibrationPixels.push_back(pixels);
+ ++collectedInPos;
+ } else {
+ // if (m_stand->posMm() < m_zRangeMm) {
+ if (m_stand->posMm() < debugZRange) {
+ // TODO: dump pixels
+ // dumpCalibrationPixels(m_calibrationPixels);
+ qDebug() << "moveMm:" << m_zRangeMm << ::discretesInRage
+ << "currPos:" << m_stand->posMm() << "zRange:" << m_zRangeMm
+ << m_zRangeMm / ::discretesInRage
+ << "pos steps:" << pixels->counters.encoderPosition;
+ m_isMoving = true;
+
+ collectedInPos = 0;
+ emit moveMm(m_zRangeMm / ::discretesInRage);
+ // m_stand->moveMm(m_zRangeMm / ::discretesInRage);
+ } else {
+ qDebug() << "move to home:" << -m_zRangeMm;
+ qDebug() << "================================";
+ m_isMoving = true;
+ // emit moveMm(-m_zRangeMm);
+ // emit moveMm(debugZRange);
+ // m_stand->moveMm(-m_zRangeMm);
+ m_isCalibrating = false;
+ // m_stand.reset();
+ const auto tmp = m_calibrationPixels;
+ // dumpCalibrationPixels(m_calibrationPixels);
+ dumpCalibrationPixels(tmp, DumpFormat::Binary);
+ m_calibrationPixels.clear();
+ }
+ }
+ }
+ }
}
}
diff --git a/src/camera/veyeimx287m.h b/src/camera/veyeimx287m.h
index b624fd2..bdc57d9 100644
--- a/src/camera/veyeimx287m.h
+++ b/src/camera/veyeimx287m.h
@@ -15,6 +15,8 @@
#include "constants.h"
#include "icamera.h"
#include "image.h"
+// TODO: remove this include
+#include "printerclient.h"
#include "utils/sem_queue.h"
namespace veye {
@@ -24,6 +26,7 @@ class i2c;
} // namespace veye
class HttpServer;
+class IStand;
/*
* start calibration
@@ -58,12 +61,17 @@ public:
VeyeIMX287m();
~VeyeIMX287m() override;
+public slots:
+ void onMoveFinished() override;
+
public:
static std::vector<std::shared_ptr<ICamera>> search();
public:
bool startStream() override;
+ void startCalibration(std::shared_ptr<IStand> stand, double zRangeMm) override;
+
bool dequeueImageBuffer(size_t &image);
std::shared_ptr<Image> getImage() override;
@@ -157,4 +165,13 @@ private:
std::shared_ptr<veye::imx287m::i2c> m_i2c;
std::shared_ptr<HttpServer> m_httpServer;
+
+ // calibration
+ // TODO: re-organize this logic
+ bool m_isCalibrating{false};
+ bool m_ignoreFrames{false};
+ std::vector<std::shared_ptr<Pixels>> m_calibrationPixels;
+ std::shared_ptr<IStand> m_stand;
+ double m_zRangeMm{std::numeric_limits<double>::quiet_NaN()};
+ bool m_isMoving{false};
};
diff --git a/src/constants.h b/src/constants.h
index 83c81c8..6770f5f 100644
--- a/src/constants.h
+++ b/src/constants.h
@@ -34,4 +34,9 @@ const QString exposureTimeKey = "exposureTime";
const QString laserLevelKey = "laserLevel";
const QString gainKey = "gain";
-const QString dumpsRoot{QStringLiteral("/home/user/dumps")};
+// TODO: remove hardcode
+const QString user{"radxa"};
+
+const QString dumpsRoot{QStringLiteral("/home/%1/dumps").arg(user)};
+
+constexpr double debugZRange{5.0};
diff --git a/src/image.cpp b/src/image.cpp
index 0d9b92d..b840b3d 100644
--- a/src/image.cpp
+++ b/src/image.cpp
@@ -201,7 +201,8 @@ std::shared_ptr<Pixels> Image::sharedPixels()
{
t.start();
- static auto result = std::make_shared<Pixels>();
+ // TODO: get rid of this alloc
+ auto result = std::make_shared<Pixels>();
result->counters = counters;
std::transform(rotated_cw.cbegin(), rotated_cw.cend(), result->pixels.begin(), process_column);
diff --git a/src/iscanner.cpp b/src/iscanner.cpp
index c52bb9d..5229b4e 100644
--- a/src/iscanner.cpp
+++ b/src/iscanner.cpp
@@ -5,3 +5,8 @@ IScanner::IScanner(std::shared_ptr<ICamera> camera,
: m_camera{camera}
, m_protocols{protocols}
{}
+
+std::shared_ptr<ICamera> IScanner::camera() const
+{
+ return m_camera;
+}
diff --git a/src/iscanner.h b/src/iscanner.h
index 75300e1..e09197e 100644
--- a/src/iscanner.h
+++ b/src/iscanner.h
@@ -4,12 +4,16 @@
#include <memory>
#include <vector>
+// TODO: remove this include
+#include "calibration.h"
+
class IProtocol;
class ICamera;
class IScanner
{
public:
+ // TODO: get rid of constructor or rename class
explicit IScanner(std::shared_ptr<ICamera> camera,
std::vector<std::shared_ptr<IProtocol>> protocols);
virtual ~IScanner() = default;
@@ -18,6 +22,13 @@ public:
virtual bool startAllProtocols() = 0;
virtual void stopAllProtocols() = 0;
+ // TODO: think about more flexible calibration interface
+ virtual CalibrationTablePtr calibrationTableX() const = 0;
+ virtual CalibrationTablePtr calibrationTableZ() const = 0;
+
+ // TODO: add nullptr check everywhere where this function is used
+ std::shared_ptr<ICamera> camera() const;
+
protected:
std::shared_ptr<ICamera> m_camera;
std::vector<std::shared_ptr<IProtocol>> m_protocols;
diff --git a/src/main.cpp b/src/main.cpp
index 208004f..2d86dac 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -68,11 +68,6 @@ QMutex calibrationPixelsMutex;
using namespace std::chrono_literals;
-namespace {
-CalibrationTablePtr calibrationTableZ;
-CalibrationTablePtr calibrationTableX;
-} // namespace
-
auto printPixels = [](const auto &pixels) {
for (size_t i = (img_width - 10) / 2;
i < img_width - ((img_width - 10) / 2);
@@ -99,30 +94,44 @@ int main(int argc, char *argv[])
QList<QFuture<void>> initializers;
qDebug() << "size of raw profile" << sizeof(Pixels);
- if (false) {
+
+ // Pixels p;
+ // p.counters.encoderPosition = 123;
+ // if (!p.save("/tmp/tmp.pixels")) {
+ // return EXIT_FAILURE;
+ // }
+
+ // Pixels p1;
+ // if (!p1.load("/tmp/tmp.pixels")) {
+ // return EXIT_FAILURE;
+ // }
+ // qDebug() << p.counters.encoderPosition << p.counters.encoderPosition;
+ // return EXIT_SUCCESS;
+
+ if (true) {
// open binary calibration table
- if (true) {
+ if (false) {
initializers << QtConcurrent::run([&]() {
- if (!openCalibrationTable(
- "/home/user/dumps/binz.calibration_table",
- // "/tmp/binz.calibration_table",
- ::calibrationTableZ)) {
+ if (!openCalibrationTable(QStringLiteral("/home/%1/dumps/binz.calibration_table")
+ .arg(user),
+ // "/tmp/binz.calibration_table",
+ ::calibrationTableZ)) {
exit(EXIT_FAILURE);
}
});
initializers << QtConcurrent::run([&]() {
- if (!openCalibrationTable(
- "/home/user/dumps/binx.calibration_table",
- // "/tmp/binx.calibration_table",
- ::calibrationTableX)) {
+ if (!openCalibrationTable(QStringLiteral("/home/%1/dumps/binx.calibration_table")
+ .arg(user),
+ // "/tmp/binx.calibration_table",
+ ::calibrationTableX)) {
exit(EXIT_FAILURE);
}
});
}
if (false) {
- auto rawProfiles = openDump("/home/user/dumps/binx");
+ auto rawProfiles = openDump(QStringLiteral("/home/%1/dumps/binx").arg(user));
qDebug() << "raw x-profiles count is" << rawProfiles.size();
// qDebug() << "height" << calibrationColumnHeight;
@@ -136,22 +145,29 @@ int main(int argc, char *argv[])
}
// load binary calibration dumps and calibrate
- if (false) {
+ if (true) {
if (true) {
- auto rawProfiles = openDump("/home/user/dumps/binz");
+ auto rawProfiles = openDump(QStringLiteral("/home/%1/dumps/binz").arg(user));
qDebug() << "raw z-profiles count is" << rawProfiles.size();
+ if (rawProfiles.empty()) {
+ return EXIT_FAILURE;
+ }
+
auto filteredRawProfiles = filter(std::move(rawProfiles));
qDebug() << "filtered z-profiles count is"
<< filteredRawProfiles.count();
::calibrationTableZ = calibrateZ(std::move(filteredRawProfiles),
requested_params.stepsPerMm);
+ // DEBUG
+ ::calibrationTableX = CalibrationTablePtr{new CalibrationTable{{0}}};
+ memset(::calibrationTableX.get(), 0, sizeof(CalibrationTable));
interpolate(::calibrationTableZ);
if (!dump(::calibrationTableZ,
- "/home/user/dumps/binz.calibration_table")) {
+ QStringLiteral("/home/%1/dumps/binz.calibration_table").arg(user))) {
qApp->exit(EXIT_FAILURE);
}
}
@@ -159,8 +175,8 @@ int main(int argc, char *argv[])
qDebug()
<< "--------------------------------------------------------";
- if (true) {
- auto rawProfiles = openDump("/home/user/dumps/binx");
+ if (false) {
+ auto rawProfiles = openDump(QStringLiteral("/home/%1/dumps/binx").arg(user));
qDebug() << "raw x-profiles count is" << rawProfiles.size();
auto filteredRawProfiles = filter(std::move(rawProfiles));
@@ -172,13 +188,15 @@ int main(int argc, char *argv[])
interpolate(::calibrationTableX);
if (!dump(::calibrationTableX,
- "/home/user/dumps/binx.calibration_table")) {
+ QStringLiteral("/home/%1/dumps/binx.calibration_table").arg(user))) {
qApp->exit(EXIT_FAILURE);
}
}
}
}
+ // exit(EXIT_SUCCESS);
+
QElapsedTimer t;
t.start();
@@ -205,32 +223,29 @@ int main(int argc, char *argv[])
return EXIT_FAILURE;
}
- auto httpServer = std::make_shared<HttpServer>(camera);
-
- const auto scanner
- = std::make_shared<Scanner>(camera,
- std::vector<std::shared_ptr<IProtocol>>{
- httpServer});
+ // TODO: refactor: scanner and http server depend on each other
+ const auto scanner = std::make_shared<Scanner>(camera);
+ auto httpServer = std::make_shared<HttpServer>(scanner);
scanner->startAllProtocols();
+ httpServer->start();
- Esp32Stand stand{QHostAddress{"192.168.18.248"}, 80, 1600};
+ auto stand = std::make_shared<Esp32Stand>(QHostAddress{"192.168.18.248"}, 80, 1600);
QHttpServer qHttpServer;
qHttpServer.route("/v1/profile", [&]() -> QHttpServerResponse {
// std::cout << "http: profile" << std::endl;
- return QHttpServerResponse::StatusCode::ServiceUnavailable;
+ // return QHttpServerResponse::StatusCode::ServiceUnavailable;
std::lock_guard<std::mutex> lg(pgm_image_mtx);
- if (!::calibrationTableZ || !::calibrationTableX)
- return QHttpServerResponse::StatusCode::ServiceUnavailable;
+ // if (!::calibrationTableZ || !::calibrationTableX)
+ // return QHttpServerResponse::StatusCode::ServiceUnavailable;
- const Profile profile(::pixels,
- ::calibrationTableZ,
- ::calibrationTableX);
+ const Profile profile{::pixels, ::calibrationTableZ, ::calibrationTableX};
const QJsonObject json{{"profile", QJsonObject(profile)}};
+ // qDebug() << "profile:" << QJsonDocument(json).toJson();
return QHttpServerResponse(QJsonDocument(json).toJson());
});
@@ -263,6 +278,14 @@ int main(int argc, char *argv[])
// TODO: use flags
scanningModeFlags = ScanningModeFlags::Calibration;
calibrationTimer.start();
+ QObject::connect(camera.get(), &ICamera::moveMm, stand.get(), &IStand::moveMm);
+ QObject::connect(stand.get(),
+ &IStand::moveFinished,
+ camera.get(),
+ &ICamera::onMoveFinished);
+
+ //camera->startCalibration(stand, 200);
+ camera->startCalibration(stand, 200);
return QHttpServerResponse::StatusCode::Ok;
});
@@ -284,7 +307,7 @@ int main(int argc, char *argv[])
distanceMm.remove(0, 1);
// printerClient.sendCommand(command);
- stand.moveMm(distanceMm.toInt());
+ stand->moveMm(distanceMm.toInt());
return QHttpServerResponse::StatusCode::Ok;
});
diff --git a/src/pixels.cpp b/src/pixels.cpp
index 3b69c99..e6d359c 100644
--- a/src/pixels.cpp
+++ b/src/pixels.cpp
@@ -87,6 +87,8 @@ bool Pixels::save(
return false;
}
+ std::cout << "saved pixels at enc pos " << counters.encoderPosition << std::endl;
+
return true;
}
diff --git a/src/printerclient.cpp b/src/printerclient.cpp
index 3a548e9..c19e2a8 100644
--- a/src/printerclient.cpp
+++ b/src/printerclient.cpp
@@ -92,9 +92,28 @@ void PrinterClient::onErrorOccured(QSerialPort::SerialPortError error)
Esp32Stand::Esp32Stand(const QHostAddress &address, const uint32_t port, const uint32_t stepsPerMm)
: m_apiRoot{QStringLiteral("http://") + address.toString() + ':' + QString::number(port)}
, INIT_FIELD(stepsPerMm)
- , m_manager{new QNetworkAccessManager{this}}
+ // , m_manager{new QNetworkAccessManager{this}}
+ // WARNING: memleak
+ , m_manager{new QNetworkAccessManager{}}
{}
+bool Esp32Stand::resetPosSteps()
+{
+ m_posSteps = 0;
+
+ return true;
+}
+
+int Esp32Stand::posSteps()
+{
+ return m_posSteps;
+}
+
+double Esp32Stand::posMm()
+{
+ return m_posSteps / double(m_stepsPerMm);
+}
+
bool Esp32Stand::moveMm(const double mm)
{
return moveSteps(mm * m_stepsPerMm);
@@ -103,23 +122,30 @@ bool Esp32Stand::moveMm(const double mm)
bool Esp32Stand::moveSteps(const int steps)
{
qDebug() << __func__ << "move" << steps << "steps";
- QElapsedTimer t;
- t.start();
+ // QElapsedTimer t;
+ // t.start();
+
QUrlQuery query;
query.addQueryItem(QStringLiteral("steps"), QString::number(steps));
+ // qDebug() << "here-2";
QUrl url{m_apiRoot + QStringLiteral("/move")};
url.setQuery(query);
std::mutex mtx;
+ // qDebug() << "here-1";
+
const auto reply = m_manager->get(QNetworkRequest{url});
+ // qDebug() << "here-123";
mtx.lock();
+ // qDebug() << "here";
connect(reply, &QNetworkReply::finished, this, [reply, &mtx]() {
qDebug() << reply->readAll();
mtx.unlock();
});
+ // qDebug() << "here2";
while (!reply->isFinished()) {
reply->waitForReadyRead(100);
@@ -131,7 +157,11 @@ bool Esp32Stand::moveSteps(const int steps)
std::lock_guard g{mtx};
- qDebug() << __func__ << "moved" << steps << "steps" << t.elapsed();
+ // qDebug() << __func__ << "moved" << steps << "steps" << t.elapsed();
+
+ m_posSteps += steps;
+
+ emit moveFinished();
return true;
}
diff --git a/src/printerclient.h b/src/printerclient.h
index 189bfb5..232dad8 100644
--- a/src/printerclient.h
+++ b/src/printerclient.h
@@ -7,12 +7,20 @@
class QSerialPort;
-class IStand
+class IStand : public QObject
{
+ Q_OBJECT
+
public:
virtual ~IStand() = default;
+signals:
+ void moveFinished();
+
public:
+ virtual bool resetPosSteps() = 0;
+ virtual int posSteps() = 0;
+ virtual double posMm() = 0;
/*!
* \warning be careful when rounding mm to steps
*/
@@ -21,13 +29,16 @@ public:
};
// TODO: think if QObject is needed
-class Esp32Stand : public QObject, public IStand
+class Esp32Stand : public IStand
{
public:
explicit Esp32Stand(const QHostAddress &address, const uint32_t port, const uint32_t stepsPerMm);
~Esp32Stand() override = default;
public:
+ bool resetPosSteps() override;
+ int posSteps() override;
+ double posMm() override;
bool moveMm(const double mm) override;
bool moveSteps(const int steps) override;
@@ -35,6 +46,7 @@ private:
QString m_apiRoot;
uint32_t m_stepsPerMm{0};
QNetworkAccessManager *m_manager{nullptr};
+ int m_posSteps{0};
};
class PrinterClient : public QObject
diff --git a/src/profile.cpp b/src/profile.cpp
index 64ba091..3ed11ba 100644
--- a/src/profile.cpp
+++ b/src/profile.cpp
@@ -11,33 +11,35 @@ Profile::Profile(
const CalibrationTablePtr calibrationTableX)
: m_counters(pixels.counters)
{
- if (!calibrationTableZ || !calibrationTableX)
- {
- std::cerr << __func__ << ": got invalid calibration tables"
- << std::endl;
+ // if (!calibrationTableZ || !calibrationTableX) {
+ // std::cerr << __func__ << ": got invalid calibration tables" << std::endl;
- return;
- }
+ // return;
+ // }
static bool done{false};
- if (!done) {
- for (size_t i = 9471; i < 9472; i++) {
- std::cout << __func__ << ": row #" << i << ": ";
+ // if (!done) {
+ // // for (size_t i = 9471; i < 9472; i++) {
+ // for (size_t i = 0; i < calibrationTableHeight; i++) {
+ // std::cout << __func__ << ": row #" << i << ": ";
- for (size_t j = 0; j < img_width; ++j) {
- const auto& x = calibrationTableX->at(j).at(i);
- const auto& z = calibrationTableZ->at(j).at(i);
- std::cout << "Profile: table: " << x << ' ' << z << std::endl;
- }
+ // for (size_t j = 0; j < img_width; ++j) {
+ // const auto &x = calibrationTableX ? calibrationTableX->at(j).at(i) : j;
+ // const auto &z = calibrationTableZ->at(j).at(i);
+ // std::cout << "Profile: table: " << x << ' ' << z << std::endl;
+ // }
- std::cout << std::endl;
- }
- }
+ // std::cout << std::endl;
+ // }
+ // }
for (size_t i = 0; i < img_width; ++i) {
try {
const auto& pixel = pixels.pixels[i];
+ if (!qFuzzyIsNull(pixel)) {
+ qt_noop();
+ }
const auto pixelDiscrete = pixel * discretesInRage / img_height;
if (Q_UNLIKELY(pixel >= sizeof(CalibrationColumn) / sizeof(float))) {
qWarning() << "got invalid calibration pixel at" << i << ":"
@@ -79,8 +81,7 @@ Profile::Profile(
// TODO: use only NaN (or zero?) everywhere
// NOTE: QJsonValue converts NaN to zero
if (qFuzzyIsNull(z) || std::isnan(z)) {
- // qDebug() << "got nan z for discrete" << pixelDiscrete << leftMmZ
- // << rightMmZ;
+ // qDebug() << "got nan z for discrete" << pixelDiscrete << leftMmZ << rightMmZ;
m_pointsMm.at(i) = {std::nan(""), std::nan("")};
continue;
}
diff --git a/src/protocols/httpserver.cpp b/src/protocols/httpserver.cpp
index dc3b59a..3ca1f5c 100644
--- a/src/protocols/httpserver.cpp
+++ b/src/protocols/httpserver.cpp
@@ -12,7 +12,9 @@
#include "constants.h"
#include "image.h"
#include "imagealgos.h"
+#include "iscanner.h"
#include "macro.h"
+#include "profile.h"
#include "utils/elapsed_logger.h"
// rapidjson
@@ -24,10 +26,10 @@ extern uint8_t pgm_image[64 + img_width * img_height * sizeof(uint8_t)];
extern size_t pgm_image_size;
extern std::mutex pgm_image_mtx;
-HttpServer::HttpServer(std::shared_ptr<ICamera> camera,
+HttpServer::HttpServer(std::shared_ptr<IScanner> scanner,
const QHostAddress &address,
const uint16_t port)
- : IProtocol{camera}
+ : IProtocol{scanner}
, INIT_FIELD(address)
, INIT_FIELD(port)
// , m_server{std::make_shared<QHttpServer>()}
@@ -40,11 +42,14 @@ bool HttpServer::start()
// TODO: move these vars outside
const auto apiPrefix = QStringLiteral("/v1");
+ // TODO: route automatically
const auto pixelsPath = apiPrefix + "/pixels";
+ const auto profilesPath = apiPrefix + "/profile";
qDebug().noquote() << Q_FUNC_INFO << ": pixelsPath: " << pixelsPath;
// TODO: get rid of lamdas, there should be a better way
m_server->route(pixelsPath, [this]() { return GET_pixels(); });
+ m_server->route(profilesPath, [this]() { return GET_profile(); });
m_server->route(apiPrefix + QStringLiteral("/sensor/params"),
QHttpServerRequest::Method::Get,
[this]() { return GET_params(); });
@@ -86,7 +91,7 @@ QHttpServerResponse HttpServer::GET_image()
{
// Image img;
- const auto image = m_camera->getImage();
+ const auto image = m_scanner->camera()->getImage();
// if (!m_camera->getImage(&img)) {
if (!image) {
@@ -110,7 +115,7 @@ QFuture<QHttpServerResponse> HttpServer::GET_image_async()
QHttpServerResponse HttpServer::GET_pixels()
{
- if (!m_camera) {
+ if (!m_scanner) {
qWarning() << "NO CAM";
return QHttpServerResponse::StatusCode::ServiceUnavailable;
}
@@ -118,7 +123,7 @@ QHttpServerResponse HttpServer::GET_pixels()
std::shared_ptr<Image> image;
{
// const elapsed_logger logger{__func__};
- /*const auto */ image = m_camera->getImage();
+ /*const auto */ image = m_scanner->camera()->getImage();
}
if (!image) {
@@ -176,6 +181,17 @@ QHttpServerResponse HttpServer::GET_pixels()
return QHttpServerResponse{res};
}
+QHttpServerResponse HttpServer::GET_profile()
+{
+ const auto image = m_scanner->camera()->getImage();
+ const auto pixels = image->sharedPixels();
+ const auto profile = Profile{*pixels, ::calibrationTableZ, ::calibrationTableX};
+
+ const QJsonObject json{profile};
+
+ return QHttpServerResponse{QJsonDocument{json}.toJson()};
+}
+
QHttpServerResponse HttpServer::POST_params(const QHttpServerRequest &request)
{
const auto json = QJsonDocument::fromJson(request.body()).object();
@@ -201,9 +217,11 @@ QHttpServerResponse HttpServer::POST_params(const QHttpServerRequest &request)
const auto gain = json["gain"];
const auto triggerExposureDelayUs = json["triggerExposureDelayUs"];
+ // TODO: unify args processing to avoid code duplicates
if (!autoExposure.isNull()) {
if (autoExposure.isBool()) {
- m_camera->set_autoExposure(autoExposure.toBool());
+ // TODO: enable -Werror and some pedantic checks
+ m_scanner->camera()->set_autoExposure(autoExposure.toBool());
} else {
return {invalidValue("autoExposure"),
QHttpServerResponse::StatusCode::BadRequest};
@@ -212,8 +230,7 @@ QHttpServerResponse HttpServer::POST_params(const QHttpServerRequest &request)
if (!exposureTime.isNull()) {
if (exposureTime.isDouble()) {
- m_camera->set_exposureTime(
- std::chrono::microseconds{exposureTime.toInt()});
+ m_scanner->camera()->set_exposureTime(std::chrono::microseconds{exposureTime.toInt()});
} else {
return {invalidValue("exposureTime"),
QHttpServerResponse::StatusCode::BadRequest};
@@ -222,7 +239,7 @@ QHttpServerResponse HttpServer::POST_params(const QHttpServerRequest &request)
if (!autoGain.isNull()) {
if (autoGain.isBool()) {
- m_camera->set_autoGain(autoGain.toBool());
+ m_scanner->camera()->set_autoGain(autoGain.toBool());
} else {
return {invalidValue("autoGain"),
QHttpServerResponse::StatusCode::BadRequest};
@@ -231,7 +248,7 @@ QHttpServerResponse HttpServer::POST_params(const QHttpServerRequest &request)
if (!gain.isNull()) {
if (gain.isDouble()) {
- m_camera->set_gain(gain.toDouble());
+ m_scanner->camera()->set_gain(gain.toDouble());
} else {
return {invalidValue("gain"),
QHttpServerResponse::StatusCode::BadRequest};
@@ -240,7 +257,7 @@ QHttpServerResponse HttpServer::POST_params(const QHttpServerRequest &request)
if (!triggerExposureDelayUs.isNull()) {
if (triggerExposureDelayUs.isDouble()) {
- const auto ok = m_camera->set_triggerExposureDelay(
+ const auto ok = m_scanner->camera()->set_triggerExposureDelay(
std::chrono::microseconds{triggerExposureDelayUs.toInt()});
if (!ok) {
@@ -270,10 +287,10 @@ QHttpServerResponse HttpServer::GET_params()
};
const auto json = QJsonObject{
- {"autoExposure", val_or_null(m_camera->get_autoExposure())},
- {"exposureTime", chrono_val_or_null(m_camera->get_exposureTime())},
- {"autoGain", val_or_null(m_camera->get_autoGain())},
- {"gain", val_or_null(m_camera->get_gain())},
+ {"autoExposure", val_or_null(m_scanner->camera()->get_autoExposure())},
+ {"exposureTime", chrono_val_or_null(m_scanner->camera()->get_exposureTime())},
+ {"autoGain", val_or_null(m_scanner->camera()->get_autoGain())},
+ {"gain", val_or_null(m_scanner->camera()->get_gain())},
};
qDebug().noquote() << __func__ << ": " << json;
diff --git a/src/protocols/httpserver.h b/src/protocols/httpserver.h
index e3ca66f..320ce00 100644
--- a/src/protocols/httpserver.h
+++ b/src/protocols/httpserver.h
@@ -9,7 +9,7 @@
// orpheus
#include "iprotocol.h"
-class ICamera;
+class IScanner;
class QHttpServer;
class HttpServer : public IProtocol
@@ -25,7 +25,7 @@ public:
static constexpr uint16_t DefaultPort{8080};
public:
- explicit HttpServer(std::shared_ptr<ICamera> camera,
+ explicit HttpServer(std::shared_ptr<IScanner> scanner,
const QHostAddress &address = DefaultAddress,
const uint16_t port = DefaultPort);
~HttpServer() override = default;
@@ -45,6 +45,7 @@ public:
*/
QFuture<QHttpServerResponse> GET_image_async();
QHttpServerResponse GET_pixels();
+ QHttpServerResponse GET_profile();
QHttpServerResponse POST_params(const QHttpServerRequest &request);
QHttpServerResponse GET_params();
diff --git a/src/protocols/iprotocol.cpp b/src/protocols/iprotocol.cpp
index 5422a9d..02270b4 100644
--- a/src/protocols/iprotocol.cpp
+++ b/src/protocols/iprotocol.cpp
@@ -1,5 +1,5 @@
#include "iprotocol.h"
-IProtocol::IProtocol(std::shared_ptr<ICamera> camera)
- : m_camera{camera}
+IProtocol::IProtocol(std::shared_ptr<IScanner> camera)
+ : m_scanner{camera}
{}
diff --git a/src/protocols/iprotocol.h b/src/protocols/iprotocol.h
index 75259bc..3f49eb6 100644
--- a/src/protocols/iprotocol.h
+++ b/src/protocols/iprotocol.h
@@ -2,12 +2,13 @@
#include <memory>
-class ICamera;
+class IScanner;
class IProtocol
{
public:
- explicit IProtocol(std::shared_ptr<ICamera> camera);
+ // TODO: get rid of constructor or rename class
+ explicit IProtocol(std::shared_ptr<IScanner> camera);
virtual ~IProtocol() = default;
public:
@@ -15,5 +16,5 @@ public:
virtual void stop() = 0;
protected:
- std::shared_ptr<ICamera> m_camera;
+ std::shared_ptr<IScanner> m_scanner;
};
diff --git a/src/protocols/pixelsudpstreamer.cpp b/src/protocols/pixelsudpstreamer.cpp
index e7498d7..2855a35 100644
--- a/src/protocols/pixelsudpstreamer.cpp
+++ b/src/protocols/pixelsudpstreamer.cpp
@@ -2,9 +2,9 @@
#include <QUdpSocket>
-PixelsUdpStreamer::PixelsUdpStreamer(std::shared_ptr<ICamera> camera, QObject *parent)
+PixelsUdpStreamer::PixelsUdpStreamer(std::shared_ptr<IScanner> scanner, QObject *parent)
: QObject{parent}
- , IProtocol{camera}
+ , IProtocol{scanner}
{}
bool PixelsUdpStreamer::start()
diff --git a/src/protocols/pixelsudpstreamer.h b/src/protocols/pixelsudpstreamer.h
index a7f69b7..dacc9cb 100644
--- a/src/protocols/pixelsudpstreamer.h
+++ b/src/protocols/pixelsudpstreamer.h
@@ -15,7 +15,7 @@ class PixelsUdpStreamer : public QObject, public IProtocol
Q_OBJECT
public:
- explicit PixelsUdpStreamer(std::shared_ptr<ICamera> camera, QObject *parent = nullptr);
+ explicit PixelsUdpStreamer(std::shared_ptr<IScanner> scanner, QObject *parent = nullptr);
~PixelsUdpStreamer() override = default;
public slots:
diff --git a/src/scanner.cpp b/src/scanner.cpp
index 07d3c0f..9012769 100644
--- a/src/scanner.cpp
+++ b/src/scanner.cpp
@@ -2,9 +2,10 @@
#include "protocols/iprotocol.h"
-Scanner::Scanner(std::shared_ptr<ICamera> camera,
- std::vector<std::shared_ptr<IProtocol>> protocols)
+Scanner::Scanner(std::shared_ptr<ICamera> camera, std::vector<std::shared_ptr<IProtocol>> protocols)
: IScanner{camera, protocols}
+ , m_calibrationTableX{new CalibrationTable{}}
+ , m_calibrationTableZ{new CalibrationTable{}}
{
// m_protocols.push_back()
}
@@ -28,3 +29,13 @@ void Scanner::stopAllProtocols()
protocol->stop();
}
}
+
+CalibrationTablePtr Scanner::calibrationTableX() const
+{
+ return m_calibrationTableX;
+}
+
+CalibrationTablePtr Scanner::calibrationTableZ() const
+{
+ return m_calibrationTableZ;
+}
diff --git a/src/scanner.h b/src/scanner.h
index 8031dda..4d81d1a 100644
--- a/src/scanner.h
+++ b/src/scanner.h
@@ -6,10 +6,17 @@ class Scanner : public IScanner
{
public:
explicit Scanner(std::shared_ptr<ICamera> camera,
- std::vector<std::shared_ptr<IProtocol>> protocols);
+ std::vector<std::shared_ptr<IProtocol>> protocols = {});
~Scanner() override = default;
public:
bool startAllProtocols() override;
void stopAllProtocols() override;
+
+ CalibrationTablePtr calibrationTableX() const override;
+ CalibrationTablePtr calibrationTableZ() const override;
+
+private:
+ CalibrationTablePtr m_calibrationTableX;
+ CalibrationTablePtr m_calibrationTableZ;
};