blob: 5949048bce8bafd8ad1b0139b402664a9abb801a [file] [log] [blame]
Ravago Jonese8700072023-01-14 19:41:56 -08001#include <linux/videodev2.h>
2#include <sys/ioctl.h>
3
Austin Schuhdb2ed9d2022-12-26 14:02:26 -08004#include "absl/strings/str_cat.h"
5#include "absl/strings/str_split.h"
6#include "aos/events/shm_event_loop.h"
7#include "aos/init.h"
Austin Schuh9f164e92022-12-29 16:15:28 -08008#include "aos/realtime.h"
Austin Schuhdb2ed9d2022-12-26 14:02:26 -08009#include "frc971/vision/media_device.h"
10#include "frc971/vision/v4l2_reader.h"
Ravago Jonese8700072023-01-14 19:41:56 -080011#include "y2023/vision/rkisp1-config.h"
Austin Schuhdb2ed9d2022-12-26 14:02:26 -080012
13DEFINE_string(config, "aos_config.json", "Path to the config file to use.");
Ravago Jonese8700072023-01-14 19:41:56 -080014DEFINE_bool(lowlight_camera, true, "Switch to use imx462 image sensor.");
15
16DEFINE_double(red, 1.252, "Red gain");
17DEFINE_double(green, 1, "Green gain");
18DEFINE_double(blue, 1.96, "Blue gain");
Austin Schuhdb2ed9d2022-12-26 14:02:26 -080019
Maxwell Hendersonad312342023-01-10 12:07:47 -080020namespace y2023 {
Austin Schuhdb2ed9d2022-12-26 14:02:26 -080021namespace vision {
22namespace {
23
24using namespace frc971::vision;
25
Austin Schuhdb2ed9d2022-12-26 14:02:26 -080026void CameraReaderMain() {
27 std::optional<MediaDevice> media_device = FindMediaDevice("platform:rkisp1");
28
29 if (VLOG_IS_ON(1)) {
30 media_device->Log();
31 }
32
Ravago Jonesa0a2e062023-01-03 21:45:18 -080033 int width = 1296;
34 int height = 972;
35 int color_format = MEDIA_BUS_FMT_SBGGR10_1X10;
36 std::string camera_device_string = "ov5647 4-0036";
37 if (FLAGS_lowlight_camera) {
38 width = 1920;
39 height = 1080;
40 color_format = MEDIA_BUS_FMT_SRGGB10_1X10;
Ravago Jonesda1b0082023-01-21 15:33:19 -080041 camera_device_string = "arducam-pivariety 4-000c";
Ravago Jonesa0a2e062023-01-03 21:45:18 -080042 }
43
Austin Schuhdb2ed9d2022-12-26 14:02:26 -080044 media_device->Reset();
45
Ravago Jonesa0a2e062023-01-03 21:45:18 -080046 Entity *camera = media_device->FindEntity(camera_device_string);
47 camera->pads()[0]->SetSubdevFormat(width, height, color_format);
Austin Schuhdb2ed9d2022-12-26 14:02:26 -080048
49 Entity *rkisp1_csi = media_device->FindEntity("rkisp1_csi");
Ravago Jonesa0a2e062023-01-03 21:45:18 -080050 rkisp1_csi->pads()[0]->SetSubdevFormat(width, height, color_format);
51 rkisp1_csi->pads()[1]->SetSubdevFormat(width, height, color_format);
Austin Schuhdb2ed9d2022-12-26 14:02:26 -080052
53 // TODO(austin): Should we set this on the link?
Austin Schuhdb2ed9d2022-12-26 14:02:26 -080054 Entity *rkisp1_isp = media_device->FindEntity("rkisp1_isp");
Ravago Jonesa0a2e062023-01-03 21:45:18 -080055 rkisp1_isp->pads(0)->SetSubdevFormat(width, height, color_format);
56 rkisp1_isp->pads(0)->SetSubdevCrop(width, height);
Austin Schuhdb2ed9d2022-12-26 14:02:26 -080057
Ravago Jonesa0a2e062023-01-03 21:45:18 -080058 rkisp1_isp->pads(2)->SetSubdevFormat(width, height, MEDIA_BUS_FMT_YUYV8_2X8);
59 rkisp1_isp->pads(2)->SetSubdevCrop(width, height);
Austin Schuhdb2ed9d2022-12-26 14:02:26 -080060
61 Entity *rkisp1_resizer_selfpath =
62 media_device->FindEntity("rkisp1_resizer_selfpath");
Ravago Jonesa0a2e062023-01-03 21:45:18 -080063 rkisp1_resizer_selfpath->pads(0)->SetSubdevFormat(width, height,
Austin Schuhdb2ed9d2022-12-26 14:02:26 -080064 MEDIA_BUS_FMT_YUYV8_2X8);
Ravago Jonese3182ee2023-01-28 22:33:05 -080065 rkisp1_resizer_selfpath->pads(1)->SetSubdevFormat(
66 width * 2 / 3, height * 2 / 3, MEDIA_BUS_FMT_YUYV8_2X8);
Ravago Jonesa0a2e062023-01-03 21:45:18 -080067 rkisp1_resizer_selfpath->pads(0)->SetSubdevCrop(width, height);
Austin Schuhdb2ed9d2022-12-26 14:02:26 -080068
69 Entity *rkisp1_resizer_mainpath =
70 media_device->FindEntity("rkisp1_resizer_mainpath");
Ravago Jonesa0a2e062023-01-03 21:45:18 -080071 rkisp1_resizer_mainpath->pads(0)->SetSubdevFormat(width, height,
Austin Schuhdb2ed9d2022-12-26 14:02:26 -080072 MEDIA_BUS_FMT_YUYV8_2X8);
Ravago Jones65469be2023-01-13 21:28:23 -080073
Ravago Jonesa0a2e062023-01-03 21:45:18 -080074 rkisp1_resizer_mainpath->pads(0)->SetSubdevCrop(width, height);
75 rkisp1_resizer_mainpath->pads(1)->SetSubdevFormat(width / 2, height / 2,
Austin Schuhdb2ed9d2022-12-26 14:02:26 -080076 MEDIA_BUS_FMT_YUYV8_2X8);
Austin Schuhdb2ed9d2022-12-26 14:02:26 -080077
78 Entity *rkisp1_mainpath = media_device->FindEntity("rkisp1_mainpath");
Ravago Jonesa0a2e062023-01-03 21:45:18 -080079 rkisp1_mainpath->SetFormat(width / 2, height / 2, V4L2_PIX_FMT_YUV422P);
Austin Schuhdb2ed9d2022-12-26 14:02:26 -080080
81 Entity *rkisp1_selfpath = media_device->FindEntity("rkisp1_selfpath");
Ravago Jonese3182ee2023-01-28 22:33:05 -080082 rkisp1_selfpath->SetFormat(width * 2 / 3, height * 2 / 3, V4L2_PIX_FMT_YUYV);
Austin Schuhdb2ed9d2022-12-26 14:02:26 -080083
Ravago Jones65469be2023-01-13 21:28:23 -080084 media_device->Enable(
Ravago Jonesa0a2e062023-01-03 21:45:18 -080085 media_device->FindLink(camera_device_string, 0, "rkisp1_csi", 0));
Ravago Jones65469be2023-01-13 21:28:23 -080086 media_device->Enable(
87 media_device->FindLink("rkisp1_csi", 1, "rkisp1_isp", 0));
88 media_device->Enable(
89 media_device->FindLink("rkisp1_isp", 2, "rkisp1_resizer_selfpath", 0));
90 media_device->Enable(
91 media_device->FindLink("rkisp1_isp", 2, "rkisp1_resizer_mainpath", 0));
92
Austin Schuhdb2ed9d2022-12-26 14:02:26 -080093 aos::FlatbufferDetachedBuffer<aos::Configuration> config =
94 aos::configuration::ReadConfig(FLAGS_config);
95
96 aos::ShmEventLoop event_loop(&config.message());
97
98 event_loop.SetRuntimeRealtimePriority(55);
Austin Schuh9f164e92022-12-29 16:15:28 -080099 event_loop.SetRuntimeAffinity(aos::MakeCpusetFromCpus({2}));
Austin Schuhdb2ed9d2022-12-26 14:02:26 -0800100
Ravago Jones65469be2023-01-13 21:28:23 -0800101 RockchipV4L2Reader v4l2_reader(&event_loop, event_loop.epoll(),
Ravago Jonesa0a2e062023-01-03 21:45:18 -0800102 rkisp1_selfpath->device(), camera->device());
Ravago Jones65469be2023-01-13 21:28:23 -0800103
Ravago Jonesa0a2e062023-01-03 21:45:18 -0800104 if (FLAGS_lowlight_camera) {
Ravago Jonesda1b0082023-01-21 15:33:19 -0800105 v4l2_reader.SetGainExt(100);
106 v4l2_reader.SetVerticalBlanking(1000);
Ravago Jonese8700072023-01-14 19:41:56 -0800107 v4l2_reader.SetExposure(150);
Ravago Jonesa0a2e062023-01-03 21:45:18 -0800108 } else {
109 v4l2_reader.SetGainExt(1000);
110 v4l2_reader.SetExposure(1000);
111 }
Austin Schuhdb2ed9d2022-12-26 14:02:26 -0800112
Ravago Jonese8700072023-01-14 19:41:56 -0800113 {
114 Entity *rkisp1_params = media_device->FindEntity("rkisp1_params");
115
116 LOG(INFO) << "Opening " << rkisp1_params->device();
117 aos::ScopedFD fd(open(rkisp1_params->device().c_str(), O_RDWR));
118 PCHECK(fd >= 0);
119
120 struct v4l2_capability capability;
121 memset(&capability, 0, sizeof(capability));
122 PCHECK(ioctl(fd.get(), VIDIOC_QUERYCAP, &capability) == 0);
123 CHECK(capability.device_caps & V4L2_CAP_META_OUTPUT);
124
125 // V4L2_META_FMT_RK_ISP1_PARAMS
126 // RK1P
127 uint32_t meta_params_format = (uint32_t)('R') | ((uint32_t)('K') << 8) |
128 ((uint32_t)('1') << 16) |
129 ((uint32_t)('P') << 24);
130 struct v4l2_format format;
131 std::memset(&format, 0, sizeof(format));
132 format.type = V4L2_BUF_TYPE_META_OUTPUT;
133
134 PCHECK(ioctl(fd.get(), VIDIOC_G_FMT, &format) == 0);
135 CHECK_EQ(format.fmt.meta.buffersize, 3048ul);
136 CHECK_EQ(format.fmt.meta.dataformat, meta_params_format);
137
138 struct v4l2_requestbuffers request;
139 memset(&request, 0, sizeof(request));
140 request.count = 1;
141 request.type = V4L2_BUF_TYPE_META_OUTPUT;
142 request.memory = V4L2_MEMORY_USERPTR;
143 PCHECK(ioctl(fd.get(), VIDIOC_REQBUFS, &request) == 0);
144
145 struct rkisp1_params_cfg configuration;
146 memset(&configuration, 0, sizeof(configuration));
147
148 configuration.module_cfg_update |= RKISP1_CIF_ISP_MODULE_AWB_GAIN;
149
150 configuration.others.awb_gain_config.gain_red = 256 * FLAGS_red;
151 configuration.others.awb_gain_config.gain_green_r = 256 * FLAGS_green;
152 configuration.others.awb_gain_config.gain_blue = 256 * FLAGS_blue;
153 configuration.others.awb_gain_config.gain_green_b = 256 * FLAGS_green;
154
155 // Enable the AWB gains
156 configuration.module_en_update |= RKISP1_CIF_ISP_MODULE_AWB_GAIN;
157 configuration.module_ens |= RKISP1_CIF_ISP_MODULE_AWB_GAIN;
158
159 struct v4l2_buffer buffer;
160 memset(&buffer, 0, sizeof(buffer));
161 buffer.memory = V4L2_MEMORY_USERPTR;
162 buffer.index = 0;
163 buffer.type = V4L2_BUF_TYPE_META_OUTPUT;
164 buffer.m.userptr = reinterpret_cast<uintptr_t>(&configuration);
165 buffer.length = format.fmt.meta.buffersize;
166
167 int type = V4L2_BUF_TYPE_META_OUTPUT;
168 PCHECK(ioctl(fd.get(), VIDIOC_STREAMON, &type) == 0);
169
170 PCHECK(ioctl(fd.get(), VIDIOC_QBUF, &buffer) == 0);
171 CHECK(buffer.flags & V4L2_BUF_FLAG_QUEUED);
172
173 PCHECK(ioctl(fd.get(), VIDIOC_DQBUF, &buffer) == 0);
174 }
175
Austin Schuhdb2ed9d2022-12-26 14:02:26 -0800176 event_loop.Run();
177}
178
179} // namespace
180} // namespace vision
Maxwell Hendersonad312342023-01-10 12:07:47 -0800181} // namespace y2023
Austin Schuhdb2ed9d2022-12-26 14:02:26 -0800182
183int main(int argc, char **argv) {
184 aos::InitGoogle(&argc, &argv);
Maxwell Hendersonad312342023-01-10 12:07:47 -0800185 y2023::vision::CameraReaderMain();
Austin Schuhdb2ed9d2022-12-26 14:02:26 -0800186}