blob: b60451627ef280f668fa29f8d85cf53ea30747b0 [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");
Ravago Jones0f2e3a12023-01-29 16:13:29 -080019DEFINE_double(exposure, 150, "Camera exposure");
Austin Schuhdb2ed9d2022-12-26 14:02:26 -080020
Maxwell Hendersonad312342023-01-10 12:07:47 -080021namespace y2023 {
Austin Schuhdb2ed9d2022-12-26 14:02:26 -080022namespace vision {
23namespace {
24
25using namespace frc971::vision;
26
Austin Schuhdb2ed9d2022-12-26 14:02:26 -080027void CameraReaderMain() {
28 std::optional<MediaDevice> media_device = FindMediaDevice("platform:rkisp1");
29
30 if (VLOG_IS_ON(1)) {
31 media_device->Log();
32 }
33
Ravago Jonesa0a2e062023-01-03 21:45:18 -080034 int width = 1296;
35 int height = 972;
36 int color_format = MEDIA_BUS_FMT_SBGGR10_1X10;
37 std::string camera_device_string = "ov5647 4-0036";
38 if (FLAGS_lowlight_camera) {
39 width = 1920;
40 height = 1080;
41 color_format = MEDIA_BUS_FMT_SRGGB10_1X10;
Ravago Jonesda1b0082023-01-21 15:33:19 -080042 camera_device_string = "arducam-pivariety 4-000c";
Ravago Jonesa0a2e062023-01-03 21:45:18 -080043 }
44
Austin Schuhdb2ed9d2022-12-26 14:02:26 -080045 media_device->Reset();
46
Ravago Jonesa0a2e062023-01-03 21:45:18 -080047 Entity *camera = media_device->FindEntity(camera_device_string);
48 camera->pads()[0]->SetSubdevFormat(width, height, color_format);
Austin Schuhdb2ed9d2022-12-26 14:02:26 -080049
50 Entity *rkisp1_csi = media_device->FindEntity("rkisp1_csi");
Ravago Jonesa0a2e062023-01-03 21:45:18 -080051 rkisp1_csi->pads()[0]->SetSubdevFormat(width, height, color_format);
52 rkisp1_csi->pads()[1]->SetSubdevFormat(width, height, color_format);
Austin Schuhdb2ed9d2022-12-26 14:02:26 -080053
54 // TODO(austin): Should we set this on the link?
Austin Schuhdb2ed9d2022-12-26 14:02:26 -080055 Entity *rkisp1_isp = media_device->FindEntity("rkisp1_isp");
Ravago Jonesa0a2e062023-01-03 21:45:18 -080056 rkisp1_isp->pads(0)->SetSubdevFormat(width, height, color_format);
57 rkisp1_isp->pads(0)->SetSubdevCrop(width, height);
Austin Schuhdb2ed9d2022-12-26 14:02:26 -080058
Ravago Jonesa0a2e062023-01-03 21:45:18 -080059 rkisp1_isp->pads(2)->SetSubdevFormat(width, height, MEDIA_BUS_FMT_YUYV8_2X8);
60 rkisp1_isp->pads(2)->SetSubdevCrop(width, height);
Austin Schuhdb2ed9d2022-12-26 14:02:26 -080061
62 Entity *rkisp1_resizer_selfpath =
63 media_device->FindEntity("rkisp1_resizer_selfpath");
Ravago Jonesa0a2e062023-01-03 21:45:18 -080064 rkisp1_resizer_selfpath->pads(0)->SetSubdevFormat(width, height,
Austin Schuhdb2ed9d2022-12-26 14:02:26 -080065 MEDIA_BUS_FMT_YUYV8_2X8);
Ravago Jonese3182ee2023-01-28 22:33:05 -080066 rkisp1_resizer_selfpath->pads(1)->SetSubdevFormat(
67 width * 2 / 3, height * 2 / 3, MEDIA_BUS_FMT_YUYV8_2X8);
Ravago Jonesa0a2e062023-01-03 21:45:18 -080068 rkisp1_resizer_selfpath->pads(0)->SetSubdevCrop(width, height);
Austin Schuhdb2ed9d2022-12-26 14:02:26 -080069
70 Entity *rkisp1_resizer_mainpath =
71 media_device->FindEntity("rkisp1_resizer_mainpath");
Ravago Jonesa0a2e062023-01-03 21:45:18 -080072 rkisp1_resizer_mainpath->pads(0)->SetSubdevFormat(width, height,
Austin Schuhdb2ed9d2022-12-26 14:02:26 -080073 MEDIA_BUS_FMT_YUYV8_2X8);
Ravago Jones65469be2023-01-13 21:28:23 -080074
Ravago Jonesa0a2e062023-01-03 21:45:18 -080075 rkisp1_resizer_mainpath->pads(0)->SetSubdevCrop(width, height);
76 rkisp1_resizer_mainpath->pads(1)->SetSubdevFormat(width / 2, height / 2,
Austin Schuhdb2ed9d2022-12-26 14:02:26 -080077 MEDIA_BUS_FMT_YUYV8_2X8);
Austin Schuhdb2ed9d2022-12-26 14:02:26 -080078
79 Entity *rkisp1_mainpath = media_device->FindEntity("rkisp1_mainpath");
Ravago Jonesa0a2e062023-01-03 21:45:18 -080080 rkisp1_mainpath->SetFormat(width / 2, height / 2, V4L2_PIX_FMT_YUV422P);
Austin Schuhdb2ed9d2022-12-26 14:02:26 -080081
82 Entity *rkisp1_selfpath = media_device->FindEntity("rkisp1_selfpath");
Ravago Jonese3182ee2023-01-28 22:33:05 -080083 rkisp1_selfpath->SetFormat(width * 2 / 3, height * 2 / 3, V4L2_PIX_FMT_YUYV);
Austin Schuhdb2ed9d2022-12-26 14:02:26 -080084
Ravago Jones65469be2023-01-13 21:28:23 -080085 media_device->Enable(
Ravago Jonesa0a2e062023-01-03 21:45:18 -080086 media_device->FindLink(camera_device_string, 0, "rkisp1_csi", 0));
Ravago Jones65469be2023-01-13 21:28:23 -080087 media_device->Enable(
88 media_device->FindLink("rkisp1_csi", 1, "rkisp1_isp", 0));
89 media_device->Enable(
90 media_device->FindLink("rkisp1_isp", 2, "rkisp1_resizer_selfpath", 0));
91 media_device->Enable(
92 media_device->FindLink("rkisp1_isp", 2, "rkisp1_resizer_mainpath", 0));
93
Austin Schuhdb2ed9d2022-12-26 14:02:26 -080094 aos::FlatbufferDetachedBuffer<aos::Configuration> config =
95 aos::configuration::ReadConfig(FLAGS_config);
96
97 aos::ShmEventLoop event_loop(&config.message());
98
99 event_loop.SetRuntimeRealtimePriority(55);
Austin Schuh9f164e92022-12-29 16:15:28 -0800100 event_loop.SetRuntimeAffinity(aos::MakeCpusetFromCpus({2}));
Austin Schuhdb2ed9d2022-12-26 14:02:26 -0800101
Ravago Jones65469be2023-01-13 21:28:23 -0800102 RockchipV4L2Reader v4l2_reader(&event_loop, event_loop.epoll(),
Ravago Jonesa0a2e062023-01-03 21:45:18 -0800103 rkisp1_selfpath->device(), camera->device());
Ravago Jones65469be2023-01-13 21:28:23 -0800104
Ravago Jonesa0a2e062023-01-03 21:45:18 -0800105 if (FLAGS_lowlight_camera) {
Ravago Jonesda1b0082023-01-21 15:33:19 -0800106 v4l2_reader.SetGainExt(100);
107 v4l2_reader.SetVerticalBlanking(1000);
Ravago Jones0f2e3a12023-01-29 16:13:29 -0800108 v4l2_reader.SetExposure(FLAGS_exposure);
Ravago Jonesa0a2e062023-01-03 21:45:18 -0800109 } else {
110 v4l2_reader.SetGainExt(1000);
111 v4l2_reader.SetExposure(1000);
112 }
Austin Schuhdb2ed9d2022-12-26 14:02:26 -0800113
Ravago Jonese8700072023-01-14 19:41:56 -0800114 {
115 Entity *rkisp1_params = media_device->FindEntity("rkisp1_params");
116
117 LOG(INFO) << "Opening " << rkisp1_params->device();
118 aos::ScopedFD fd(open(rkisp1_params->device().c_str(), O_RDWR));
119 PCHECK(fd >= 0);
120
121 struct v4l2_capability capability;
122 memset(&capability, 0, sizeof(capability));
123 PCHECK(ioctl(fd.get(), VIDIOC_QUERYCAP, &capability) == 0);
124 CHECK(capability.device_caps & V4L2_CAP_META_OUTPUT);
125
126 // V4L2_META_FMT_RK_ISP1_PARAMS
127 // RK1P
128 uint32_t meta_params_format = (uint32_t)('R') | ((uint32_t)('K') << 8) |
129 ((uint32_t)('1') << 16) |
130 ((uint32_t)('P') << 24);
131 struct v4l2_format format;
132 std::memset(&format, 0, sizeof(format));
133 format.type = V4L2_BUF_TYPE_META_OUTPUT;
134
135 PCHECK(ioctl(fd.get(), VIDIOC_G_FMT, &format) == 0);
136 CHECK_EQ(format.fmt.meta.buffersize, 3048ul);
137 CHECK_EQ(format.fmt.meta.dataformat, meta_params_format);
138
139 struct v4l2_requestbuffers request;
140 memset(&request, 0, sizeof(request));
141 request.count = 1;
142 request.type = V4L2_BUF_TYPE_META_OUTPUT;
143 request.memory = V4L2_MEMORY_USERPTR;
144 PCHECK(ioctl(fd.get(), VIDIOC_REQBUFS, &request) == 0);
145
146 struct rkisp1_params_cfg configuration;
147 memset(&configuration, 0, sizeof(configuration));
148
149 configuration.module_cfg_update |= RKISP1_CIF_ISP_MODULE_AWB_GAIN;
150
151 configuration.others.awb_gain_config.gain_red = 256 * FLAGS_red;
152 configuration.others.awb_gain_config.gain_green_r = 256 * FLAGS_green;
153 configuration.others.awb_gain_config.gain_blue = 256 * FLAGS_blue;
154 configuration.others.awb_gain_config.gain_green_b = 256 * FLAGS_green;
155
156 // Enable the AWB gains
157 configuration.module_en_update |= RKISP1_CIF_ISP_MODULE_AWB_GAIN;
158 configuration.module_ens |= RKISP1_CIF_ISP_MODULE_AWB_GAIN;
159
160 struct v4l2_buffer buffer;
161 memset(&buffer, 0, sizeof(buffer));
162 buffer.memory = V4L2_MEMORY_USERPTR;
163 buffer.index = 0;
164 buffer.type = V4L2_BUF_TYPE_META_OUTPUT;
165 buffer.m.userptr = reinterpret_cast<uintptr_t>(&configuration);
166 buffer.length = format.fmt.meta.buffersize;
167
168 int type = V4L2_BUF_TYPE_META_OUTPUT;
169 PCHECK(ioctl(fd.get(), VIDIOC_STREAMON, &type) == 0);
170
171 PCHECK(ioctl(fd.get(), VIDIOC_QBUF, &buffer) == 0);
172 CHECK(buffer.flags & V4L2_BUF_FLAG_QUEUED);
173
174 PCHECK(ioctl(fd.get(), VIDIOC_DQBUF, &buffer) == 0);
175 }
176
Austin Schuhdb2ed9d2022-12-26 14:02:26 -0800177 event_loop.Run();
178}
179
180} // namespace
181} // namespace vision
Maxwell Hendersonad312342023-01-10 12:07:47 -0800182} // namespace y2023
Austin Schuhdb2ed9d2022-12-26 14:02:26 -0800183
184int main(int argc, char **argv) {
185 aos::InitGoogle(&argc, &argv);
Maxwell Hendersonad312342023-01-10 12:07:47 -0800186 y2023::vision::CameraReaderMain();
Austin Schuhdb2ed9d2022-12-26 14:02:26 -0800187}