// cpp and linux #include #include #include #include #include #include #include #include #include // qt #include #include #include #include #include #include #include #include #include #include #include #include #include // orpheus #include "LibCamera.h" #include "calibration.h" #include "camera/veyeimx287m.h" #include "dumps.h" #include "imagealgos.h" #include "printerclient.h" #include "profile.h" #include "protocols/httpserver.h" #include "scanner.h" // #include "rapidjson/document.h" #include "rapidjson/stringbuffer.h" #include "rapidjson/writer.h" 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; #define try_apply_config() \ if (!applyConfig(config)) { \ camera->release(); \ cm->stop(); \ \ return EXIT_FAILURE; \ } ScanningModeFlags scanningModeFlags{ScanningModeFlags::None}; QElapsedTimer calibrationTimer; extern volatile int32_t positionSteps; requested_params_t requested_params; namespace { Pixels pixels; std::vector calibrationPixels; QMutex calibrationPixelsMutex; } // namespace using namespace std::chrono_literals; auto printPixels = [](const auto &pixels) { for (size_t i = (img_width - 10) / 2; i < img_width - ((img_width - 10) / 2); ++i) { std::cout << pixels[i] << " "; } std::cout << std::endl; }; int main(int argc, char *argv[]) { auto sigHandler = [](int s) { std::cout << "got signal " << s << std::endl; std::signal(s, SIG_DFL); }; qDebug() << "sizeof(Pixels):" << sizeof(Pixels); std::signal(SIGINT, sigHandler); std::signal(SIGTERM, sigHandler); QCoreApplication app(argc, argv); QList> initializers; qDebug() << "size of raw profile" << sizeof(Pixels); // 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 (false) { initializers << QtConcurrent::run([&]() { if (!openCalibrationTable(QStringLiteral("/home/%1/dumps/binz.calibration_table") .arg(user), // "/tmp/binz.calibration_table", ::calibrationTableZ)) { exit(EXIT_FAILURE); } }); initializers << QtConcurrent::run([&]() { if (!openCalibrationTable(QStringLiteral("/home/%1/dumps/binx.calibration_table") .arg(user), // "/tmp/binx.calibration_table", ::calibrationTableX)) { exit(EXIT_FAILURE); } }); } if (false) { auto rawProfiles = openDump(QStringLiteral("/home/%1/dumps/binx").arg(user)); qDebug() << "raw x-profiles count is" << rawProfiles.size(); // qDebug() << "height" << calibrationColumnHeight; auto filteredRawProfiles = filter(std::move(rawProfiles)); qDebug() << "filtered x-profiles count is" << filteredRawProfiles.count(); ::calibrationTableX = calibrateX(std::move(filteredRawProfiles)); interpolate(::calibrationTableX); } // load binary calibration dumps and calibrate if (true) { if (true) { 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, QStringLiteral("/home/%1/dumps/binz.calibration_table").arg(user))) { qApp->exit(EXIT_FAILURE); } } 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(); ::calibrationTableX = calibrateX(std::move(filteredRawProfiles)); interpolate(::calibrationTableX); if (!dump(::calibrationTableX, QStringLiteral("/home/%1/dumps/binx.calibration_table").arg(user))) { qApp->exit(EXIT_FAILURE); } } } } // 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(camera); auto httpServer = std::make_shared(scanner); scanner->startAllProtocols(); httpServer->start(); auto stand = std::make_shared(QHostAddress{"192.168.18.248"}, 80, 1600); QHttpServer qHttpServer; qHttpServer.route("/v1/profile", [&]() -> QHttpServerResponse { // std::cout << "http: profile" << std::endl; // return QHttpServerResponse::StatusCode::ServiceUnavailable; std::lock_guard lg(pgm_image_mtx); // if (!::calibrationTableZ || !::calibrationTableX) // return QHttpServerResponse::StatusCode::ServiceUnavailable; const Profile profile{::pixels, ::calibrationTableZ, ::calibrationTableX}; const QJsonObject json{{"profile", QJsonObject(profile)}}; // qDebug() << "profile:" << QJsonDocument(json).toJson(); return QHttpServerResponse(QJsonDocument(json).toJson()); }); qHttpServer .route("/v1/commands/resetEncoder", [&](const QHttpServerRequest &request) -> QHttpServerResponse { std::cout << "http: resetEncoder" << std::endl; if (request.method() != QHttpServerRequest::Method::Post) { return QHttpServerResponse::StatusCode::NotFound; } qDebug() << "reset encoder"; positionSteps = 0; return QHttpServerResponse::StatusCode::Ok; }); qHttpServer .route("/v1/commands/startCalibration", [&](const QHttpServerRequest &request) -> QHttpServerResponse { std::cout << "http: startCalibration" << std::endl; if (request.method() != QHttpServerRequest::Method::Post) { return QHttpServerResponse::StatusCode::NotFound; } qDebug() << "start calibration"; // 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; }); qHttpServer .route("/v1/commands/gCode", [&](const QHttpServerRequest &request) -> QHttpServerResponse { std::cout << "http: gCode" << std::endl; if (request.method() != QHttpServerRequest::Method::Post) { return QHttpServerResponse::StatusCode::NotFound; } const auto command = request.body(); qDebug() << "send gCode:" << command; // WARNING: tmp logic auto distanceMm = command.split(' ').at(1); distanceMm.remove(0, 1); // printerClient.sendCommand(command); stand->moveMm(distanceMm.toInt()); return QHttpServerResponse::StatusCode::Ok; }); qDebug() << "listen: " << qHttpServer.listen(QHostAddress::Any, 8081); //////////////////////////////////////////////////////////////////////////// std::clog << std::flush; std::cerr << std::flush; std::cout << "ok for now" << std::endl << std::flush; auto result = app.exec(); return result; }