summaryrefslogtreecommitdiff
path: root/src/camera/veyeimx287m.cpp
diff options
context:
space:
mode:
authorNikita Kostovsky <nikita@kostovsky.me>2025-11-14 21:05:12 +0100
committerNikita Kostovsky <nikita@kostovsky.me>2025-11-14 21:05:12 +0100
commit5df63c0bc7e3d6f1850d04f5bafbae2dd6fa619e (patch)
tree7b98d59baec4aac62cab374e95795a2ce6b88d03 /src/camera/veyeimx287m.cpp
parent36ef6a75e3418d88227e84ab175c0057e860c151 (diff)
organize things a bit, populate ICamera
Diffstat (limited to 'src/camera/veyeimx287m.cpp')
-rw-r--r--src/camera/veyeimx287m.cpp252
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;
}