Switch rockpi to use imx290 camera
Our sensor, imx462 is similar enough that the imx290 driver supports it.
This change relies on changes to frc971/linux
Signed-off-by: Ravago Jones <ravagojones@gmail.com>
Change-Id: I7a1ba5367e9ead7cc2b4c1a098102fc4b535d612
diff --git a/frc971/rockpi/.config b/frc971/rockpi/.config
index 5fe3348..636a585 100644
--- a/frc971/rockpi/.config
+++ b/frc971/rockpi/.config
@@ -3366,7 +3366,7 @@
CONFIG_VIDEO_IMX219=m
# CONFIG_VIDEO_IMX258 is not set
# CONFIG_VIDEO_IMX274 is not set
-# CONFIG_VIDEO_IMX290 is not set
+CONFIG_VIDEO_IMX290=m
# CONFIG_VIDEO_IMX319 is not set
# CONFIG_VIDEO_IMX334 is not set
# CONFIG_VIDEO_IMX335 is not set
diff --git a/frc971/vision/v4l2_reader.cc b/frc971/vision/v4l2_reader.cc
index 63e33e6..9b4863e 100644
--- a/frc971/vision/v4l2_reader.cc
+++ b/frc971/vision/v4l2_reader.cc
@@ -340,6 +340,13 @@
}
void RockchipV4L2Reader::SetGain(size_t gain) {
+ v4l2_control gain_control;
+ gain_control.id = V4L2_CID_GAIN;
+ gain_control.value = static_cast<int>(gain);
+ PCHECK(ImageSensorIoctl(VIDIOC_S_CTRL, &gain_control) == 0);
+}
+
+void RockchipV4L2Reader::SetGainExt(size_t gain) {
struct v4l2_ext_controls controls;
memset(&controls, 0, sizeof(controls));
struct v4l2_ext_control control[1];
@@ -354,5 +361,17 @@
PCHECK(ImageSensorIoctl(VIDIOC_S_EXT_CTRLS, &controls) == 0);
}
+void RockchipV4L2Reader::SetBlanking(size_t hblank, size_t vblank) {
+ v4l2_control hblank_control;
+ hblank_control.id = V4L2_CID_HBLANK;
+ hblank_control.value = static_cast<int>(hblank);
+ PCHECK(ImageSensorIoctl(VIDIOC_S_CTRL, &hblank_control) == 0);
+
+ v4l2_control vblank_control;
+ vblank_control.id = V4L2_CID_VBLANK;
+ vblank_control.value = static_cast<int>(vblank);
+ PCHECK(ImageSensorIoctl(VIDIOC_S_CTRL, &vblank_control) == 0);
+}
+
} // namespace vision
} // namespace frc971
diff --git a/frc971/vision/v4l2_reader.h b/frc971/vision/v4l2_reader.h
index 2013113..182160d 100644
--- a/frc971/vision/v4l2_reader.h
+++ b/frc971/vision/v4l2_reader.h
@@ -151,6 +151,9 @@
void SetExposure(size_t duration) override;
void SetGain(size_t gain);
+ void SetGainExt(size_t gain);
+
+ void SetBlanking(size_t hblank, size_t vblank);
private:
void OnImageReady();
diff --git a/y2023/vision/camera_reader.cc b/y2023/vision/camera_reader.cc
index 5105e86..560e9ee 100644
--- a/y2023/vision/camera_reader.cc
+++ b/y2023/vision/camera_reader.cc
@@ -7,6 +7,7 @@
#include "frc971/vision/v4l2_reader.h"
DEFINE_string(config, "aos_config.json", "Path to the config file to use.");
+DEFINE_bool(lowlight_camera, false, "Switch to use imx462 image sensor.");
namespace y2023 {
namespace vision {
@@ -21,48 +22,59 @@
media_device->Log();
}
+ int width = 1296;
+ int height = 972;
+ int color_format = MEDIA_BUS_FMT_SBGGR10_1X10;
+ std::string camera_device_string = "ov5647 4-0036";
+ if (FLAGS_lowlight_camera) {
+ width = 1920;
+ height = 1080;
+ color_format = MEDIA_BUS_FMT_SRGGB10_1X10;
+ camera_device_string = "imx290 4-0036";
+ }
+
media_device->Reset();
- Entity *ov5647 = media_device->FindEntity("ov5647 4-0036");
- ov5647->pads()[0]->SetSubdevFormat(1296, 972, MEDIA_BUS_FMT_SBGGR10_1X10);
+ Entity *camera = media_device->FindEntity(camera_device_string);
+ camera->pads()[0]->SetSubdevFormat(width, height, color_format);
Entity *rkisp1_csi = media_device->FindEntity("rkisp1_csi");
- rkisp1_csi->pads()[0]->SetSubdevFormat(1296, 972, MEDIA_BUS_FMT_SBGGR10_1X10);
- rkisp1_csi->pads()[1]->SetSubdevFormat(1296, 972, MEDIA_BUS_FMT_SBGGR10_1X10);
+ rkisp1_csi->pads()[0]->SetSubdevFormat(width, height, color_format);
+ rkisp1_csi->pads()[1]->SetSubdevFormat(width, height, color_format);
// TODO(austin): Should we set this on the link?
Entity *rkisp1_isp = media_device->FindEntity("rkisp1_isp");
- rkisp1_isp->pads(0)->SetSubdevFormat(1296, 972, MEDIA_BUS_FMT_SBGGR10_1X10);
- rkisp1_isp->pads(0)->SetSubdevCrop(1296, 972);
+ rkisp1_isp->pads(0)->SetSubdevFormat(width, height, color_format);
+ rkisp1_isp->pads(0)->SetSubdevCrop(width, height);
- rkisp1_isp->pads(2)->SetSubdevFormat(1296, 972, MEDIA_BUS_FMT_YUYV8_2X8);
- rkisp1_isp->pads(2)->SetSubdevCrop(1296, 972);
+ rkisp1_isp->pads(2)->SetSubdevFormat(width, height, MEDIA_BUS_FMT_YUYV8_2X8);
+ rkisp1_isp->pads(2)->SetSubdevCrop(width, height);
Entity *rkisp1_resizer_selfpath =
media_device->FindEntity("rkisp1_resizer_selfpath");
- rkisp1_resizer_selfpath->pads(0)->SetSubdevFormat(1296, 972,
+ rkisp1_resizer_selfpath->pads(0)->SetSubdevFormat(width, height,
MEDIA_BUS_FMT_YUYV8_2X8);
- rkisp1_resizer_selfpath->pads(1)->SetSubdevFormat(1296, 972,
+ rkisp1_resizer_selfpath->pads(1)->SetSubdevFormat(width, height,
MEDIA_BUS_FMT_YUYV8_2X8);
- rkisp1_resizer_selfpath->pads(0)->SetSubdevCrop(1296, 972);
+ rkisp1_resizer_selfpath->pads(0)->SetSubdevCrop(width, height);
Entity *rkisp1_resizer_mainpath =
media_device->FindEntity("rkisp1_resizer_mainpath");
- rkisp1_resizer_mainpath->pads(0)->SetSubdevFormat(1296, 972,
+ rkisp1_resizer_mainpath->pads(0)->SetSubdevFormat(width, height,
MEDIA_BUS_FMT_YUYV8_2X8);
- rkisp1_resizer_mainpath->pads(0)->SetSubdevCrop(1296, 972);
- rkisp1_resizer_mainpath->pads(1)->SetSubdevFormat(1296 / 2, 972 / 2,
+ rkisp1_resizer_mainpath->pads(0)->SetSubdevCrop(width, height);
+ rkisp1_resizer_mainpath->pads(1)->SetSubdevFormat(width / 2, height / 2,
MEDIA_BUS_FMT_YUYV8_2X8);
Entity *rkisp1_mainpath = media_device->FindEntity("rkisp1_mainpath");
- rkisp1_mainpath->SetFormat(1296 / 2, 972 / 2, V4L2_PIX_FMT_YUV422P);
+ rkisp1_mainpath->SetFormat(width / 2, height / 2, V4L2_PIX_FMT_YUV422P);
Entity *rkisp1_selfpath = media_device->FindEntity("rkisp1_selfpath");
- rkisp1_selfpath->SetFormat(1296, 972, V4L2_PIX_FMT_YUYV);
+ rkisp1_selfpath->SetFormat(width, height, V4L2_PIX_FMT_YUYV);
media_device->Enable(
- media_device->FindLink("ov5647 4-0036", 0, "rkisp1_csi", 0));
+ media_device->FindLink(camera_device_string, 0, "rkisp1_csi", 0));
media_device->Enable(
media_device->FindLink("rkisp1_csi", 1, "rkisp1_isp", 0));
media_device->Enable(
@@ -78,12 +90,17 @@
event_loop.SetRuntimeRealtimePriority(55);
event_loop.SetRuntimeAffinity(aos::MakeCpusetFromCpus({2}));
-
RockchipV4L2Reader v4l2_reader(&event_loop, event_loop.epoll(),
- rkisp1_selfpath->device(), ov5647->device());
+ rkisp1_selfpath->device(), camera->device());
- v4l2_reader.SetGain(1000);
- v4l2_reader.SetExposure(1000);
+ if (FLAGS_lowlight_camera) {
+ v4l2_reader.SetGain(72);
+ v4l2_reader.SetExposure(30);
+ v4l2_reader.SetBlanking(2480, 45);
+ } else {
+ v4l2_reader.SetGainExt(1000);
+ v4l2_reader.SetExposure(1000);
+ }
event_loop.Run();
}