You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
134 lines
7.1 KiB
134 lines
7.1 KiB
#include <cmath>
|
|
|
|
#include "system/camerad/sensors/sensor.h"
|
|
|
|
namespace {
|
|
|
|
const float sensor_analog_gains_OS04C10[] = {
|
|
1.0, 1.0625, 1.125, 1.1875, 1.25, 1.3125, 1.375, 1.4375, 1.5, 1.5625, 1.6875,
|
|
1.8125, 1.9375, 2.0, 2.125, 2.25, 2.375, 2.5, 2.625, 2.75, 2.875, 3.0,
|
|
3.125, 3.375, 3.625, 3.875, 4.0, 4.25, 4.5, 4.75, 5.0, 5.25, 5.5,
|
|
5.75, 6.0, 6.25, 6.5, 7.0, 7.5, 8.0, 8.5, 9.0, 9.5, 10.0,
|
|
10.5, 11.0, 11.5, 12.0, 12.5, 13.0, 13.5, 14.0, 14.5, 15.0, 15.5};
|
|
|
|
const uint32_t os04c10_analog_gains_reg[] = {
|
|
0x080, 0x088, 0x090, 0x098, 0x0A0, 0x0A8, 0x0B0, 0x0B8, 0x0C0, 0x0C8, 0x0D8,
|
|
0x0E8, 0x0F8, 0x100, 0x110, 0x120, 0x130, 0x140, 0x150, 0x160, 0x170, 0x180,
|
|
0x190, 0x1B0, 0x1D0, 0x1F0, 0x200, 0x220, 0x240, 0x260, 0x280, 0x2A0, 0x2C0,
|
|
0x2E0, 0x300, 0x320, 0x340, 0x380, 0x3C0, 0x400, 0x440, 0x480, 0x4C0, 0x500,
|
|
0x540, 0x580, 0x5C0, 0x600, 0x640, 0x680, 0x6C0, 0x700, 0x740, 0x780, 0x7C0};
|
|
|
|
} // namespace
|
|
|
|
OS04C10::OS04C10() {
|
|
image_sensor = cereal::FrameData::ImageSensor::OS04C10;
|
|
bayer_pattern = CAM_ISP_PATTERN_BAYER_BGBGBG;
|
|
pixel_size_mm = 0.004;
|
|
data_word = false;
|
|
|
|
// hdr_offset = 64 * 2 + 8; // stagger
|
|
frame_width = 1344;
|
|
frame_height = 760; //760 * 2 + hdr_offset;
|
|
frame_stride = (frame_width * 12 / 8); // no alignment
|
|
|
|
extra_height = 0;
|
|
frame_offset = 0;
|
|
|
|
start_reg_array.assign(std::begin(start_reg_array_os04c10), std::end(start_reg_array_os04c10));
|
|
init_reg_array.assign(std::begin(init_array_os04c10), std::end(init_array_os04c10));
|
|
probe_reg_addr = 0x300a;
|
|
probe_expected_data = 0x5304;
|
|
bits_per_pixel = 12;
|
|
mipi_format = CAM_FORMAT_MIPI_RAW_12;
|
|
frame_data_type = 0x2c;
|
|
mclk_frequency = 24000000; // Hz
|
|
|
|
// TODO: this was set from logs. actually calculate it out
|
|
readout_time_ns = 11000000;
|
|
|
|
ev_scale = 150.0;
|
|
dc_gain_factor = 1;
|
|
dc_gain_min_weight = 1; // always on is fine
|
|
dc_gain_max_weight = 1;
|
|
dc_gain_on_grey = 0.9;
|
|
dc_gain_off_grey = 1.0;
|
|
exposure_time_min = 2;
|
|
exposure_time_max = 1684;
|
|
analog_gain_min_idx = 0x0;
|
|
analog_gain_rec_idx = 0x0; // 1x
|
|
analog_gain_max_idx = 0x28;
|
|
analog_gain_cost_delta = -1;
|
|
analog_gain_cost_low = 0.4;
|
|
analog_gain_cost_high = 6.4;
|
|
for (int i = 0; i <= analog_gain_max_idx; i++) {
|
|
sensor_analog_gains[i] = sensor_analog_gains_OS04C10[i];
|
|
}
|
|
min_ev = exposure_time_min * sensor_analog_gains[analog_gain_min_idx];
|
|
max_ev = exposure_time_max * dc_gain_factor * sensor_analog_gains[analog_gain_max_idx];
|
|
target_grey_factor = 0.01;
|
|
|
|
black_level = 48;
|
|
color_correct_matrix = {
|
|
0x000000c2, 0x00000fe0, 0x00000fde,
|
|
0x00000fa7, 0x000000d9, 0x00001000,
|
|
0x00000fca, 0x00000fef, 0x000000c7,
|
|
};
|
|
for (int i = 0; i < 65; i++) {
|
|
float fx = i / 64.0;
|
|
gamma_lut_rgb.push_back((uint32_t)((10*fx)/(1+9*fx)*1023.0 + 0.5));
|
|
}
|
|
prepare_gamma_lut();
|
|
linearization_lut = {
|
|
0x02000000, 0x02000000, 0x02000000, 0x02000000,
|
|
0x020007ff, 0x020007ff, 0x020007ff, 0x020007ff,
|
|
0x02000bff, 0x02000bff, 0x02000bff, 0x02000bff,
|
|
0x020017ff, 0x020017ff, 0x020017ff, 0x020017ff,
|
|
0x02001bff, 0x02001bff, 0x02001bff, 0x02001bff,
|
|
0x020023ff, 0x020023ff, 0x020023ff, 0x020023ff,
|
|
0x00003fff, 0x00003fff, 0x00003fff, 0x00003fff,
|
|
0x00003fff, 0x00003fff, 0x00003fff, 0x00003fff,
|
|
0x00003fff, 0x00003fff, 0x00003fff, 0x00003fff,
|
|
};
|
|
linearization_pts = {0x07ff0bff, 0x17ff1bff, 0x23ff3fff, 0x3fff3fff};
|
|
vignetting_lut = {
|
|
0x01064832, 0x00da26d1, 0x00bb25d9, 0x00aac556, 0x00a06503, 0x009a64d3, 0x009744ba, 0x009744ba, 0x009a24d1, 0x00a00500, 0x00aa2551, 0x00ba45d2, 0x00d826c1, 0x01040820, 0x013729b9, 0x0171ab8d, 0x01b36d9b,
|
|
0x00eee777, 0x00c2c616, 0x00ae2571, 0x009fe4ff, 0x0096e4b7, 0x0090e487, 0x008d446a, 0x008d2469, 0x0090a485, 0x009684b4, 0x009f64fb, 0x00ad456a, 0x00c1a60d, 0x00eca765, 0x011fc8fe, 0x015a4ad2, 0x019c0ce0,
|
|
0x00dee6f7, 0x00b9c5ce, 0x00a5652b, 0x009964cb, 0x00904482, 0x00892449, 0x0085842c, 0x0085642b, 0x0088e447, 0x008fe47f, 0x0098e4c7, 0x00a4c526, 0x00b8a5c5, 0x00dc86e4, 0x010fc87e, 0x014a2a51, 0x018c0c60,
|
|
0x00d626b1, 0x00b4e5a7, 0x00a1e50f, 0x0095e4af, 0x008c2461, 0x00850428, 0x0081640b, 0x0081440a, 0x0084a425, 0x008ba45d, 0x009564ab, 0x00a1450a, 0x00b3c59e, 0x00d3e69f, 0x01070838, 0x01418a0c, 0x01834c1a,
|
|
0x00d4c6a6, 0x00b425a1, 0x00a1450a, 0x009544aa, 0x008b645b, 0x00844422, 0x0080a405, 0x0080a405, 0x00840420, 0x008b0458, 0x0094c4a6, 0x00a0a505, 0x00b30598, 0x00d26693, 0x0105a82d, 0x01402a01, 0x0181ec0f,
|
|
0x00daa6d5, 0x00b765bb, 0x00a3c51e, 0x0097a4bd, 0x008e4472, 0x00872439, 0x0083841c, 0x0083641b, 0x0086e437, 0x008de46f, 0x009724b9, 0x00a30518, 0x00b665b3, 0x00d866c3, 0x010b885c, 0x01460a30, 0x0187ec3f,
|
|
0x00e80740, 0x00bec5f6, 0x00aa6553, 0x009d24e9, 0x009404a0, 0x008d846c, 0x0089e44f, 0x0089e44f, 0x008d446a, 0x0093c49e, 0x009ca4e5, 0x00a9854c, 0x00bdc5ee, 0x00e5a72d, 0x0118c8c6, 0x01534a9a, 0x01952ca9,
|
|
0x00fca7e5, 0x00d06683, 0x00b5c5ae, 0x00a5852c, 0x009c84e4, 0x009664b3, 0x0093649b, 0x0093449a, 0x009624b1, 0x009c24e1, 0x00a50528, 0x00b4e5a7, 0x00ce8674, 0x00fa47d2, 0x012d696b, 0x0167eb3f, 0x01a9cd4e,
|
|
0x011888c4, 0x00ec6763, 0x00c7863c, 0x00b4e5a7, 0x00a8a545, 0x00a1c50e, 0x009ec4f6, 0x009ea4f5, 0x00a1a50d, 0x00a82541, 0x00b445a2, 0x00c5e62f, 0x00ea6753, 0x011648b2, 0x01496a4b, 0x0183ec1f, 0x01c5ae2d,
|
|
0x013bc9de, 0x010fa87d, 0x00eac756, 0x00cd466a, 0x00bc25e1, 0x00b405a0, 0x00afc57e, 0x00afa57d, 0x00b3a59d, 0x00bbc5de, 0x00cc0660, 0x00e92749, 0x010da86d, 0x013989cc, 0x016cab65, 0x01a72d39, 0x01e8ef47,
|
|
0x01666b33, 0x013a49d2, 0x011568ab, 0x00f7e7bf, 0x00e1c70e, 0x00d2e697, 0x00cb665b, 0x00cb2659, 0x00d26693, 0x00e0c706, 0x00f6a7b5, 0x0113c89e, 0x013849c2, 0x01642b21, 0x01974cba, 0x01d1ce8e, 0x0213909c,
|
|
0x01986cc3, 0x016c2b61, 0x01476a3b, 0x0129e94f, 0x0113a89d, 0x0104c826, 0x00fd47ea, 0x00fd27e9, 0x01044822, 0x0112c896, 0x0128a945, 0x0145ca2e, 0x016a4b52, 0x01960cb0, 0x01c92e49, 0x0203b01d, 0x0245922c,
|
|
0x01d1ae8d, 0x01a58d2c, 0x0180ac05, 0x01632b19, 0x014cea67, 0x013e29f1, 0x013689b4, 0x013669b3, 0x013d89ec, 0x014c0a60, 0x0161eb0f, 0x017f0bf8, 0x01a38d1c, 0x01cf4e7a, 0x02029014, 0x023d11e8, 0x027ed3f6,
|
|
};
|
|
}
|
|
|
|
std::vector<i2c_random_wr_payload> OS04C10::getExposureRegisters(int exposure_time, int new_exp_g, bool dc_gain_enabled) const {
|
|
uint32_t long_time = exposure_time;
|
|
uint32_t real_gain = os04c10_analog_gains_reg[new_exp_g];
|
|
|
|
return {
|
|
{0x3501, long_time>>8}, {0x3502, long_time&0xFF},
|
|
{0x3508, real_gain>>8}, {0x3509, real_gain&0xFF},
|
|
{0x350c, real_gain>>8}, {0x350d, real_gain&0xFF},
|
|
};
|
|
}
|
|
|
|
int OS04C10::getSlaveAddress(int port) const {
|
|
assert(port >= 0 && port <= 2);
|
|
return (int[]){0x6C, 0x20, 0x6C}[port];
|
|
}
|
|
|
|
float OS04C10::getExposureScore(float desired_ev, int exp_t, int exp_g_idx, float exp_gain, int gain_idx) const {
|
|
float score = std::abs(desired_ev - (exp_t * exp_gain));
|
|
float m = exp_g_idx > analog_gain_rec_idx ? analog_gain_cost_high : analog_gain_cost_low;
|
|
score += std::abs(exp_g_idx - (int)analog_gain_rec_idx) * m;
|
|
score += ((1 - analog_gain_cost_delta) +
|
|
analog_gain_cost_delta * (exp_g_idx - analog_gain_min_idx) / (analog_gain_max_idx - analog_gain_min_idx)) *
|
|
std::abs(exp_g_idx - gain_idx) * 3.0;
|
|
return score;
|
|
}
|
|
|