diff options
| author | Nikita Kostovsky <luntik2012@gmail.com> | 2024-12-02 19:42:15 +0100 |
|---|---|---|
| committer | Nikita Kostovsky <luntik2012@gmail.com> | 2024-12-02 19:42:15 +0100 |
| commit | 5e6df9ccf832d166bd231297b521394beec1fec6 (patch) | |
| tree | 73b38c20f836de769fbe0c5304b20d5096f985bf | |
| parent | 53979d9d26c5bb51e86e70eb9c3a998bc50f713c (diff) | |
line search
| -rw-r--r-- | CMakeLists.txt | 9 | ||||
| -rw-r--r-- | LibCamera.cpp | 456 | ||||
| -rw-r--r-- | LibCamera.h | 131 | ||||
| -rw-r--r-- | fuck_intel.h | 9 | ||||
| -rw-r--r-- | genetic_algos.h | 2 | ||||
| -rw-r--r-- | imagealgos.cpp | 228 | ||||
| -rw-r--r-- | imagealgos.h | 10 | ||||
| -rw-r--r-- | main.cpp | 430 |
8 files changed, 910 insertions, 365 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 83ef86c..e07bf77 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,7 +7,7 @@ include_guard(GLOBAL) set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_AUTOMOC ON) -set(CMAKE_AUTORCC ON) +set(CMAKE_AUTORCC OFF) set(CMAKE_SYSTEM_NAME Linux) set(CMAKE_SYSTEM_PROCESSOR arm) @@ -32,6 +32,7 @@ set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS}") # ...../rpi-sysroot/usr/lib/qt6/libexec/moc: error while loading shared libraries: # libpcre2-16.so.0: cannot open shared object file: No such file or directory # +# export this path for qtcreator: # LD_LIBRARY_PATH=/home/nikita/rpi/rpi-sysroot/usr/lib/aarch64-linux-gnu/:$LD_LIBRARY_PATH set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) @@ -59,6 +60,8 @@ set(CMAKE_CXX20_EXTENSION_COMPILE_OPTION "-std:c++latest") find_package(Qt6 6.4 REQUIRED COMPONENTS Quick HttpServer SerialPort) +find_package(TBB REQUIRED) + qt_standard_project_setup(REQUIRES 6.4) include_directories(. "${CAMERA_INCLUDE_DIRS}") @@ -82,6 +85,7 @@ qt_add_executable(apporpheus rotaryencoder.cpp printerclient.h printerclient.cpp + fuck_intel.h ) target_link_libraries(app${PROJECT_NAME} PRIVATE @@ -90,6 +94,7 @@ target_link_libraries(app${PROJECT_NAME} Qt6::HttpServer Qt6::SerialPort wiringPi + TBB::tbb ) include(GNUInstallDirs) @@ -107,4 +112,4 @@ endif() # add_compile_options(-Wall -Wextra -Wpedantic) -add_compile_options(-Ofast -fno-unroll-loops) +add_compile_options(-Ofast -fno-unroll-loops -Wall) diff --git a/LibCamera.cpp b/LibCamera.cpp index 945a8ae..1e68228 100644 --- a/LibCamera.cpp +++ b/LibCamera.cpp @@ -1,267 +1,267 @@ -#include "LibCamera.h"
+// #include "LibCamera.h"
-using namespace std::placeholders;
+// using namespace std::placeholders;
-int LibCamera::initCamera() {
- int ret;
- cm = std::make_unique<CameraManager>();
- ret = cm->start();
- if (ret){
- std::cout << "Failed to start camera manager: "
- << ret << std::endl;
- return ret;
- }
- cameraId = cm->cameras()[0]->id();
- camera_ = cm->get(cameraId);
- if (!camera_) {
- std::cerr << "Camera " << cameraId << " not found" << std::endl;
- return 1;
- }
+// int LibCamera::initCamera() {
+// int ret;
+// cm = std::make_unique<CameraManager>();
+// ret = cm->start();
+// if (ret){
+// std::cout << "Failed to start camera manager: "
+// << ret << std::endl;
+// return ret;
+// }
+// cameraId = cm->cameras()[0]->id();
+// camera_ = cm->get(cameraId);
+// if (!camera_) {
+// std::cerr << "Camera " << cameraId << " not found" << std::endl;
+// return 1;
+// }
- if (camera_->acquire()) {
- std::cerr << "Failed to acquire camera " << cameraId
- << std::endl;
- return 1;
- }
- camera_acquired_ = true;
- return 0;
-}
+// if (camera_->acquire()) {
+// std::cerr << "Failed to acquire camera " << cameraId
+// << std::endl;
+// return 1;
+// }
+// camera_acquired_ = true;
+// return 0;
+// }
-char * LibCamera::getCameraId(){
- return cameraId.data();
-}
+// char * LibCamera::getCameraId(){
+// return cameraId.data();
+// }
-void LibCamera::configureStill(int width, int height, PixelFormat format, int buffercount, int rotation) {
- printf("Configuring still capture...\n");
- config_ = camera_->generateConfiguration({ StreamRole::StillCapture });
- if (width && height) {
- libcamera::Size size(width, height);
- config_->at(0).size = size;
- }
- config_->at(0).pixelFormat = format;
- if (buffercount)
- config_->at(0).bufferCount = buffercount;
- Transform transform = Transform::Identity;
- bool ok;
- Transform rot = transformFromRotation(rotation, &ok);
- if (!ok)
- throw std::runtime_error("illegal rotation value, Please use 0 or 180");
- transform = rot * transform;
- if (!!(transform & Transform::Transpose))
- throw std::runtime_error("transforms requiring transpose not supported");
- // FIXME: update
- // config_->transform = transform;
+// void LibCamera::configureStill(int width, int height, PixelFormat format, int buffercount, int rotation) {
+// printf("Configuring still capture...\n");
+// config_ = camera_->generateConfiguration({ StreamRole::StillCapture });
+// if (width && height) {
+// libcamera::Size size(width, height);
+// config_->at(0).size = size;
+// }
+// config_->at(0).pixelFormat = format;
+// if (buffercount)
+// config_->at(0).bufferCount = buffercount;
+// Transform transform = Transform::Identity;
+// bool ok;
+// Transform rot = transformFromRotation(rotation, &ok);
+// if (!ok)
+// throw std::runtime_error("illegal rotation value, Please use 0 or 180");
+// transform = rot * transform;
+// if (!!(transform & Transform::Transpose))
+// throw std::runtime_error("transforms requiring transpose not supported");
+// // FIXME: update
+// // config_->transform = transform;
- CameraConfiguration::Status validation = config_->validate();
- if (validation == CameraConfiguration::Invalid)
- throw std::runtime_error("failed to valid stream configurations");
- else if (validation == CameraConfiguration::Adjusted)
- std::cout << "Stream configuration adjusted" << std::endl;
+// CameraConfiguration::Status validation = config_->validate();
+// if (validation == CameraConfiguration::Invalid)
+// throw std::runtime_error("failed to valid stream configurations");
+// else if (validation == CameraConfiguration::Adjusted)
+// std::cout << "Stream configuration adjusted" << std::endl;
- printf("Still capture setup complete\n");
-}
+// printf("Still capture setup complete\n");
+// }
-int LibCamera::startCamera() {
- int ret;
- ret = camera_->configure(config_.get());
- if (ret < 0) {
- std::cout << "Failed to configure camera" << std::endl;
- return ret;
- }
+// int LibCamera::startCamera() {
+// int ret;
+// ret = camera_->configure(config_.get());
+// if (ret < 0) {
+// std::cout << "Failed to configure camera" << std::endl;
+// return ret;
+// }
- camera_->requestCompleted.connect(this, &LibCamera::requestComplete);
+// camera_->requestCompleted.connect(this, &LibCamera::requestComplete);
- allocator_ = std::make_unique<FrameBufferAllocator>(camera_);
+// allocator_ = std::make_unique<FrameBufferAllocator>(camera_);
- return startCapture();
-}
+// return startCapture();
+// }
-int LibCamera::startCapture() {
- int ret;
- unsigned int nbuffers = UINT_MAX;
- for (StreamConfiguration &cfg : *config_) {
- ret = allocator_->allocate(cfg.stream());
- if (ret < 0) {
- std::cerr << "Can't allocate buffers" << std::endl;
- return -ENOMEM;
- }
+// int LibCamera::startCapture() {
+// int ret;
+// unsigned int nbuffers = UINT_MAX;
+// for (StreamConfiguration &cfg : *config_) {
+// ret = allocator_->allocate(cfg.stream());
+// if (ret < 0) {
+// std::cerr << "Can't allocate buffers" << std::endl;
+// return -ENOMEM;
+// }
- unsigned int allocated = allocator_->buffers(cfg.stream()).size();
- nbuffers = std::min(nbuffers, allocated);
- }
+// unsigned int allocated = allocator_->buffers(cfg.stream()).size();
+// nbuffers = std::min(nbuffers, allocated);
+// }
- for (unsigned int i = 0; i < nbuffers; i++) {
- std::unique_ptr<Request> request = camera_->createRequest();
- if (!request) {
- std::cerr << "Can't create request" << std::endl;
- return -ENOMEM;
- }
+// for (unsigned int i = 0; i < nbuffers; i++) {
+// std::unique_ptr<Request> request = camera_->createRequest();
+// if (!request) {
+// std::cerr << "Can't create request" << std::endl;
+// return -ENOMEM;
+// }
- for (StreamConfiguration &cfg : *config_) {
- Stream *stream = cfg.stream();
- const std::vector<std::unique_ptr<FrameBuffer>> &buffers =
- allocator_->buffers(stream);
- const std::unique_ptr<FrameBuffer> &buffer = buffers[i];
+// for (StreamConfiguration &cfg : *config_) {
+// Stream *stream = cfg.stream();
+// const std::vector<std::unique_ptr<FrameBuffer>> &buffers =
+// allocator_->buffers(stream);
+// const std::unique_ptr<FrameBuffer> &buffer = buffers[i];
- ret = request->addBuffer(stream, buffer.get());
- if (ret < 0) {
- std::cerr << "Can't set buffer for request"
- << std::endl;
- return ret;
- }
- for (const FrameBuffer::Plane &plane : buffer->planes()) {
- void *memory = mmap(NULL, plane.length, PROT_READ, MAP_SHARED,
- plane.fd.get(), 0);
- mappedBuffers_[plane.fd.get()] =
- std::make_pair(memory, plane.length);
- }
- }
+// ret = request->addBuffer(stream, buffer.get());
+// if (ret < 0) {
+// std::cerr << "Can't set buffer for request"
+// << std::endl;
+// return ret;
+// }
+// for (const FrameBuffer::Plane &plane : buffer->planes()) {
+// void *memory = mmap(NULL, plane.length, PROT_READ, MAP_SHARED,
+// plane.fd.get(), 0);
+// mappedBuffers_[plane.fd.get()] =
+// std::make_pair(memory, plane.length);
+// }
+// }
- requests_.push_back(std::move(request));
- }
+// requests_.push_back(std::move(request));
+// }
- ret = camera_->start(&this->controls_);
- // ret = camera_->start();
- if (ret) {
- std::cout << "Failed to start capture" << std::endl;
- return ret;
- }
- controls_.clear();
- camera_started_ = true;
- for (std::unique_ptr<Request> &request : requests_) {
- ret = queueRequest(request.get());
- if (ret < 0) {
- std::cerr << "Can't queue request" << std::endl;
- camera_->stop();
- return ret;
- }
- }
- viewfinder_stream_ = config_->at(0).stream();
- return 0;
-}
+// ret = camera_->start(&this->controls_);
+// // ret = camera_->start();
+// if (ret) {
+// std::cout << "Failed to start capture" << std::endl;
+// return ret;
+// }
+// controls_.clear();
+// camera_started_ = true;
+// for (std::unique_ptr<Request> &request : requests_) {
+// ret = queueRequest(request.get());
+// if (ret < 0) {
+// std::cerr << "Can't queue request" << std::endl;
+// camera_->stop();
+// return ret;
+// }
+// }
+// viewfinder_stream_ = config_->at(0).stream();
+// return 0;
+// }
-void LibCamera::StreamDimensions(Stream const *stream, uint32_t *w, uint32_t *h, uint32_t *stride) const
-{
- StreamConfiguration const &cfg = stream->configuration();
- if (w)
- *w = cfg.size.width;
- if (h)
- *h = cfg.size.height;
- if (stride)
- *stride = cfg.stride;
-}
+// void LibCamera::StreamDimensions(Stream const *stream, uint32_t *w, uint32_t *h, uint32_t *stride) const
+// {
+// StreamConfiguration const &cfg = stream->configuration();
+// if (w)
+// *w = cfg.size.width;
+// if (h)
+// *h = cfg.size.height;
+// if (stride)
+// *stride = cfg.stride;
+// }
-Stream *LibCamera::VideoStream(uint32_t *w, uint32_t *h, uint32_t *stride) const
-{
- StreamDimensions(viewfinder_stream_, w, h, stride);
- return viewfinder_stream_;
-}
+// Stream *LibCamera::VideoStream(uint32_t *w, uint32_t *h, uint32_t *stride) const
+// {
+// StreamDimensions(viewfinder_stream_, w, h, stride);
+// return viewfinder_stream_;
+// }
-int LibCamera::queueRequest(Request *request) {
- std::lock_guard<std::mutex> stop_lock(camera_stop_mutex_);
- if (!camera_started_)
- return -1;
- {
- std::lock_guard<std::mutex> lock(control_mutex_);
- request->controls() = std::move(controls_);
- }
- return camera_->queueRequest(request);
-}
+// int LibCamera::queueRequest(Request *request) {
+// std::lock_guard<std::mutex> stop_lock(camera_stop_mutex_);
+// if (!camera_started_)
+// return -1;
+// {
+// std::lock_guard<std::mutex> lock(control_mutex_);
+// request->controls() = std::move(controls_);
+// }
+// return camera_->queueRequest(request);
+// }
-void LibCamera::requestComplete(Request *request) {
- if (request->status() == Request::RequestCancelled)
- return;
- processRequest(request);
-}
+// void LibCamera::requestComplete(Request *request) {
+// if (request->status() == Request::RequestCancelled)
+// return;
+// processRequest(request);
+// }
-void LibCamera::processRequest(Request *request) {
- requestQueue.push(request);
-}
+// void LibCamera::processRequest(Request *request) {
+// requestQueue.push(request);
+// }
-void LibCamera::returnFrameBuffer(LibcameraOutData frameData) {
- uint64_t request = frameData.request;
- Request * req = (Request *)request;
- req->reuse(Request::ReuseBuffers);
- queueRequest(req);
-}
+// void LibCamera::returnFrameBuffer(LibcameraOutData frameData) {
+// uint64_t request = frameData.request;
+// Request * req = (Request *)request;
+// req->reuse(Request::ReuseBuffers);
+// queueRequest(req);
+// }
-bool LibCamera::readFrame(LibcameraOutData *frameData){
- std::lock_guard<std::mutex> lock(free_requests_mutex_);
- // int w, h, stride;
- if (!requestQueue.empty()){
- Request *request = this->requestQueue.front();
+// bool LibCamera::readFrame(LibcameraOutData *frameData){
+// std::lock_guard<std::mutex> lock(free_requests_mutex_);
+// // int w, h, stride;
+// if (!requestQueue.empty()){
+// Request *request = this->requestQueue.front();
- const Request::BufferMap &buffers = request->buffers();
- for (auto it = buffers.begin(); it != buffers.end(); ++it) {
- FrameBuffer *buffer = it->second;
- for (unsigned int i = 0; i < buffer->planes().size(); ++i) {
- const FrameBuffer::Plane &plane = buffer->planes()[i];
- const FrameMetadata::Plane &meta = buffer->metadata().planes()[i];
+// const Request::BufferMap &buffers = request->buffers();
+// for (auto it = buffers.begin(); it != buffers.end(); ++it) {
+// FrameBuffer *buffer = it->second;
+// for (unsigned int i = 0; i < buffer->planes().size(); ++i) {
+// const FrameBuffer::Plane &plane = buffer->planes()[i];
+// const FrameMetadata::Plane &meta = buffer->metadata().planes()[i];
- void *data = mappedBuffers_[plane.fd.get()].first;
- int length = std::min(meta.bytesused, plane.length);
+// void *data = mappedBuffers_[plane.fd.get()].first;
+// int length = std::min(meta.bytesused, plane.length);
- frameData->size = length;
- frameData->imageData = (uint8_t *)data;
- }
- }
- this->requestQueue.pop();
- frameData->request = (uint64_t)request;
- return true;
- } else {
- Request *request = nullptr;
- frameData->request = (uint64_t)request;
- return false;
- }
-}
+// frameData->size = length;
+// frameData->imageData = (uint8_t *)data;
+// }
+// }
+// this->requestQueue.pop();
+// frameData->request = (uint64_t)request;
+// return true;
+// } else {
+// Request *request = nullptr;
+// frameData->request = (uint64_t)request;
+// return false;
+// }
+// }
-void LibCamera::set(ControlList controls){
- std::lock_guard<std::mutex> lock(control_mutex_);
- this->controls_ = std::move(controls);
-}
+// void LibCamera::set(ControlList controls){
+// std::lock_guard<std::mutex> lock(control_mutex_);
+// this->controls_ = std::move(controls);
+// }
-int LibCamera::resetCamera(int width, int height, PixelFormat format, int buffercount, int rotation) {
- stopCamera();
- configureStill(width, height, format, buffercount, rotation);
- return startCamera();
-}
+// int LibCamera::resetCamera(int width, int height, PixelFormat format, int buffercount, int rotation) {
+// stopCamera();
+// configureStill(width, height, format, buffercount, rotation);
+// return startCamera();
+// }
-void LibCamera::stopCamera() {
- if (camera_){
- {
- std::lock_guard<std::mutex> lock(camera_stop_mutex_);
- if (camera_started_){
- if (camera_->stop())
- throw std::runtime_error("failed to stop camera");
- camera_started_ = false;
- }
- }
- camera_->requestCompleted.disconnect(this, &LibCamera::requestComplete);
- }
- while (!requestQueue.empty())
- requestQueue.pop();
+// void LibCamera::stopCamera() {
+// if (camera_){
+// {
+// std::lock_guard<std::mutex> lock(camera_stop_mutex_);
+// if (camera_started_){
+// if (camera_->stop())
+// throw std::runtime_error("failed to stop camera");
+// camera_started_ = false;
+// }
+// }
+// camera_->requestCompleted.disconnect(this, &LibCamera::requestComplete);
+// }
+// while (!requestQueue.empty())
+// requestQueue.pop();
- for (auto &iter : mappedBuffers_)
- {
- std::pair<void *, unsigned int> pair_ = iter.second;
- munmap(std::get<0>(pair_), std::get<1>(pair_));
- }
+// for (auto &iter : mappedBuffers_)
+// {
+// std::pair<void *, unsigned int> pair_ = iter.second;
+// munmap(std::get<0>(pair_), std::get<1>(pair_));
+// }
- mappedBuffers_.clear();
+// mappedBuffers_.clear();
- requests_.clear();
+// requests_.clear();
- allocator_.reset();
+// allocator_.reset();
- controls_.clear();
-}
+// controls_.clear();
+// }
-void LibCamera::closeCamera(){
- if (camera_acquired_)
- camera_->release();
- camera_acquired_ = false;
+// void LibCamera::closeCamera(){
+// if (camera_acquired_)
+// camera_->release();
+// camera_acquired_ = false;
- camera_.reset();
+// camera_.reset();
- cm.reset();
-}
+// cm.reset();
+// }
diff --git a/LibCamera.h b/LibCamera.h index 2262ab2..89cf835 100644 --- a/LibCamera.h +++ b/LibCamera.h @@ -1,19 +1,25 @@ -#include <atomic>
-#include <iomanip>
-#include <iostream>
-#include <signal.h>
-#include <limits.h>
-#include <memory>
-#include <stdint.h>
-#include <string>
-#include <vector>
-#include <unordered_map>
-#include <queue>
-#include <sstream>
-#include <sys/mman.h>
-#include <unistd.h>
-#include <time.h>
-#include <mutex>
+#pragma once
+
+// #include <atomic>
+// #include <iomanip>
+// #include <iostream>
+// #include <signal.h>
+// #include <limits.h>
+// #include <memory>
+// #include <stdint.h>
+// #include <string>
+// #include <vector>
+// #include <unordered_map>
+// #include <queue>
+// #include <sstream>
+// #include <sys/mman.h>
+// #include <unistd.h>
+// #include <time.h>
+// #include <mutex>
+
+#ifdef signals
+#error ("don't include this file after any qt files")
+#endif
#include <libcamera/controls.h>
#include <libcamera/control_ids.h>
@@ -26,61 +32,60 @@ #include <libcamera/stream.h>
#include <libcamera/formats.h>
#include <libcamera/transform.h>
+// using namespace libcamera;
-using namespace libcamera;
-
-typedef struct {
- uint8_t *imageData;
- uint32_t size;
- uint64_t request;
-} LibcameraOutData;
+// typedef struct {
+// uint8_t *imageData;
+// uint32_t size;
+// uint64_t request;
+// } LibcameraOutData;
-class LibCamera {
- public:
- LibCamera(){};
- ~LibCamera(){};
+// class LibCamera {
+// public:
+// LibCamera(){};
+// ~LibCamera(){};
- int initCamera();
- void configureStill(int width, int height, PixelFormat format, int buffercount, int rotation);
- int startCamera();
- int resetCamera(int width, int height, PixelFormat format, int buffercount, int rotation);
- bool readFrame(LibcameraOutData *frameData);
- void returnFrameBuffer(LibcameraOutData frameData);
+// int initCamera();
+// void configureStill(int width, int height, PixelFormat format, int buffercount, int rotation);
+// int startCamera();
+// int resetCamera(int width, int height, PixelFormat format, int buffercount, int rotation);
+// bool readFrame(LibcameraOutData *frameData);
+// void returnFrameBuffer(LibcameraOutData frameData);
- void set(ControlList controls);
- void stopCamera();
- void closeCamera();
+// void set(ControlList controls);
+// void stopCamera();
+// void closeCamera();
- Stream *VideoStream(uint32_t *w, uint32_t *h, uint32_t *stride) const;
- char * getCameraId();
+// Stream *VideoStream(uint32_t *w, uint32_t *h, uint32_t *stride) const;
+// char * getCameraId();
- private:
- int startCapture();
- int queueRequest(Request *request);
- void requestComplete(Request *request);
- void processRequest(Request *request);
+// private:
+// int startCapture();
+// int queueRequest(Request *request);
+// void requestComplete(Request *request);
+// void processRequest(Request *request);
- void StreamDimensions(Stream const *stream, uint32_t *w, uint32_t *h, uint32_t *stride) const;
+// void StreamDimensions(Stream const *stream, uint32_t *w, uint32_t *h, uint32_t *stride) const;
- unsigned int cameraIndex_;
- uint64_t last_;
- std::unique_ptr<CameraManager> cm;
- std::shared_ptr<Camera> camera_;
- bool camera_acquired_ = false;
- bool camera_started_ = false;
- std::unique_ptr<CameraConfiguration> config_;
- std::unique_ptr<FrameBufferAllocator> allocator_;
- std::vector<std::unique_ptr<Request>> requests_;
- // std::map<std::string, Stream *> stream_;
- std::map<int, std::pair<void *, unsigned int>> mappedBuffers_;
+// unsigned int cameraIndex_;
+// uint64_t last_;
+// std::unique_ptr<CameraManager> cm;
+// std::shared_ptr<Camera> camera_;
+// bool camera_acquired_ = false;
+// bool camera_started_ = false;
+// std::unique_ptr<CameraConfiguration> config_;
+// std::unique_ptr<FrameBufferAllocator> allocator_;
+// std::vector<std::unique_ptr<Request>> requests_;
+// // std::map<std::string, Stream *> stream_;
+// std::map<int, std::pair<void *, unsigned int>> mappedBuffers_;
- std::queue<Request *> requestQueue;
+// std::queue<Request *> requestQueue;
- ControlList controls_;
- std::mutex control_mutex_;
- std::mutex camera_stop_mutex_;
- std::mutex free_requests_mutex_;
+// ControlList controls_;
+// std::mutex control_mutex_;
+// std::mutex camera_stop_mutex_;
+// std::mutex free_requests_mutex_;
- Stream *viewfinder_stream_ = nullptr;
- std::string cameraId;
-};
\ No newline at end of file +// Stream *viewfinder_stream_ = nullptr;
+// std::string cameraId;
+// };
diff --git a/fuck_intel.h b/fuck_intel.h new file mode 100644 index 0000000..a9fa7d5 --- /dev/null +++ b/fuck_intel.h @@ -0,0 +1,9 @@ +#pragma once + +#ifdef emit +#undef emit +#include <execution> +#define emit +#else +#include <execution> +#endif diff --git a/genetic_algos.h b/genetic_algos.h index 862cd34..8dea732 100644 --- a/genetic_algos.h +++ b/genetic_algos.h @@ -3,9 +3,9 @@ // #define _USE_MATH_DEFINES #include <algorithm> #include <cmath> -// #include <execution> #include <numbers> #include <random> +// TODO: <execution> /* diff --git a/imagealgos.cpp b/imagealgos.cpp index 3e84155..b4fba4b 100644 --- a/imagealgos.cpp +++ b/imagealgos.cpp @@ -1,5 +1,7 @@ #include "imagealgos.h" +#include <QDebug> + #include <cassert> #include <cstdint> #include <cstring> @@ -14,6 +16,7 @@ // #include <arm_neon.h> +#include "fuck_intel.h" #include "genetic_algos.h" #include "macro.h" @@ -210,7 +213,7 @@ float process_column(uint16_t (&column)[]) } result = (y2 != y1) ? - (img_height - (float(x1) - (float(y1) / (y2 - y1)))) : + (float(x1) - (float(y1) / (y2 - y1))) : std::numeric_limits<float>::quiet_NaN(); @@ -267,11 +270,230 @@ Pixels process_columns(Image &image) // image.pixels[i] = genetic.run().a; // if (i == 0) { - // std::cout << "pixel: " << image.pixels[i] << std::endl; - // } + // std::cout << "pixel: " << image.pixels[i] << std::endl; + // } } stop_timer(process_columns); return result; } + +Pixels& Pixels::operator+=(const Pixels& other) +{ + std::transform(std::execution::par, + pixels.begin(), pixels.end(), + other.pixels.begin(), + pixels.begin(), + // [](auto& toAdd) { return dst += src; }); + std::plus<>()); + + return *this; +} + +Pixels& Pixels::operator/=(const float divider) +{ + std::for_each(std::execution::par_unseq, + pixels.begin(), pixels.end(), + [divider](auto& pixel) { pixel /= divider; }); + + return *this; +} + +QList<QLineF> pixelsToLines(const Pixels &rawProfile) +{ + const auto& pixels = rawProfile.pixels; + QList<QPointF> points { pixels.size() }; + + for (int i = 0; i < pixels.size(); ++i) + { + points[i] = { qreal(i) - img_width / 2, pixels.at(i) }; + } + + // qDebug() << "mid points" << points.mid(points.count() - 3, 6); + + return pointsToLines(std::move(points)); +} + +QList<QLineF> pointsToLines(const QList<QPointF> &points) +{ + constexpr double maxDistanceFromLine { 3 }; + constexpr double minLineLength { 10 }; + + QList<int> lineAnchors { 0, points.size() - 1 }; + + auto vecLength = [](const QPointF& vector) { + return std::hypot(vector.x(), vector.y()); + }; + + auto distanceToLine = [vecLength](const QPointF& point, const QLineF& line) { + // const auto d1 = point - line.p1(); + // const auto d2 = line.p2() - line.p1(); + + // const auto norm = vecLength(d2); + // qDebug() << "norm" << norm; + + // if (norm <= std::numeric_limits<double>::epsilon()) + // { + // qDebug() << "AAAAAAAAAAAAAAAAAA"; + // return vecLength(d1); + // } + + // const auto result = std::fabs(d1.x() * d2.y() - d1.y() * d2.x()) / norm; + + // if (!qFuzzyIsNull(result)) + // { + // qDebug() << "NOT NULL" << result << point << line; + // } + + // return result; + // transform to loocal coordinates system (0,0) - (lx, ly) + QPointF p1 = line.p1(); + QPointF p2 = line.p2(); + const auto& p = point; + qreal x = p.x() - p1.x(); + qreal y = p.y() - p1.y(); + qreal x2 = p2.x() - p1.x(); + qreal y2 = p2.y() - p1.y(); + + // if line is a point (nodes are the same) => + // just return distance between point and one line node + qreal norm = sqrt(x2*x2 + y2*y2); + if (norm <= std::numeric_limits<int>::epsilon()) + return sqrt(x*x + y*y); + + // distance + // qDebug() << "dist" << fabs(x*y2 - y*x2) / norm << point << line; + return fabs(x*y2 - y*x2) / norm; + }; + + // for (const auto& p : points) + // { + // qDebug() << "\t" << p; + // } + + for (int i = 0; i < lineAnchors.count() - 1; ++i) + { + const auto &lineFirst = i; + const auto &lineLast = i + 1; + const auto& leftPointIdx = lineAnchors.at(lineFirst); + const auto& rightPointIdx = lineAnchors.at(lineLast); + + if (rightPointIdx - leftPointIdx < 2) + { + continue; + } + + const QLineF line { points.at(leftPointIdx), points.at(rightPointIdx) }; + + const auto farthest = std::max_element( + // std::execution::par_unseq, + points.cbegin() + leftPointIdx + 1, + points.cbegin() + rightPointIdx - 1, + [line, distanceToLine](const QPointF& a, const QPointF& b) { + return distanceToLine(a, line) < distanceToLine(b, line); + }); + + // qDebug() << "farthest point" << distanceToLine(*farthest, line); + // qDebug() << "farthest dist" << distanceToLine(*farthest, line); + // qDebug() << "that's from line" << line; + + if (distanceToLine(*farthest, line) > maxDistanceFromLine) + { + lineAnchors.insert(i + 1, farthest - points.cbegin()); + --i; + // qDebug() << "I'm here" << i; + continue; + } + } + + struct LineAB + { + double a { std::numeric_limits<double>::quiet_NaN() }; + double b { std::numeric_limits<double>::quiet_NaN() }; + + LineAB(const QList<QPointF>& points) { + if (points.isEmpty()) + { + return; + } + + double sumX { 0 }; + double sumY { 0 }; + double sumXY { 0 }; + double sumXX { 0 }; + + // FIXME: validate + // for (const auto& point : points) + const int delta = points.count() * 0.15; + for (int i = delta; i < points.count() - delta; ++i) + { + const auto& point = points.at(i); + sumX += point.x(); + sumY += point.y(); + sumXY += point.x() * point.y(); + sumXX += point.x() * point.x(); + } + + // sumX /= points.count(); + // sumY /= points.count(); + // sumXY /= points.count(); + // sumXX /= points.count(); + + const int n = points.count() - delta * 2; + Q_ASSERT_X(n > 0, Q_FUNC_INFO, "n <= 0"); + + a = (n * sumXY - sumX * sumY) / + (n * sumXX - sumX * sumX); + b = (sumY - a * sumX) / n; + } + }; + + // auto pointsToLineAB = + + // qDebug() << "line anchors count is" << lineAnchors.count(); + + constexpr bool useLsd = true; + + QList<QLineF> result { lineAnchors.length() - 1 }; + + for (int i = 0; i < lineAnchors.count() - 1; ++i) + { + const auto& leftPointIdx = lineAnchors.at(i); + const auto& rightPointIdx = lineAnchors.at(i + 1); + + QPointF leftPoint = points.at(leftPointIdx); + QPointF rightPoint = points.at(rightPointIdx); + + LineAB lineAB(points.mid(leftPointIdx, rightPointIdx - leftPointIdx)); + + leftPoint.setY(lineAB.a * leftPoint.x() + lineAB.b); + rightPoint.setY(lineAB.a * rightPoint.x() + lineAB.b); + + if (useLsd) + result[i] = QLineF{ std::move(leftPoint), std::move(rightPoint) }; + else + result[i] = QLineF{ points.at(lineAnchors.at(i)), points.at(lineAnchors.at(i + 1)) }; + } + + if (useLsd) + { + for (int i = 0; i < result.count() - 1; ++i) + { + auto& lineA = result[i]; + auto& lineB = result[i + 1]; + + QPointF intersectionPoint {}; + + if (lineA.intersects(lineB, &intersectionPoint) != QLineF::NoIntersection) + { + lineA.setP2(intersectionPoint); + lineB.setP1(intersectionPoint); + } + } + } + + // qDebug() << result; + + return result; +} diff --git a/imagealgos.h b/imagealgos.h index 77ac625..12dc8cf 100644 --- a/imagealgos.h +++ b/imagealgos.h @@ -6,6 +6,9 @@ #include <libcamera/pixel_format.h> +#include <QLineF> +#include <QList> + constexpr size_t img_width = 1280; constexpr size_t img_height = 800; constexpr uint32_t patternSize = 16; @@ -37,8 +40,12 @@ struct Pixels { Counters counters {}; std::array<float, img_width> pixels { 0.f }; + + Pixels& operator+=(const Pixels& other); + Pixels& operator/=(const float divider); }; + size_t pgm_save(Image *img, FILE *outfile, bool really_save = false); void unpack_10bit(uint8_t const *src, Image const &image, uint16_t *dest); @@ -52,3 +59,6 @@ T median3(const T& a, const T& b, const T& c) { void rotate(Image & image); Pixels process_columns(Image & image); + +QList<QLineF> pixelsToLines(const Pixels& rawProfile); +QList<QLineF> pointsToLines(const QList<QPointF>& points); @@ -1,13 +1,21 @@ +#include <chrono> +#include <errno.h> +#include <iostream> +#include <iterator> +#include <fstream> +#include <string.h> +#include <thread> +#include <sys/mman.h> +#include "LibCamera.h" +#include "printerclient.h" #include "httpservice.h" #include "genetic_algos.h" -#include "imagealgos.h" -#include "LibCamera.h" #include "pigpio.h" -#include "printerclient.h" #include "rotaryencoder.h" +#include "imagealgos.h" +#include "fuck_intel.h" -#define QT_NO_KEYWORDS #include <QCoreApplication> #include <QDebug> #include <QDir> @@ -20,14 +28,6 @@ #include <QTextStream> #include <QtConcurrent/QtConcurrentRun> #include <QTimer> -#undef QT_NO_KEYWORDS - -#include <chrono> -#include <errno.h> -#include <iostream> -#include <fstream> -#include <string.h> -#include <thread> #define try_apply_config() \ if(!applyConfig(config)) \ @@ -76,21 +76,83 @@ const QString dumpsRoot { QStringLiteral("/home/user/dumps") }; using namespace std::chrono_literals; -static std::shared_ptr<Camera> camera; -std::unique_ptr<CameraConfiguration> config; +static std::shared_ptr<libcamera::Camera> camera; +std::unique_ptr<libcamera::CameraConfiguration> config; static std::map<int, std::pair<void *, unsigned int>> mappedBuffers_; -std::vector<std::unique_ptr<Request>> requests; -ControlList lastControls; +std::vector<std::unique_ptr<libcamera::Request>> requests; +libcamera::ControlList lastControls; -static bool applyConfig(const std::unique_ptr<CameraConfiguration> & config); -static void onRequestCompleted(Request *completed_request); +static QList<Pixels> openDump(const QString& dumpPath = ""); +static std::optional<Pixels> openRawProfile(const QString& filePath); +constexpr float hardcodedZRangeMm { 175.f }; +constexpr size_t calibrationTableHeight { 0x4000 }; // 16384 +// img_width * calibrationTableHeight +using CalibrationColumn = std::array<float, calibrationTableHeight>; +using CalibrationTable = std::array<CalibrationColumn, img_width>; +constexpr auto calibrationColumnHeight = std::tuple_size<CalibrationColumn>(); +// CalibrationTable* calibrationTable { new CalibrationTable {{ 0 }} }; + +static bool applyConfig(const std::unique_ptr<libcamera::CameraConfiguration> & config); +static void onRequestCompleted(libcamera::Request *completed_request); static void printControls(); static void dumpCalibrationPixels(); -static std::vector<Pixels> openDump(const QString dumpPath = ""); +static QList<Pixels> filter(const QList<Pixels>& rawProfiles); +static QSharedPointer<CalibrationTable> calibrate(const QList<Pixels>& rawProfiles); + +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; +}; + +bool initLaser(); + +class A +{ +public: + A(const int var) : m_var{ var } { std::cout << m_var << std::endl; } + +private: + int m_var { 0 }; +}; + +class B : public A +{ +public: + B(const int var) : A{var} {} +}; int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); + // if (!initLaser()) + // { + // return EXIT_FAILURE; + // } + + if (false) + { + // auto rawProfiles = openDump("/home/user/dumps/2024.11.24_19.17.32"); + // auto rawProfiles = openDump("/home/user/dumps/2024.11.26_21.53.55"); + auto rawProfiles = openDump("/home/user/dumps/2024.11.26_21.53.55_small"); + qDebug() << "raw profiles count is" << rawProfiles.size(); + // qDebug() << "height" << calibrationColumnHeight; + + auto filteredRawProfiles = filter(rawProfiles); + qDebug() << "filtered profiles count is" << filteredRawProfiles.count(); + + auto calibrationTable = calibrate(filteredRawProfiles); + // auto calibrationTable = calibrate(rawProfiles); + // CalibrationTable* aaa { new CalibrationTable {{ 0 }} }; + // (*aaa)[1][0] = 123; + // CalibrationTable bbb {{ 0 }}; + // bbb[1][0] = 123; + + // float* values = new float[calibrationColumnHeight]; + } + QElapsedTimer t; t.start(); @@ -102,7 +164,7 @@ int main(int argc, char *argv[]) { qDebug() << "msecs before camera:" << t.elapsed(); // FIXME: don't use one var for everything int ret; - std::unique_ptr<CameraManager> cm = std::make_unique<CameraManager>(); + std::unique_ptr<libcamera::CameraManager> cm = std::make_unique<libcamera::CameraManager>(); cm->start(); const auto cameras = cm->cameras(); @@ -139,7 +201,7 @@ int main(int argc, char *argv[]) { // FIXME: nullptr // std::unique_ptr<CameraConfiguration> config = camera->generateConfiguration( { StreamRole::Viewfinder } ); - /*std::unique_ptr<CameraConfiguration> */config = camera->generateConfiguration( { StreamRole::Raw } ); + /*std::unique_ptr<CameraConfiguration> */config = camera->generateConfiguration( { libcamera::StreamRole::Raw } ); if (config->empty()) { @@ -162,7 +224,7 @@ int main(int argc, char *argv[]) { // } // FIXME: nullptr - StreamConfiguration &streamConfig = config->at(0); + libcamera::StreamConfiguration &streamConfig = config->at(0); std::cout << "Default viewfinder configuration is: " << streamConfig.toString() << std::endl; std::cout << "Pixel format is: " << streamConfig.pixelFormat.toString() << std::endl; std::cout << "Buffer count is: " << streamConfig.bufferCount << std::endl; @@ -179,7 +241,7 @@ int main(int argc, char *argv[]) { // streamConfig.pixelFormat = PixelFormat::fromString("Y8_1X8"); // streamConfig.pixelFormat = formats::R8; - streamConfig.pixelFormat = formats::R16; + streamConfig.pixelFormat = libcamera::formats::R16; streamConfig.bufferCount = 2; // what is default R10_CSI2P? MONO_PISP_COMP1? // MONO_PISP_COMP1 - check rpicam-apps sources for decoding algos @@ -215,7 +277,7 @@ int main(int argc, char *argv[]) { // TODO: try custom FrameBufferAllocator and compare performance - auto allocator = std::make_shared<FrameBufferAllocator>(camera); + auto allocator = std::make_shared<libcamera::FrameBufferAllocator>(camera); auto stream = streamConfig.stream(); @@ -232,13 +294,13 @@ int main(int argc, char *argv[]) { size_t allocated = size_t(ret); std::cout << "Allocated " << allocated << " buffers for stream" << std::endl; - const std::vector<std::unique_ptr<FrameBuffer>> &buffers = allocator->buffers(stream); + const std::vector<std::unique_ptr<libcamera::FrameBuffer>> &buffers = allocator->buffers(stream); // for (size_t i = 0; i < buffers.size(); ++i) static int expOffset = 0; for (const auto & buffer : buffers) { - std::unique_ptr<Request> request = camera->createRequest(); + std::unique_ptr<libcamera::Request> request = camera->createRequest(); if (!request) { @@ -328,7 +390,7 @@ int main(int argc, char *argv[]) { for (size_t i = 0; i < img_width; ++i) { // pixels << img_height - img.pixels[i]; - pixels << img_height - ::pixels.pixels[i]; + pixels << ::pixels.pixels[i]; } QJsonObject json; @@ -337,6 +399,22 @@ int main(int argc, char *argv[]) { json["measurementCounter"] = qint64 { img.counters.measurementCounter }; json["timestampUs"] = qint64(img.counters.timestampUs); + const auto lines = pixelsToLines(::pixels); + + qDebug() << "lines count is " << lines.count(); + + QJsonArray jsonLines; + + for (const auto& l : lines) + { + jsonLines << QJsonArray { + QJsonArray { l.p1().x(), l.p1().y() }, + QJsonArray { l.p2().x(), l.p2().y() } + }; + } + + json["lines"] = jsonLines; + return QHttpServerResponse(QJsonDocument(json).toJson()); }); @@ -403,14 +481,14 @@ int main(int argc, char *argv[]) { std::lock_guard<std::mutex> lg(pgm_image_mtx); QJsonObject json; - const ControlIdMap & ctrlIdMap = camera->controls().idmap(); + const libcamera::ControlIdMap & ctrlIdMap = camera->controls().idmap(); qDebug() << "readParams:" << lastControls.size(); qDebug() << request.method(); for (const auto & [id, value]: lastControls) { - const ControlId * controlId = ctrlIdMap.at(id); + const libcamera::ControlId * controlId = ctrlIdMap.at(id); auto name = QString::fromStdString(controlId->name()); const auto valueStr = QString::fromStdString(value.toString()); qDebug() << "\t param:" @@ -611,8 +689,10 @@ int main(int argc, char *argv[]) { * important not to block the thread for a long time, as this blocks internal * processing of the camera pipelines, and can affect realtime performance. */ -void onRequestCompleted(Request *completed_request) +void onRequestCompleted(libcamera::Request *completed_request) { + using namespace libcamera; + static std::chrono::steady_clock::time_point fpsTimstamp = std::chrono::steady_clock::now(); QElapsedTimer t; @@ -683,8 +763,7 @@ void onRequestCompleted(Request *completed_request) // qDebug() << "calibration mode" << scanningModeFlags; if (scanningModeFlags == ScanningModeFlags::Calibration) { - constexpr int32_t hardcodedZRangeMm { 175 }; - const int32_t maxEncoderPosition = hardcodedZRangeMm * requested_params.stepsPerMm; + const int32_t maxEncoderPosition = int32_t(hardcodedZRangeMm) * requested_params.stepsPerMm; // qDebug() << "calibration max range" << maxEncoderPosition; // qDebug() << "calibration encoder pos" << pixels.counters.encoderPosition; if (pixels.counters.encoderPosition >= 0 && @@ -789,12 +868,14 @@ void onRequestCompleted(Request *completed_request) } -static bool applyConfig(const std::unique_ptr<CameraConfiguration> & config) +static bool applyConfig(const std::unique_ptr<libcamera::CameraConfiguration> & config) { + using namespace libcamera; + auto status = config->validate(); // WARNING: unsafe - StreamConfiguration &streamConfig = config->at(0); + libcamera::StreamConfiguration &streamConfig = config->at(0); switch (status) { case CameraConfiguration::Status::Valid: @@ -819,7 +900,8 @@ static bool applyConfig(const std::unique_ptr<CameraConfiguration> & config) static void printControls() { - const ControlInfoMap & control_map = camera->controls(); + using namespace libcamera; + const libcamera::ControlInfoMap & control_map = camera->controls(); // for (const auto & [id, info]: control_map) for (const std::pair<const ControlId *, ControlInfo> & pair : control_map) @@ -888,10 +970,10 @@ static void dumpCalibrationPixels() } QJsonObject jsonCounters { - { "timestampUs", qint64(rawProfile.counters.timestampUs) }, - { "measurementCounter", qint64(rawProfile.counters.measurementCounter) }, - { "encoderPosition", qint64(rawProfile.counters.encoderPosition) }, - }; + { "timestampUs", qint64(rawProfile.counters.timestampUs) }, + { "measurementCounter", qint64(rawProfile.counters.measurementCounter) }, + { "encoderPosition", qint64(rawProfile.counters.encoderPosition) }, + }; QJsonObject json; @@ -920,11 +1002,10 @@ static void dumpCalibrationPixels() qDebug() << "dump finished"; } -static std::vector<Pixels> openDump(const QString dumpPath) +static QList<Pixels> openDump(const QString &dumpPath) { - std::vector<Pixels> result; - QString dirToRead { dumpPath }; + qDebug() << "trying to open dump path:" << dirToRead; if (dirToRead.isEmpty()) { @@ -945,10 +1026,10 @@ static std::vector<Pixels> openDump(const QString dumpPath) return {}; } - dirToRead = entries.last(); + dirToRead = dumpsRoot + "/" + entries.last(); } - QDir dumpDir { dumpsRoot + "/" + dirToRead }; + QDir dumpDir { dirToRead }; const auto filter = QDir::Files; const auto sort = QDir::Name; @@ -958,47 +1039,260 @@ static std::vector<Pixels> openDump(const QString dumpPath) if (filenames.isEmpty()) { qDebug() << "no filenames found in" << dumpDir.path(); + return {}; } - for (const auto& filename : filenames) + QList<std::optional<Pixels>> resultOptionals { filenames.size() }; + + QElapsedTimer t; + t.start(); + + std::transform( + std::execution::par, + filenames.begin(), filenames.end(), + resultOptionals.begin(), + [dirToRead](const auto& filename) { + std::cout << '.'; + return openRawProfile(dirToRead + "/" + filename); + }); + + std::cout << std::endl; + + std::remove_if( + std::execution::par, + resultOptionals.begin(), + resultOptionals.end(), + [](auto& a) { return !a.has_value(); }); + + QList<Pixels> result { resultOptionals.size() }; + + std::transform( + std::execution::par, + std::make_move_iterator(resultOptionals.begin()), + std::make_move_iterator(resultOptionals.end()), + result.begin(), + [](auto& p) { return p.value(); }); + + qDebug() << Q_FUNC_INFO << "elapsed (ms)" << t.elapsed(); + + return result; +} + +static std::optional<Pixels> openRawProfile(const QString& filePath) +{ + QFile f { filePath }; + + if (!f.open(QFile::ReadOnly)) { - qDebug() << "raw profile:" << filename; + qWarning() << "cannot open file for reading:" << f.fileName(); + qWarning() << "error string:" << f.errorString(); + + return {}; + } - QFile f { dumpDir.path() + "/" + filename }; + // TODO: rewrite to remove manual serialization/deserialization + const auto json = QJsonDocument::fromJson(f.readAll()).object(); + const auto jsonCounters = json["counters"].toObject(); - if (!f.open(QFile::ReadOnly)) + Pixels result; + result.counters.timestampUs = jsonCounters["timestampUs"].toInteger(); + result.counters.measurementCounter = jsonCounters["measurementCounter"].toInteger(); + result.counters.encoderPosition = jsonCounters["encoderPosition"].toInteger(); + + const auto jsonPixels = json["pixels"].toArray(); + + for (size_t i = 0; i < jsonPixels.count() && i < result.pixels.size(); ++i) + { + result.pixels[i] = jsonPixels[i].toDouble(); + } + + return result; +} + +static QList<Pixels> filter(const QList<Pixels>& rawProfiles) +{ + QList<Pixels> result; + + QList<Pixels>::const_iterator it = rawProfiles.constBegin(); + + // for (size_t i = 0; i < 10; ++i) + // { + // std::cout << "pos - " << rawProfiles.at(i).counters.encoderPosition << std::endl; + // } + + // ++it; + while (it != rawProfiles.constEnd()) + { + Pixels sum = *it; + std::cout << "current pos is " << sum.counters.encoderPosition << std::endl; + + printPixels(sum.pixels); + + size_t count { 1 }; + ++it; + + std::cout << "here\n"; + while (it != rawProfiles.constEnd() && it->counters.encoderPosition == sum.counters.encoderPosition) { - qWarning() << "cannot open file for reading:" << f.fileName(); - qWarning() << "error string:" << f.errorString(); + std::cout << "here2\n"; + std::cout << "\tadd to pos " << it->counters.encoderPosition << std::endl; + sum += *it; + std::cout << "\tadded" << std::endl; + ++count; + ++it; - return {}; } - // TODO: rewrite to remove manual serialization/deserialization - const auto json = QJsonDocument::fromJson(f.readAll()).object(); - const auto jsonCounters = json["counters"].toObject(); - qDebug() << jsonCounters; + std::cout << "here3\n"; + sum /= float(count); + printPixels(sum.pixels); - Pixels rawProfile; + result << sum; - rawProfile.counters.timestampUs = jsonCounters["timestampUs"].toInteger(); - rawProfile.counters.measurementCounter = jsonCounters["measurementCounter"].toInteger(); - rawProfile.counters.encoderPosition = jsonCounters["encoderPosition"].toInteger(); + // return result; + } - const auto jsonPixels = json["pixels"].toArray(); - qDebug() << jsonPixels.count() << rawProfile.pixels.size(); + return result; +} - for (size_t i = 0; i < jsonPixels.count() && i < rawProfile.pixels.size(); ++i) +static QSharedPointer<CalibrationTable> calibrate(const QList<Pixels>& rawProfiles) +{ + QSharedPointer<CalibrationTable> result { new CalibrationTable {{ 0 }} }; + + constexpr uint16_t discretesInRage { 16384 }; + + for (const auto& rawProfile : rawProfiles) + { + std::cout << "calibration: pos is " << rawProfile.counters.encoderPosition << std::endl; + const float positionMm { + float(rawProfile.counters.encoderPosition) / + float(requested_params.stepsPerMm) + }; + + const auto& pixels = rawProfile.pixels; + printPixels(pixels); + // static size_t counter { 0 }; + // qDebug() << "calibrated" << counter++; + const float pos = rawProfile.counters.encoderPosition; + const float divider = requested_params.stepsPerMm; + std::cout << pos << " " << divider << " " << pos / divider << std::endl; + // std::cout << std::setw(5) << rawProfile.counters.encoderPosition + // << std::setw(5) << requested_params.stepsPerMm + // << std::setw(8) << positionMm + // << std::setw(8) << float(rawProfile.counters.encoderPosition) / + // float(requested_params.stepsPerMm) + // << ": "; + + for (size_t columnIdx = 0; columnIdx < pixels.size(); ++columnIdx) { - rawProfile.pixels[i] = jsonPixels[i].toDouble(); + const auto& pixelValue = pixels.at(columnIdx); + + // float[0, img_height] -> uint16_t[0, calibrationColumnHeight] + const uint16_t discretePixelValue { + uint16_t(pixelValue * discretesInRage / img_height) + }; + + Q_ASSERT_X(discretePixelValue > 0 && discretePixelValue < calibrationColumnHeight, + Q_FUNC_INFO, + ("got ivalid discrete value " + + QString::number(discretePixelValue) + + ". pixelValues is " + + QString::number(pixelValue) + + ". calc result is " + + QString::number(pixelValue * discretesInRage / img_height) + ).toStdString().c_str()); + + // auto& calibrationColumn = result[columnIdx]; + auto& calibrationColumn = (*result)[columnIdx]; + calibrationColumn[discretePixelValue] = positionMm; + + if (columnIdx >= ((img_width - 10) / 2) && columnIdx < img_width - ((img_width - 10) / 2)) + { + std::cout << discretePixelValue << ";"; + } } - } - // { - // QMutexLocker l(&calibrationPixelsMutex); - // std::swap(result, ::calibrationPixels); - // } + std::cout << std::endl << std::flush; + } return result; + // TODO: try something interesting + // return {}; +} + +bool initLaser() +{ + const QLatin1String pwmChip { "pwmchip2" }; + const uint16_t pwmChannel { 1 }; + const QLatin1String pwmSystemRoot { "/sys/class/pwm" }; + const QString pwmChipRoot { pwmSystemRoot + "/" + pwmChip }; + + const QString pwmExportFile { pwmChipRoot + "/export" }; + + QFile f { pwmExportFile }; + + if (!f.open(QFile::WriteOnly)) + { + qWarning() << "cannot open" << f.fileName() << "for writing"; + qWarning() << "error:" << f.errorString(); + + return false; + } + + QTextStream s { &f }; + s << pwmChannel; + + const QString pwm { QLatin1String("pwm%1").arg(QString::number(pwmChannel)) }; + const QString pwmRoot { pwmChipRoot + "/" + pwm }; + + const QString periodFilename { pwmRoot + "/period" }; + f.close(); + f.setFileName(periodFilename); + + if (!f.open(QFile::WriteOnly)) + { + qWarning() << "cannot open" << f.fileName() << "for writing"; + qWarning() << "error:" << f.errorString(); + + return false; + } + + const unsigned periodHz { 50'000 }; + + s << periodHz; + + const QString dutyCycleFilename { pwmRoot + "/duty_cycle" }; + f.close(); + f.setFileName(dutyCycleFilename); + + if (!f.open(QFile::WriteOnly)) + { + qWarning() << "cannot open" << f.fileName() << "for writing"; + qWarning() << "error:" << f.errorString(); + + return false; + } + + const unsigned dutyCycle { 3'000 }; + + s << dutyCycle; + + const QString enableFilename { pwmRoot + "/enable" }; + f.close(); + f.setFileName(enableFilename); + + if (!f.open(QFile::WriteOnly)) + { + qWarning() << "cannot open" << f.fileName() << "for writing"; + qWarning() << "error:" << f.errorString(); + + return false; + } + + const int enable { 1 }; + + s << enable; + + return true; } |
