#include "profile.h" #include #include #include Profile::Profile( const Pixels& pixels, const CalibrationTablePtr calibrationTableZ, const CalibrationTablePtr calibrationTableX) : m_counters(pixels.counters) { if (!calibrationTableZ || !calibrationTableX) { std::cerr << __func__ << ": got invalid calibration tables" << std::endl; return; } static bool done{false}; if (!done) { for (size_t i = 9471; i < 9472; 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; } std::cout << std::endl; } } for (size_t i = 0; i < img_width; ++i) { try { const auto& pixel = pixels.pixels[i]; const auto pixelDiscrete = pixel * discretesInRage / img_height; if (Q_UNLIKELY(pixel >= sizeof(CalibrationColumn) / sizeof(float))) { qWarning() << "got invalid calibration pixel at" << i << ":" << pixel; m_counters = {}; m_pointsMm = {QPointF{std::nan(""), std::nan("")}}; return; } if (Q_UNLIKELY(pixel == sizeof(CalibrationColumn) - 1)) { qDebug() << "Profile: got edge value"; const auto& z = calibrationTableZ->at(i).at(pixelDiscrete); if (qFuzzyIsNull(z) || std::isnan(z)) { m_pointsMm.at(i) = {std::nan(""), std::nan("")}; continue; } const auto& x = calibrationTableX->at(i).at(pixelDiscrete); m_pointsMm.at(i) = {x, z}; continue; } const auto& leftMmZ = calibrationTableZ->at(i).at( size_t(pixelDiscrete)); const auto& rightMmZ = calibrationTableZ->at(i).at( size_t(pixelDiscrete) + 1); const auto& leftMmX = calibrationTableX->at(i).at( size_t(pixelDiscrete)); const auto& rightMmX = calibrationTableX->at(i).at( size_t(pixelDiscrete) + 1); const auto& fract = pixelDiscrete - long(pixelDiscrete); const auto z = (leftMmZ * (1 - fract) + rightMmZ * fract); // 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; m_pointsMm.at(i) = {std::nan(""), std::nan("")}; continue; } const auto x = (leftMmX * (1 - fract) + rightMmX * fract); m_pointsMm.at(i) = {x, z}; if (!done) { qDebug() << "got these values\t" << pixels.pixels[i] << pixelDiscrete << m_pointsMm[i] << leftMmZ << rightMmZ << leftMmX << rightMmX; } } catch (const std::out_of_range& ex) { qWarning() << "out of range exception:" << ex.what(); qWarning() << "i:" << i; // << "pixels[i]" << pixels.pixels[i]; m_counters = {}; m_pointsMm = {QPointF{std::nan(""), std::nan("")}}; return; } catch (const std::exception& ex) { qWarning() << "exception:" << ex.what(); qWarning() << "i:" << i << "pixels[i]" << pixels.pixels[i]; m_counters = {}; m_pointsMm = {QPointF{std::nan(""), std::nan("")}}; return; } catch (...) { qWarning() << "unknown exception"; m_counters = {}; m_pointsMm = {QPointF{std::nan(""), std::nan("")}}; return; } } done = true; // static bool printOnce = [&]() -> bool { // for (size_t i = 0; i < m_pointsMm.size(); ++i) { // qDebug() << '\t' << pixels.pixels[i] << m_pointsMm[i]; // } // return true; // }(); } const Counters& Profile::counters() const { return m_counters; } const Profile::PointsMm& Profile::pointsMm() const { return m_pointsMm; } Profile::operator const QJsonObject() const { QJsonObject counters{ {"timestampUs", qint64(m_counters.timestampUs)}, {"measurementCounter", qint64(m_counters.measurementCounter)}, {"encoderPosition", qint64(m_counters.encoderPosition)}, }; QJsonArray jsonPoints; for (const auto& p : m_pointsMm) { jsonPoints << QJsonArray{p.x(), p.y()}; } return {{"counters", counters}, {"pointsMm", jsonPoints}}; }