diff options
| author | Nikita Kostovsky <nikita@kostovsky.me> | 2025-11-14 21:05:12 +0100 |
|---|---|---|
| committer | Nikita Kostovsky <nikita@kostovsky.me> | 2025-11-14 21:05:12 +0100 |
| commit | 5df63c0bc7e3d6f1850d04f5bafbae2dd6fa619e (patch) | |
| tree | 7b98d59baec4aac62cab374e95795a2ce6b88d03 /src/camera/veyeimx287m.cpp | |
| parent | 36ef6a75e3418d88227e84ab175c0057e860c151 (diff) | |
organize things a bit, populate ICamera
Diffstat (limited to 'src/camera/veyeimx287m.cpp')
| -rw-r--r-- | src/camera/veyeimx287m.cpp | 252 |
1 files changed, 129 insertions, 123 deletions
diff --git a/src/camera/veyeimx287m.cpp b/src/camera/veyeimx287m.cpp index b8fdbb4..a03aa83 100644 --- a/src/camera/veyeimx287m.cpp +++ b/src/camera/veyeimx287m.cpp @@ -9,20 +9,15 @@ #include <sys/mman.h> #include <unistd.h> -#include <execution> #include <iostream> -#include <ranges> -#include <span> #include <QElapsedTimer> +// orpheus #include "camera/veye_i2c.h" #include "constants.h" -#include "httpservice.h" -#include "imagealgos.h" -#include "mem_utils.h" -#include "pixels.h" -// #include "rotaryencoder.h" +#include "protocols/httpserver.h" +#include "veyeimx287m_types.h" static const struct v4l2_format_info { @@ -232,7 +227,9 @@ VeyeIMX287m::~VeyeIMX287m() if (m_cam_fd >= 0) { if (close(m_cam_fd) == -1) { - std::cout << __func__ << ": cannot close camera: " << strerror(errno) << std::endl; + std::cout << __func__ + << ": cannot close camera: " << strerror(errno) + << std::endl; } }; @@ -242,35 +239,26 @@ VeyeIMX287m::~VeyeIMX287m() std::vector<std::shared_ptr<ICamera> > VeyeIMX287m::search() { // return only one camera for now - std::cout << std::boolalpha; - auto cam = std::make_shared<VeyeIMX287m>(); + const auto cam = std::make_shared<VeyeIMX287m>(); if (!cam->init()) return {}; - if (!cam->setExposureTimeUs(30)) + // if (!cam->set_autoExposure(false)) + if (!cam->set_autoExposure(true)) return {}; - if (!cam->setLaserLevel(1)) + if (!cam->set_exposureTime(std::chrono::microseconds(30))) return {}; - if (!cam->setGain(2)) + if (!cam->set_autoGain(false)) return {}; - if (!cam->setSomething(0)) { + if (!cam->set_gain(0.1)) return {}; - } - // m_someThread = std::jthread{[=](std::stop_token stopToken) { - // std::cout << "VeyeIMX287m: start stream" << std::endl; - // sleep(5); - - // static int i = 0; - // while (!stopToken.stop_requested()) { - // cam->setSomething(i); - // i -= 1; - // } - // }}; + if (!cam->setLaserLevel(1)) + return {}; return {cam}; } @@ -283,8 +271,8 @@ bool VeyeIMX287m::startStream() auto ret = ioctl(m_cam_fd, VIDIOC_STREAMON, &radxa_buf_type); if (ret != 0) { - std::cerr << "ioctl(VIDIOC_STREAMON) failed: " << errno << " (" << strerror(errno) << ")" - << std::endl; + std::cerr << "ioctl(VIDIOC_STREAMON) failed: " << errno << " (" + << strerror(errno) << ")" << std::endl; return false; } @@ -310,123 +298,110 @@ bool VeyeIMX287m::init() if (!initCam()) return false; + if (!initI2C()) { + return false; + } + if (!initHttpServer()) return false; return true; } -bool VeyeIMX287m::setExposureTime(const std::chrono::microseconds us) +bool VeyeIMX287m::set_autoExposure(const bool enable) { - const std::string i2c_dev{"/dev/i2c-2"}; - const auto address = 0x3b; - const auto metime_reg = 0xc10; - const auto val = us.count(); - - const int fd = open(i2c_dev.c_str(), O_RDWR); + using namespace veye::imx287m; - if (!fd) { - std::cerr << "cannot open i2c dev: " << i2c_dev << ", errno: " << errno << " (" - << strerror(errno) << ")" << std::endl; - return false; - } + const uint32_t value = static_cast<uint32_t>( + enable ? ExposureMode::AutoExposureContinious : ExposureMode::Manual); - return true; + return m_i2c->write(static_cast<uint16_t>(Register::Exposure_Mode), value); } -bool VeyeIMX287m::setExposureTimeUs(int valueUs) +std::optional<bool> VeyeIMX287m::get_autoExposure() { - std::cout << "AAAAAAAAAAAAAAAAAAAAAAAAAAAAA: " << __func__ << ": " << valueUs << std::endl; - const std::string i2c_dev{"/dev/i2c-2"}; - const auto address = 0x3b; - const auto metime_reg = 0xc10; + using namespace veye::imx287m; - //return true; - std::cout << __func__ << ": " << V4L2_CID_EXPOSURE << " - " << valueUs << std::endl - << std::flush; + const auto value = m_i2c->read( + static_cast<uint32_t>(Register::Exposure_Mode)); - /* - * Shutter Time. Value is from 8721ns to 8721*885ns, must be integral - * multiple of 8721ns . - * 8721xN(N =1,2,3,4,5.....855) - */ - // constexpr int exposureStep{8721}; - // constexpr int maxExposureStepMultiplier{885}; - // auto valueNs = valueUs; - // valueNs = (valueNs / exposureStep) * exposureStep; + if (!value) { + return {}; + } - // std::clamp(valueNs, exposureStep, exposureStep * maxExposureStepMultiplier); - // setGain(rand() % 254); - // setGain(3); - // setLaserLevel(rand() % 0x7fffffff); - // setLaserLevel(rand() % 100); - // int exp = rand() % 10; - // return setCamParam(V4L2_CID_EXPOSURE, exp * exp * exp * exp * exp * exp); - // return setCamParam(V4L2_CID_EXPOSURE, valueUs); - return setCamParam(V4L2_CID_EXPOSURE, valueUs); + return *value + == static_cast<uint32_t>(ExposureMode::AutoExposureContinious); } -bool VeyeIMX287m::setGain(int value) +bool VeyeIMX287m::set_autoGain(const bool enable) { - std::cout << __func__ << ": " << value << std::endl << std::flush; + using namespace veye::imx287m; - // return setCamParam(V4L2_CID_GAIN, value); - // FIXME: tmp workaround for imx287llr - return true; + const uint32_t value = static_cast<uint32_t>( + enable ? GainMode::AutoGainContinious : GainMode::Manual); + + return m_i2c->write(static_cast<uint16_t>(Register::Gain_Mode), value); } -bool VeyeIMX287m::setLaserLevel(int value) +std::optional<bool> VeyeIMX287m::get_autoGain() { - std::cout << __func__ << ": " << value << std::endl << std::flush; + using namespace veye::imx287m; - // return setCamParam(V4L2_CID_FLASH_TIMEOUT, value); + const auto value = m_i2c->read(static_cast<uint32_t>(Register::Gain_Mode)); - // FIXME: tmp workaround for imx287llr - return true; + if (!value) { + return {}; + } + + return *value == static_cast<uint32_t>(GainMode::AutoGainContinious); } -bool VeyeIMX287m::setSomething(int value) +bool VeyeIMX287m::set_exposureTime(const std::chrono::microseconds us) { - std::cout << __func__ << ": " << value << std::endl << std::flush; - - // return setCamParam(V4L2_CID_FLASH_INTENSITY, value); - // FIXME: tmp workaround for imx287llr - return true; + using namespace veye::imx287m; + return m_i2c->write(static_cast<uint16_t>(Register::ME_Time), us.count()); } -bool VeyeIMX287m::setCamParam(unsigned int v4l2controlId, int value) +std::optional<const std::chrono::microseconds> VeyeIMX287m::get_exposureTime() { - veye::imx287m::test(value); + using namespace veye::imx287m; - std::cout << "radxa: skip setCamParam" << std::endl; + const auto value = m_i2c->read(static_cast<uint32_t>(Register::ME_Time)); - return true; - - v4l2_control ctl{v4l2controlId, value}; + if (!value) { + return {}; + } - if (ioctl(m_cam_fd, VIDIOC_S_CTRL, &ctl) < 0) { - fprintf(stderr, - "cannot set cam param: id - %d, error - '%s'\n", - v4l2controlId, - strerror(errno)); - fflush(stderr); + return std::chrono::microseconds{*value}; +} - return false; - } +bool VeyeIMX287m::set_gain(const float value) +{ + using namespace veye::imx287m; + return m_i2c->write(static_cast<uint16_t>(Register::Manual_Gain), + static_cast<uint32_t>(value * 10)); +} - if (ioctl(m_cam_fd, VIDIOC_G_CTRL, &ctl) < 0) { - fprintf(stderr, - "cannot get cam param: id - %d, error - '%s'\n", - v4l2controlId, - strerror(errno)); +std::optional<float> VeyeIMX287m::get_gain() +{ + using namespace veye::imx287m; - fflush(stderr); + const auto value = m_i2c->read(static_cast<uint32_t>(Register::Manual_Gain)); - return false; + if (!value) { + return {}; } - std::cout << __func__ << ": new value is " << ctl.value << std::endl; + return *value * 10; +} + +bool VeyeIMX287m::setLaserLevel(int value) +{ + std::cout << __func__ << ": " << value << std::endl << std::flush; + + // return setCamParam(V4L2_CID_FLASH_TIMEOUT, value); + // FIXME: tmp workaround for imx287llr return true; } @@ -435,7 +410,10 @@ bool VeyeIMX287m::openCam() m_cam_fd = open(videoDevice, O_RDWR); if (m_cam_fd < 0) { - fprintf(stderr, "cannot open cam '%s', error: '%s'\n", videoDevice, strerror(errno)); + fprintf(stderr, + "cannot open cam '%s', error: '%s'\n", + videoDevice, + strerror(errno)); return false; } @@ -448,7 +426,10 @@ bool VeyeIMX287m::selectCam(int camIdx) int ret = ioctl(m_cam_fd, VIDIOC_S_INPUT, &input); if (ret < 0) { - fprintf(stderr, "cannot select cam: idx - %d, error - '%s'\n", camIdx, strerror(errno)); + fprintf(stderr, + "cannot select cam: idx - %d, error - '%s'\n", + camIdx, + strerror(errno)); return false; } @@ -474,7 +455,9 @@ bool VeyeIMX287m::initCam() ret = ioctl(m_cam_fd, VIDIOC_TRY_FMT, &format); if (ret < 0) { - fprintf(stderr, "cannot try cam format: error - '%s'\n", strerror(errno)); + fprintf(stderr, + "cannot try cam format: error - '%s'\n", + strerror(errno)); return false; } @@ -485,7 +468,9 @@ bool VeyeIMX287m::initCam() ret = ioctl(m_cam_fd, VIDIOC_S_FMT, &format); if (ret < 0) { - fprintf(stderr, "cannot set cam format: error - '%s'\n", strerror(errno)); + fprintf(stderr, + "cannot set cam format: error - '%s'\n", + strerror(errno)); return false; } @@ -541,7 +526,9 @@ bool VeyeIMX287m::initCam() ret = ioctl(m_cam_fd, VIDIOC_REQBUFS, &rb); if (ret < 0) { - fprintf(stderr, "cannot set cam request buffers: ioctl error - '%s'\n", strerror(errno)); + fprintf(stderr, + "cannot set cam request buffers: ioctl error - '%s'\n", + strerror(errno)); return false; } @@ -565,7 +552,8 @@ bool VeyeIMX287m::initCam() std::cout << "query buffers" << std::endl; for (uint32_t i = 0; i < rb.count; i++) { - std::cout << "-----------------------------------------------------" << std::endl; + std::cout << "-----------------------------------------------------" + << std::endl; struct v4l2_buffer buf; struct v4l2_plane planes[VIDEO_MAX_PLANES]; @@ -583,8 +571,8 @@ bool VeyeIMX287m::initCam() if (ret < 0) { // std::cout << "ioctl(VIDIOC_QUERYBUF) failed: " << errno << " " << std::endl; - std::cerr << "ioctl(VIDIOC_QUERYBUF) failed: " << errno << " (" << strerror(errno) - << ")" << std::endl; + std::cerr << "ioctl(VIDIOC_QUERYBUF) failed: " << errno << " (" + << strerror(errno) << ")" << std::endl; return false; } @@ -597,9 +585,15 @@ bool VeyeIMX287m::initCam() const auto length = buf.m.planes[0].length; const auto offset = buf.m.planes[0].m.mem_offset; - buffers[i].mem[0] = mmap(0, length, PROT_READ | PROT_WRITE, MAP_SHARED, m_cam_fd, offset); + buffers[i].mem[0] = mmap(0, + length, + PROT_READ | PROT_WRITE, + MAP_SHARED, + m_cam_fd, + offset); if (buffers[i].mem[0] == MAP_FAILED) { - std::cerr << "mmap() failed: " << errno << " (" << strerror(errno) << ")" << std::endl; + std::cerr << "mmap() failed: " << errno << " (" << strerror(errno) + << ")" << std::endl; std::cerr << "length: " << length << std::endl; std::cerr << "offset: " << offset << std::endl; return false; @@ -616,15 +610,18 @@ bool VeyeIMX287m::initCam() buffers[i].size[i] = length; buffers[i].padding[i] = 0; - printf("Buffer %u/%u mapped at address %p.\n", buffers[i].idx, i, buffers[i].mem[0]); + printf("Buffer %u/%u mapped at address %p.\n", + buffers[i].idx, + i, + buffers[i].mem[0]); // buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; // buf.memory = V4L2_MEMORY_MMAP; // buf.index = i; ret = ioctl(m_cam_fd, VIDIOC_QBUF, &buf); if (ret != 0) { - std::cerr << "ioctl(VIDIOC_QBUF) failed: " << errno << " (" << strerror(errno) << ")" - << std::endl; + std::cerr << "ioctl(VIDIOC_QBUF) failed: " << errno << " (" + << strerror(errno) << ")" << std::endl; return false; } @@ -650,6 +647,13 @@ bool VeyeIMX287m::initCam() return true; } +bool VeyeIMX287m::initI2C() +{ + m_i2c = std::make_shared<veye::imx287m::i2c>(); + + return m_i2c != nullptr && m_i2c->open(); +} + bool VeyeIMX287m::initHttpServer() { m_httpServer = std::make_shared<HttpServer>(this); @@ -761,8 +765,8 @@ bool VeyeIMX287m::dequeueImageBuffer(size_t &imageIndex) } if (ret != 0) { - std::cerr << "ioctl(VIDIOC_DQBUF) failed: " << errno << " (" << strerror(errno) << ")" - << std::endl; + std::cerr << "ioctl(VIDIOC_DQBUF) failed: " << errno << " (" + << strerror(errno) << ")" << std::endl; return false; } @@ -780,11 +784,13 @@ bool VeyeIMX287m::dequeueImageBuffer(size_t &imageIndex) // image.counters.encoderPosition = RotaryEncoder::instance()->position(); image.counters.measurementCounter = buf.sequence; + // FIXME: git rid of static vars static int64_t prevCounter = buf.sequence; dropped_count += buf.sequence - prevCounter - 1; prevCounter = buf.sequence; - image.counters.timestampUs = buf.timestamp.tv_sec * 1000 * 1000 + buf.timestamp.tv_usec; + image.counters.timestampUs = buf.timestamp.tv_sec * 1000 * 1000 + + buf.timestamp.tv_usec; { std::lock_guard<std::mutex> lock(m_camMtx); @@ -792,8 +798,8 @@ bool VeyeIMX287m::dequeueImageBuffer(size_t &imageIndex) } if (ret != 0) { - std::cerr << "ioctl(VIDIOC_QBUF) failed: " << errno << " (" << strerror(errno) << ")" - << std::endl; + std::cerr << "ioctl(VIDIOC_QBUF) failed: " << errno << " (" + << strerror(errno) << ")" << std::endl; return false; } |
