better OX03C10 settings (#25796)

* ev has different scales

* fix initial gradient

* fix highlight weirdness

* try smooth set of gains

* delay

* add gain idx

* oops

* set different min dc

Co-authored-by: Comma Device <device@comma.ai>
pull/25799/head
ZwX1616 3 years ago committed by GitHub
parent a9f88503fe
commit c7a0f23b45
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 61
      system/camerad/cameras/camera_qcom2.cc
  2. 4
      system/camerad/cameras/camera_qcom2.h
  3. 6
      system/camerad/cameras/sensor2_i2c.h

@ -61,39 +61,48 @@ const float DC_GAIN_OX03C10 = 7.32;
const float DC_GAIN_ON_GREY_AR0231= 0.2; const float DC_GAIN_ON_GREY_AR0231= 0.2;
const float DC_GAIN_OFF_GREY_AR0231 = 0.3; const float DC_GAIN_OFF_GREY_AR0231 = 0.3;
const float DC_GAIN_ON_GREY_OX03C10= 0.3; const float DC_GAIN_ON_GREY_OX03C10= 0.25;
const float DC_GAIN_OFF_GREY_OX03C10 = 0.375; const float DC_GAIN_OFF_GREY_OX03C10 = 0.35;
const int DC_GAIN_MIN_WEIGHT = 0; const int DC_GAIN_MIN_WEIGHT_AR0231 = 0;
const int DC_GAIN_MAX_WEIGHT_AR0231 = 1; const int DC_GAIN_MAX_WEIGHT_AR0231 = 1;
const int DC_GAIN_MIN_WEIGHT_OX03C10 = 16;
const int DC_GAIN_MAX_WEIGHT_OX03C10 = 32; const int DC_GAIN_MAX_WEIGHT_OX03C10 = 32;
const float TARGET_GREY_FACTOR_AR0231 = 1.0;
const float TARGET_GREY_FACTOR_OX03C10 = 0.02;
const float sensor_analog_gains_AR0231[] = { const float sensor_analog_gains_AR0231[] = {
1.0/8.0, 2.0/8.0, 2.0/7.0, 3.0/7.0, // 0, 1, 2, 3 1.0/8.0, 2.0/8.0, 2.0/7.0, 3.0/7.0, // 0, 1, 2, 3
3.0/6.0, 4.0/6.0, 4.0/5.0, 5.0/5.0, // 4, 5, 6, 7 3.0/6.0, 4.0/6.0, 4.0/5.0, 5.0/5.0, // 4, 5, 6, 7
5.0/4.0, 6.0/4.0, 6.0/3.0, 7.0/3.0, // 8, 9, 10, 11 5.0/4.0, 6.0/4.0, 6.0/3.0, 7.0/3.0, // 8, 9, 10, 11
7.0/2.0, 8.0/2.0, 8.0/1.0}; // 12, 13, 14, 15 = bypass 7.0/2.0, 8.0/2.0, 8.0/1.0}; // 12, 13, 14, 15 = bypass
// similar gain curve to AR
const float sensor_analog_gains_OX03C10[] = { const float sensor_analog_gains_OX03C10[] = {
1.0, 1.25, 1.3125, 1.5625, 1.0, 1.125, 1.25, 1.3125, 1.5625,
1.6875, 2.0, 2.25, 2.625, 1.6875, 2.0, 2.25, 2.625, 3.125,
3.125, 3.625, 4.5, 5.0, 3.625, 4.0, 4.5, 5.0, 5.5,
7.25, 8.5, 12.0, 15.5}; 6.0, 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 ox03c10_analog_gains_reg[] = { const uint32_t ox03c10_analog_gains_reg[] = {
0x100, 0x140, 0x150, 0x190, 0x100, 0x120, 0x140, 0x150, 0x190,
0x1B0, 0x200, 0x240, 0x2A0, 0x1B0, 0x200, 0x240, 0x2A0, 0x320,
0x320, 0x3A0, 0x480, 0x500, 0x3A0, 0x400, 0x480, 0x500, 0x580,
0x740, 0x880, 0xC00, 0xF80}; 0x600, 0x680, 0x700, 0x780, 0x800,
0x880, 0x900, 0x980, 0xA00, 0xA80,
0xB00, 0xB80, 0xC00, 0xC80, 0xD00,
0xD80, 0xE00, 0xE80, 0xF00, 0xF80};
const int ANALOG_GAIN_MIN_IDX_AR0231 = 0x1; // 0.25x const int ANALOG_GAIN_MIN_IDX_AR0231 = 0x1; // 0.25x
const int ANALOG_GAIN_REC_IDX_AR0231 = 0x6; // 0.8x const int ANALOG_GAIN_REC_IDX_AR0231 = 0x6; // 0.8x
const int ANALOG_GAIN_MAX_IDX_AR0231 = 0xD; // 4.0x const int ANALOG_GAIN_MAX_IDX_AR0231 = 0xD; // 4.0x
const int ANALOG_GAIN_MIN_IDX_OX03C10 = 0x0; const int ANALOG_GAIN_MIN_IDX_OX03C10 = 0x0;
const int ANALOG_GAIN_REC_IDX_OX03C10 = 0x5; // 2x const int ANALOG_GAIN_REC_IDX_OX03C10 = 0x6; // 2x
const int ANALOG_GAIN_MAX_IDX_OX03C10 = 0xF; const int ANALOG_GAIN_MAX_IDX_OX03C10 = 0x22;
const int EXPOSURE_TIME_MIN_AR0231 = 2; // with HDR, fastest ss const int EXPOSURE_TIME_MIN_AR0231 = 2; // with HDR, fastest ss
const int EXPOSURE_TIME_MAX_AR0231 = 0x0855; // with HDR, slowest ss, 40ms const int EXPOSURE_TIME_MAX_AR0231 = 0x0855; // with HDR, slowest ss, 40ms
@ -517,6 +526,7 @@ void CameraState::enqueue_req_multi(int start, int n, bool dp) {
void CameraState::camera_set_parameters() { void CameraState::camera_set_parameters() {
if (camera_id == CAMERA_ID_AR0231) { if (camera_id == CAMERA_ID_AR0231) {
dc_gain_factor = DC_GAIN_AR0231; dc_gain_factor = DC_GAIN_AR0231;
dc_gain_min_weight = DC_GAIN_MIN_WEIGHT_AR0231;
dc_gain_max_weight = DC_GAIN_MAX_WEIGHT_AR0231; dc_gain_max_weight = DC_GAIN_MAX_WEIGHT_AR0231;
dc_gain_on_grey = DC_GAIN_ON_GREY_AR0231; dc_gain_on_grey = DC_GAIN_ON_GREY_AR0231;
dc_gain_off_grey = DC_GAIN_OFF_GREY_AR0231; dc_gain_off_grey = DC_GAIN_OFF_GREY_AR0231;
@ -529,8 +539,10 @@ void CameraState::camera_set_parameters() {
sensor_analog_gains[i] = sensor_analog_gains_AR0231[i]; sensor_analog_gains[i] = sensor_analog_gains_AR0231[i];
} }
min_ev = exposure_time_min * sensor_analog_gains[analog_gain_min_idx]; min_ev = exposure_time_min * sensor_analog_gains[analog_gain_min_idx];
target_grey_factor = TARGET_GREY_FACTOR_AR0231;
} else if (camera_id == CAMERA_ID_OX03C10) { } else if (camera_id == CAMERA_ID_OX03C10) {
dc_gain_factor = DC_GAIN_OX03C10; dc_gain_factor = DC_GAIN_OX03C10;
dc_gain_min_weight = DC_GAIN_MIN_WEIGHT_OX03C10;
dc_gain_max_weight = DC_GAIN_MAX_WEIGHT_OX03C10; dc_gain_max_weight = DC_GAIN_MAX_WEIGHT_OX03C10;
dc_gain_on_grey = DC_GAIN_ON_GREY_OX03C10; dc_gain_on_grey = DC_GAIN_ON_GREY_OX03C10;
dc_gain_off_grey = DC_GAIN_OFF_GREY_OX03C10; dc_gain_off_grey = DC_GAIN_OFF_GREY_OX03C10;
@ -543,6 +555,7 @@ void CameraState::camera_set_parameters() {
sensor_analog_gains[i] = sensor_analog_gains_OX03C10[i]; sensor_analog_gains[i] = sensor_analog_gains_OX03C10[i];
} }
min_ev = (exposure_time_min + VS_TIME_MIN_OX03C10) * sensor_analog_gains[analog_gain_min_idx]; min_ev = (exposure_time_min + VS_TIME_MIN_OX03C10) * sensor_analog_gains[analog_gain_min_idx];
target_grey_factor = TARGET_GREY_FACTOR_OX03C10;
} else { } else {
assert(false); assert(false);
} }
@ -551,7 +564,7 @@ void CameraState::camera_set_parameters() {
target_grey_fraction = 0.3; target_grey_fraction = 0.3;
dc_gain_enabled = false; dc_gain_enabled = false;
dc_gain_weight = DC_GAIN_MIN_WEIGHT; dc_gain_weight = dc_gain_min_weight;
gain_idx = analog_gain_rec_idx; gain_idx = analog_gain_rec_idx;
exposure_time = 5; exposure_time = 5;
cur_ev[0] = cur_ev[1] = cur_ev[2] = (1 + dc_gain_weight * (dc_gain_factor-1) / dc_gain_max_weight) * sensor_analog_gains[gain_idx] * exposure_time; cur_ev[0] = cur_ev[1] = cur_ev[2] = (1 + dc_gain_weight * (dc_gain_factor-1) / dc_gain_max_weight) * sensor_analog_gains[gain_idx] * exposure_time;
@ -1037,7 +1050,7 @@ void CameraState::set_camera_exposure(float grey_frac) {
const float cur_ev_ = cur_ev[buf.cur_frame_data.frame_id % 3]; const float cur_ev_ = cur_ev[buf.cur_frame_data.frame_id % 3];
// Scale target grey between 0.1 and 0.4 depending on lighting conditions // Scale target grey between 0.1 and 0.4 depending on lighting conditions
float new_target_grey = std::clamp(0.4 - 0.3 * log2(1.0 + cur_ev_) / log2(6000.0), 0.1, 0.4); float new_target_grey = std::clamp(0.4 - 0.3 * log2(1.0 + target_grey_factor*cur_ev_) / log2(6000.0), 0.1, 0.4);
float target_grey = (1.0 - k_grey) * target_grey_fraction + k_grey * new_target_grey; float target_grey = (1.0 - k_grey) * target_grey_fraction + k_grey * new_target_grey;
float desired_ev = std::clamp(cur_ev_ * target_grey / grey_frac, min_ev, max_ev); float desired_ev = std::clamp(cur_ev_ * target_grey / grey_frac, min_ev, max_ev);
@ -1053,14 +1066,14 @@ void CameraState::set_camera_exposure(float grey_frac) {
bool enable_dc_gain = dc_gain_enabled; bool enable_dc_gain = dc_gain_enabled;
if (!enable_dc_gain && target_grey < dc_gain_on_grey) { if (!enable_dc_gain && target_grey < dc_gain_on_grey) {
enable_dc_gain = true; enable_dc_gain = true;
dc_gain_weight = DC_GAIN_MIN_WEIGHT; dc_gain_weight = dc_gain_min_weight;
} else if (enable_dc_gain && target_grey > dc_gain_off_grey) { } else if (enable_dc_gain && target_grey > dc_gain_off_grey) {
enable_dc_gain = false; enable_dc_gain = false;
dc_gain_weight = dc_gain_max_weight; dc_gain_weight = dc_gain_max_weight;
} }
if (enable_dc_gain && dc_gain_weight < dc_gain_max_weight) {dc_gain_weight += 1;} if (enable_dc_gain && dc_gain_weight < dc_gain_max_weight) {dc_gain_weight += 1;}
if (!enable_dc_gain && dc_gain_weight > DC_GAIN_MIN_WEIGHT) {dc_gain_weight -= 1;} if (!enable_dc_gain && dc_gain_weight > dc_gain_min_weight) {dc_gain_weight -= 1;}
std::string gain_bytes, time_bytes; std::string gain_bytes, time_bytes;
if (env_ctrl_exp_from_params) { if (env_ctrl_exp_from_params) {
@ -1145,10 +1158,12 @@ void CameraState::set_camera_exposure(float grey_frac) {
// t_HCG + t_LCG + t_VS on LPD, t_SPD on SPD // t_HCG + t_LCG + t_VS on LPD, t_SPD on SPD
uint32_t hcg_time = std::max((dc_gain_weight * exposure_time / dc_gain_max_weight), 0); uint32_t hcg_time = std::max((dc_gain_weight * exposure_time / dc_gain_max_weight), 0);
uint32_t lcg_time = std::max(((dc_gain_max_weight - dc_gain_weight) * exposure_time / dc_gain_max_weight), 0); uint32_t lcg_time = std::max(((dc_gain_max_weight - dc_gain_weight) * exposure_time / dc_gain_max_weight), 0);
uint32_t spd_time = std::max(hcg_time / 16, (uint32_t)exposure_time_min); // uint32_t spd_time = std::max(hcg_time / 16, (uint32_t)exposure_time_min);
uint32_t vs_time = std::min(std::max(hcg_time / 64, VS_TIME_MIN_OX03C10), VS_TIME_MAX_OX03C10); uint32_t vs_time = std::min(std::max((uint32_t)exposure_time / 128, VS_TIME_MIN_OX03C10), VS_TIME_MAX_OX03C10);
uint32_t spd_time = vs_time;
uint32_t real_gain = ox03c10_analog_gains_reg[new_g]; uint32_t real_gain = ox03c10_analog_gains_reg[new_g];
uint32_t min_gain = ox03c10_analog_gains_reg[0];
struct i2c_random_wr_payload exp_reg_array[] = { struct i2c_random_wr_payload exp_reg_array[] = {
{0x3501, hcg_time>>8}, {0x3502, hcg_time&0xFF}, {0x3501, hcg_time>>8}, {0x3502, hcg_time&0xFF},
@ -1157,9 +1172,9 @@ void CameraState::set_camera_exposure(float grey_frac) {
{0x35c1, vs_time>>8}, {0x35c2, vs_time&0xFF}, {0x35c1, vs_time>>8}, {0x35c2, vs_time&0xFF},
{0x3508, real_gain>>8}, {0x3509, real_gain&0xFF}, {0x3508, real_gain>>8}, {0x3509, real_gain&0xFF},
{0x3588, real_gain>>8}, {0x3589, real_gain&0xFF}, {0x3588, min_gain>>8}, {0x3589, min_gain&0xFF},
{0x3548, real_gain>>8}, {0x3549, real_gain&0xFF}, {0x3548, min_gain>>8}, {0x3549, min_gain&0xFF},
{0x35c8, real_gain>>8}, {0x35c9, real_gain&0xFF}, {0x35c8, min_gain>>8}, {0x35c9, min_gain&0xFF},
}; };
sensors_i2c(exp_reg_array, sizeof(exp_reg_array)/sizeof(struct i2c_random_wr_payload), CAM_SENSOR_PACKET_OPCODE_SENSOR_CONFIG, false); sensors_i2c(exp_reg_array, sizeof(exp_reg_array)/sizeof(struct i2c_random_wr_payload), CAM_SENSOR_PACKET_OPCODE_SENSOR_CONFIG, false);
} }

@ -31,11 +31,12 @@ public:
int exposure_time_max; int exposure_time_max;
float dc_gain_factor; float dc_gain_factor;
int dc_gain_min_weight;
int dc_gain_max_weight; int dc_gain_max_weight;
float dc_gain_on_grey; float dc_gain_on_grey;
float dc_gain_off_grey; float dc_gain_off_grey;
float sensor_analog_gains[16]; float sensor_analog_gains[35];
int analog_gain_min_idx; int analog_gain_min_idx;
int analog_gain_max_idx; int analog_gain_max_idx;
int analog_gain_rec_idx; int analog_gain_rec_idx;
@ -45,6 +46,7 @@ public:
float measured_grey_fraction; float measured_grey_fraction;
float target_grey_fraction; float target_grey_fraction;
float target_grey_factor;
unique_fd sensor_fd; unique_fd sensor_fd;
unique_fd csiphy_fd; unique_fd csiphy_fd;

@ -129,13 +129,13 @@ struct i2c_random_wr_payload init_array_ox03c10[] = {
{0x350a, 0x04}, {0x350b, 0x00}, {0x350c, 0x00}, // hcg digital gain {0x350a, 0x04}, {0x350b, 0x00}, {0x350c, 0x00}, // hcg digital gain
{0x3586, 0x40}, {0x3587, 0x00}, // lcg fine exposure {0x3586, 0x40}, {0x3587, 0x00}, // lcg fine exposure
{0x358a, 0x04}, {0x358b, 0x00}, {0x358c, 0x00}, // lcg digital gain {0x358a, 0x01}, {0x358b, 0x00}, {0x358c, 0x00}, // lcg digital gain
{0x3546, 0x20}, {0x3547, 0x00}, // spd fine exposure {0x3546, 0x20}, {0x3547, 0x00}, // spd fine exposure
{0x354a, 0x04}, {0x354b, 0x00}, {0x354c, 0x00}, // spd digital gain {0x354a, 0x01}, {0x354b, 0x00}, {0x354c, 0x00}, // spd digital gain
{0x35c6, 0xb0}, {0x35c7, 0x00}, // vs fine exposure {0x35c6, 0xb0}, {0x35c7, 0x00}, // vs fine exposure
{0x35ca, 0x04}, {0x35cb, 0x00}, {0x35cc, 0x00}, // vs digital gain {0x35ca, 0x01}, {0x35cb, 0x00}, {0x35cc, 0x00}, // vs digital gain
// also RSVD // also RSVD
{0x3600, 0x8f}, {0x3605, 0x16}, {0x3609, 0xf0}, {0x360a, 0x01}, {0x3600, 0x8f}, {0x3605, 0x16}, {0x3609, 0xf0}, {0x360a, 0x01},

Loading…
Cancel
Save