summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/calibration.cpp36
-rw-r--r--src/calibration.h16
-rw-r--r--src/camera/veyeimx287m.cpp29
-rw-r--r--src/camera/veyeimx287m.h9
-rw-r--r--src/constants.h3
-rw-r--r--src/main.cpp111
-rw-r--r--src/profile.cpp4
-rw-r--r--src/protocols/httpserver.cpp11
-rw-r--r--src/scanner.cpp2
9 files changed, 125 insertions, 96 deletions
diff --git a/src/calibration.cpp b/src/calibration.cpp
index 05aed58..41e6270 100644
--- a/src/calibration.cpp
+++ b/src/calibration.cpp
@@ -13,8 +13,7 @@
#include "imagealgos.h"
-bool openCalibrationTable(
- const QString& filename, CalibrationTablePtr& table)
+bool openCalibrationTable(const QString &filename, const CalibrationTablePtr table)
{
QFile f(filename);
@@ -25,7 +24,6 @@ bool openCalibrationTable(
return false;
}
- table.reset(new CalibrationTable{{0}});
auto bytes = f.read((char*) table.data(), sizeof(CalibrationTable));
if (bytes != sizeof(CalibrationTable)) {
@@ -73,8 +71,7 @@ bool dump(
return true;
}
-void interpolate(
- CalibrationTablePtr& table)
+void interpolate(const CalibrationTablePtr table)
{
std::for_each(std::execution::par,
table->begin(),
@@ -214,8 +211,8 @@ QList<Pixels> filter(
&& it->counters.encoderPosition == sum.counters.encoderPosition) {
sum += *it;
++count;
- ++it;
qDebug() << "\t\t" << __func__ << "enc pos:" << it->counters.encoderPosition;
+ ++it;
}
sum /= float(count);
@@ -225,12 +222,11 @@ QList<Pixels> filter(
return result;
}
-CalibrationTablePtr calibrateZ(
- const QList<Pixels>& rawProfiles, const uint32_t& stepsPerMm)
+bool calibrateZ(const QList<Pixels> &rawProfiles,
+ const uint32_t &stepsPerMm,
+ CalibrationTablePtr table)
{
- CalibrationTablePtr result{new CalibrationTable{{0}}};
-
- for (const auto& rawProfile : rawProfiles) {
+ for (const auto &rawProfile : rawProfiles) {
const float positionMm{float(rawProfile.counters.encoderPosition) /
float(stepsPerMm)};
@@ -247,25 +243,23 @@ CalibrationTablePtr calibrateZ(
<< ":/tinvalid discrete value. col: " << columnIdx
<< ", val: " << pixelValue << std::endl;
- return {};
+ return false;
}
- auto& calibrationColumn = (*result)[columnIdx];
+ auto &calibrationColumn = (*table)[columnIdx];
calibrationColumn[discretePixelValue] = positionMm;
}
}
- return result;
+ return true;
}
-CalibrationTablePtr calibrateX(
- const QList<Pixels>& rawProfiles)
+bool calibrateX(const QList<Pixels> &rawProfiles, CalibrationTablePtr table)
{
// TODO: move to settings
constexpr double triangleBaseMm{8.};
- CalibrationTablePtr result{new CalibrationTable{{0}}};
- for (const auto& rawProfile : rawProfiles) {
+ for (const auto &rawProfile : rawProfiles) {
const auto& pixels = rawProfile.pixels;
auto lines = pixelsToLines(rawProfile);
@@ -342,7 +336,7 @@ CalibrationTablePtr calibrateX(
std::cerr << __func__
<< ":/tinvalid discrete value. col: " << columnIdx
<< ", val: " << pixelValue << std::endl;
- return {};
+ return false;
}
// use value interpolated between line endings (anchors)
@@ -351,11 +345,11 @@ CalibrationTablePtr calibrateX(
const auto xRelative = float(columnX - xLeft) / xLineLen;
const auto xMmValue = xLeftMm + xRelative * (triangleBaseMm / 2.);
- (*result)[columnIdx][discretePixelValue] = xMmValue;
+ (*table)[columnIdx][discretePixelValue] = xMmValue;
}
}
- return result;
+ return true;
}
void dumpCalibrationPixels(const std::vector<std::shared_ptr<Pixels> > &calibrationPixels,
diff --git a/src/calibration.h b/src/calibration.h
index 4eee441..4876c17 100644
--- a/src/calibration.h
+++ b/src/calibration.h
@@ -14,7 +14,7 @@ using CalibrationTablePtr = QSharedPointer<CalibrationTable>;
constexpr auto calibrationColumnHeight = std::tuple_size<CalibrationColumn>();
-bool openCalibrationTable(const QString &filename, CalibrationTablePtr &table);
+bool openCalibrationTable(const QString &filename, const CalibrationTablePtr table);
// void dumpCalibrationPixels(std::vector<Pixels> &&calibrationPixels);
enum class DumpFormat { Json, Binary };
@@ -22,19 +22,21 @@ void dumpCalibrationPixels(const std::vector<std::shared_ptr<Pixels> > &calibrat
const DumpFormat format = DumpFormat::Json);
bool dump(const CalibrationTablePtr &table, const QString &filename);
+// TODO: implement median filter
QList<Pixels> filter(const QList<Pixels> &rawProfiles);
-CalibrationTablePtr calibrateX(const QList<Pixels> &rawProfiles);
-CalibrationTablePtr calibrateZ(const QList<Pixels> &rawProfiles,
- const uint32_t &stepsPerMm);
+bool calibrateX(const QList<Pixels> &rawProfiles, CalibrationTablePtr table);
+bool calibrateZ(const QList<Pixels> &rawProfiles,
+ const uint32_t &stepsPerMm,
+ CalibrationTablePtr table);
QImage calibrationTableToImage(const CalibrationTablePtr &calibrationTable);
-void interpolate(CalibrationTablePtr &table);
+void interpolate(const CalibrationTablePtr table);
void interpolate(CalibrationColumn &column);
// TODO: remove from this file
namespace {
-static CalibrationTablePtr calibrationTableZ;
-static CalibrationTablePtr calibrationTableX;
+// static CalibrationTablePtr calibrationTableZ;
+// static CalibrationTablePtr calibrationTableX;
} // namespace
diff --git a/src/camera/veyeimx287m.cpp b/src/camera/veyeimx287m.cpp
index 1d64395..0bb0724 100644
--- a/src/camera/veyeimx287m.cpp
+++ b/src/camera/veyeimx287m.cpp
@@ -242,6 +242,7 @@ VeyeIMX287m::~VeyeIMX287m()
void VeyeIMX287m::onMoveFinished()
{
+ qDebug() << "================================================";
qDebug() << __func__;
m_isMoving = false;
}
@@ -647,6 +648,7 @@ void VeyeIMX287m::getFrameLoop(std::stop_token stopToken)
const auto image = std::make_shared<Image>();
auto &dst = image->data;
Image::copy(dst, src);
+ image->counters.measurementCounter = m_rawBuffers[bufferIdx].sequence;
// image->rotate();
// const auto pixels = image->sharedPixels();
@@ -677,7 +679,7 @@ void VeyeIMX287m::rotateFrameLoop(std::stop_token stopToken)
void VeyeIMX287m::calcPixelsLoop(std::stop_token stopToken)
{
- uint8_t collectedInPos{0};
+ constexpr uint32_t neededCount{8};
while (!stopToken.stop_requested()) {
// const auto idx = m_sync.rotSemQueue.dequeue();
@@ -695,23 +697,24 @@ void VeyeIMX287m::calcPixelsLoop(std::stop_token stopToken)
continue;
} else {
pixels->counters.encoderPosition = m_stand->posSteps();
- constexpr uint8_t neededCount{8};
- if (collectedInPos < neededCount) {
- m_calibrationPixels.push_back(pixels);
- ++collectedInPos;
+ if (m_calibrationPixels[pixels->counters.encoderPosition].size() < neededCount) {
+ m_calibrationPixels[pixels->counters.encoderPosition].push_back(pixels);
+ qDebug() << "\tenc:" << pixels->counters.encoderPosition << "in pos:"
+ << m_calibrationPixels[pixels->counters.encoderPosition].size()
+ % neededCount;
} 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
+ << "\tcurrPos:" << m_stand->posMm() << "zRange:" << m_zRangeMm
<< m_zRangeMm / ::discretesInRage
- << "pos steps:" << pixels->counters.encoderPosition;
+ << "\tpos steps:" << pixels->counters.encoderPosition
+ << "\tcollected:" << m_calibrationPixels.size();
m_isMoving = true;
- collectedInPos = 0;
emit moveMm(m_zRangeMm / ::discretesInRage);
// m_stand->moveMm(m_zRangeMm / ::discretesInRage);
} else {
@@ -723,7 +726,12 @@ void VeyeIMX287m::calcPixelsLoop(std::stop_token stopToken)
// m_stand->moveMm(-m_zRangeMm);
m_isCalibrating = false;
// m_stand.reset();
- const auto tmp = m_calibrationPixels;
+ // const auto tmp = m_calibrationPixels;
+ std::vector<std::shared_ptr<Pixels>> tmp;
+
+ for (const auto &[e, p] : m_calibrationPixels) {
+ tmp.insert(tmp.begin(), p.cbegin(), p.cend());
+ }
// dumpCalibrationPixels(m_calibrationPixels);
dumpCalibrationPixels(tmp, DumpFormat::Binary);
m_calibrationPixels.clear();
@@ -809,11 +817,13 @@ bool VeyeIMX287m::dequeueImageBuffer(size_t &imageIndex)
if (buf.index < 0 || buf.index >= BUFFER_COUNT) {
std::cerr << "invalid buffer index: " << buf.index << std::endl;
+ m_rawBuffers[imageIndex].sequence = std::numeric_limits<buffer::sequence_t>::max();
return false;
}
}
imageIndex = buf.index;
+ m_rawBuffers[imageIndex].sequence = buf.sequence;
// const auto &image = m_rawBuffers[buf.index].image;
// image->height = img_height;
@@ -835,6 +845,7 @@ bool VeyeIMX287m::dequeueImageBuffer(size_t &imageIndex)
if (ret != 0) {
std::cerr << "ioctl(VIDIOC_QBUF) failed: " << errno << " ("
<< strerror(errno) << ")" << std::endl;
+ m_rawBuffers[imageIndex].sequence = std::numeric_limits<buffer::sequence_t>::max();
return false;
}
diff --git a/src/camera/veyeimx287m.h b/src/camera/veyeimx287m.h
index bdc57d9..d084788 100644
--- a/src/camera/veyeimx287m.h
+++ b/src/camera/veyeimx287m.h
@@ -136,6 +136,9 @@ private:
struct buffer
{
void *mem{nullptr};
+ using sequence_t = decltype(v4l2_buffer::sequence);
+ // TODO: think about optional/expected
+ sequence_t sequence{std::numeric_limits<sequence_t>::max()};
// std::shared_ptr<Image> image{std::make_shared<Image>()};
};
std::vector<buffer> m_rawBuffers;
@@ -159,7 +162,7 @@ private:
// std::jthread m_getThreads[4];
// TODO: sync all loops somehow to guarantee frames order
std::jthread m_rotateThreads[2];
- std::jthread m_calcPixelsThreads[2];
+ std::jthread m_calcPixelsThreads[1];
std::mutex m_lastImageMtx;
std::shared_ptr<Image> m_lastProcessedImage{};
@@ -170,7 +173,9 @@ private:
// TODO: re-organize this logic
bool m_isCalibrating{false};
bool m_ignoreFrames{false};
- std::vector<std::shared_ptr<Pixels>> m_calibrationPixels;
+ // std::vector<std::shared_ptr<Pixels>> m_calibrationPixels;
+ std::unordered_map<decltype(Counters::encoderPosition), 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 6770f5f..b950ede 100644
--- a/src/constants.h
+++ b/src/constants.h
@@ -39,4 +39,5 @@ const QString user{"radxa"};
const QString dumpsRoot{QStringLiteral("/home/%1/dumps").arg(user)};
-constexpr double debugZRange{5.0};
+// constexpr double debugZRange{10.0};
+constexpr double debugZRange{hardcodedZRangeMm};
diff --git a/src/main.cpp b/src/main.cpp
index 2d86dac..c717c7e 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -95,6 +95,36 @@ int main(int argc, char *argv[])
qDebug() << "size of raw profile" << sizeof(Pixels);
+ QElapsedTimer t;
+ t.start();
+
+ // FIXME: don't use one var for everything
+ int ret;
+
+ auto cameras = VeyeIMX287m::search();
+
+ if (cameras.empty()) {
+ std::cerr << "No cameras were identified on the system." << std::endl;
+
+ return EXIT_FAILURE;
+ }
+
+ auto camera = cameras.at(0);
+
+ std::cout << "connect everything" << std::endl;
+
+ for (auto &i : initializers)
+ i.waitForFinished();
+ std::cout << "loaded calibration tables" << std::endl;
+
+ if (!camera->startStream()) {
+ return EXIT_FAILURE;
+ }
+
+ // 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);
+
// Pixels p;
// p.counters.encoderPosition = 123;
// if (!p.save("/tmp/tmp.pixels")) {
@@ -115,7 +145,7 @@ int main(int argc, char *argv[])
if (!openCalibrationTable(QStringLiteral("/home/%1/dumps/binz.calibration_table")
.arg(user),
// "/tmp/binz.calibration_table",
- ::calibrationTableZ)) {
+ scanner->calibrationTableZ())) {
exit(EXIT_FAILURE);
}
});
@@ -124,7 +154,7 @@ int main(int argc, char *argv[])
if (!openCalibrationTable(QStringLiteral("/home/%1/dumps/binx.calibration_table")
.arg(user),
// "/tmp/binx.calibration_table",
- ::calibrationTableX)) {
+ scanner->calibrationTableX())) {
exit(EXIT_FAILURE);
}
});
@@ -136,12 +166,11 @@ int main(int argc, char *argv[])
// qDebug() << "height" << calibrationColumnHeight;
auto filteredRawProfiles = filter(std::move(rawProfiles));
- qDebug() << "filtered x-profiles count is"
- << filteredRawProfiles.count();
+ qDebug() << "filtered x-profiles count is" << filteredRawProfiles.count();
- ::calibrationTableX = calibrateX(std::move(filteredRawProfiles));
+ calibrateX(std::move(filteredRawProfiles), scanner->calibrationTableX());
- interpolate(::calibrationTableX);
+ interpolate(scanner->calibrationTableX());
}
// load binary calibration dumps and calibrate
@@ -154,79 +183,53 @@ int main(int argc, char *argv[])
return EXIT_FAILURE;
}
+ std::sort(rawProfiles.begin(), rawProfiles.end(), [](const auto &a, const auto &b) {
+ return a.counters.encoderPosition < b.counters.encoderPosition;
+ });
auto filteredRawProfiles = filter(std::move(rawProfiles));
- qDebug() << "filtered z-profiles count is"
- << filteredRawProfiles.count();
+ qDebug() << "filtered z-profiles count is" << filteredRawProfiles.count();
- ::calibrationTableZ = calibrateZ(std::move(filteredRawProfiles),
- requested_params.stepsPerMm);
+ if (!calibrateZ(std::move(filteredRawProfiles),
+ requested_params.stepsPerMm,
+ scanner->calibrationTableZ())) {
+ qCritical() << "Z calibration failed, exiting";
+ exit(EXIT_FAILURE);
+ }
// DEBUG
- ::calibrationTableX = CalibrationTablePtr{new CalibrationTable{{0}}};
- memset(::calibrationTableX.get(), 0, sizeof(CalibrationTable));
- interpolate(::calibrationTableZ);
+ interpolate(scanner->calibrationTableZ());
- if (!dump(::calibrationTableZ,
+ if (!dump(scanner->calibrationTableZ(),
QStringLiteral("/home/%1/dumps/binz.calibration_table").arg(user))) {
qApp->exit(EXIT_FAILURE);
}
}
- qDebug()
- << "--------------------------------------------------------";
+ qDebug() << "--------------------------------------------------------";
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));
- qDebug() << "filtered x-profiles count is"
- << filteredRawProfiles.count();
+ qDebug() << "filtered x-profiles count is" << filteredRawProfiles.count();
- ::calibrationTableX = calibrateX(std::move(filteredRawProfiles));
+ if (!calibrateX(std::move(filteredRawProfiles), scanner->calibrationTableX())) {
+ qCritical() << "X calibration failed, exiting";
+ exit(EXIT_FAILURE);
+ }
- interpolate(::calibrationTableX);
+ interpolate(scanner->calibrationTableX());
- if (!dump(::calibrationTableX,
+ if (!dump(scanner->calibrationTableX(),
QStringLiteral("/home/%1/dumps/binx.calibration_table").arg(user))) {
qApp->exit(EXIT_FAILURE);
}
}
}
+ // exit(EXIT_SUCCESS);
}
- // exit(EXIT_SUCCESS);
-
- QElapsedTimer t;
- t.start();
-
- // FIXME: don't use one var for everything
- int ret;
-
- auto cameras = VeyeIMX287m::search();
-
- if (cameras.empty()) {
- std::cerr << "No cameras were identified on the system." << std::endl;
-
- return EXIT_FAILURE;
- }
-
- auto camera = cameras.at(0);
-
- std::cout << "connect everything" << std::endl;
-
- for (auto &i : initializers)
- i.waitForFinished();
- std::cout << "loaded calibration tables" << std::endl;
-
- if (!camera->startStream()) {
- return EXIT_FAILURE;
- }
-
- // 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();
@@ -242,7 +245,7 @@ int main(int argc, char *argv[])
// if (!::calibrationTableZ || !::calibrationTableX)
// return QHttpServerResponse::StatusCode::ServiceUnavailable;
- const Profile profile{::pixels, ::calibrationTableZ, ::calibrationTableX};
+ const Profile profile{::pixels, scanner->calibrationTableZ(), scanner->calibrationTableX()};
const QJsonObject json{{"profile", QJsonObject(profile)}};
// qDebug() << "profile:" << QJsonDocument(json).toJson();
diff --git a/src/profile.cpp b/src/profile.cpp
index 3ed11ba..101ecf3 100644
--- a/src/profile.cpp
+++ b/src/profile.cpp
@@ -86,7 +86,9 @@ Profile::Profile(
continue;
}
- const auto x = (leftMmX * (1 - fract) + rightMmX * fract);
+ // const auto x = (leftMmX * (1 - fract) + rightMmX * fract);
+ // TODO: revert this debug shit
+ const auto x = static_cast<double>(i) - img_width / 2;
m_pointsMm.at(i) = {x, z};
diff --git a/src/protocols/httpserver.cpp b/src/protocols/httpserver.cpp
index 3ca1f5c..219bd76 100644
--- a/src/protocols/httpserver.cpp
+++ b/src/protocols/httpserver.cpp
@@ -185,10 +185,19 @@ QHttpServerResponse HttpServer::GET_profile()
{
const auto image = m_scanner->camera()->getImage();
const auto pixels = image->sharedPixels();
- const auto profile = Profile{*pixels, ::calibrationTableZ, ::calibrationTableX};
+ const auto profile = Profile{*pixels,
+ m_scanner->calibrationTableZ(),
+ m_scanner->calibrationTableX()};
const QJsonObject json{profile};
+ static bool done{false};
+
+ if (!done) {
+ qDebug() << json;
+ done = true;
+ }
+
return QHttpServerResponse{QJsonDocument{json}.toJson()};
}
diff --git a/src/scanner.cpp b/src/scanner.cpp
index 9012769..4045121 100644
--- a/src/scanner.cpp
+++ b/src/scanner.cpp
@@ -8,6 +8,8 @@ Scanner::Scanner(std::shared_ptr<ICamera> camera, std::vector<std::shared_ptr<IP
, m_calibrationTableZ{new CalibrationTable{}}
{
// m_protocols.push_back()
+ memset(m_calibrationTableX.get(), 0, sizeof(CalibrationTable));
+ memset(m_calibrationTableZ.get(), 0, sizeof(CalibrationTable));
}
bool Scanner::startAllProtocols()