|  |  |  | @ -40,27 +40,6 @@ const size_t AR0231_REGISTERS_HEIGHT = 2; | 
			
		
	
		
			
				
					|  |  |  |  | const size_t AR0231_STATS_HEIGHT = 2+8; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | const int MIPI_SETTLE_CNT = 33;  // Calculated by camera_freqs.py
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | CameraInfo cameras_supported[CAMERA_ID_MAX] = { | 
			
		
	
		
			
				
					|  |  |  |  |   [CAMERA_ID_AR0231] = { | 
			
		
	
		
			
				
					|  |  |  |  |     .frame_width = FRAME_WIDTH, | 
			
		
	
		
			
				
					|  |  |  |  |     .frame_height = FRAME_HEIGHT, | 
			
		
	
		
			
				
					|  |  |  |  |     .frame_stride = FRAME_STRIDE, | 
			
		
	
		
			
				
					|  |  |  |  |     .extra_height = AR0231_REGISTERS_HEIGHT + AR0231_STATS_HEIGHT, | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     .registers_offset = 0, | 
			
		
	
		
			
				
					|  |  |  |  |     .frame_offset = AR0231_REGISTERS_HEIGHT, | 
			
		
	
		
			
				
					|  |  |  |  |     .stats_offset = AR0231_REGISTERS_HEIGHT + FRAME_HEIGHT, | 
			
		
	
		
			
				
					|  |  |  |  |   }, | 
			
		
	
		
			
				
					|  |  |  |  |   [CAMERA_ID_OX03C10] = { | 
			
		
	
		
			
				
					|  |  |  |  |     .frame_width = FRAME_WIDTH, | 
			
		
	
		
			
				
					|  |  |  |  |     .frame_height = FRAME_HEIGHT, | 
			
		
	
		
			
				
					|  |  |  |  |     .frame_stride = FRAME_STRIDE, // (0xa80*12//8)
 | 
			
		
	
		
			
				
					|  |  |  |  |     .extra_height = 16, // top 2 + bot 14
 | 
			
		
	
		
			
				
					|  |  |  |  |     .frame_offset = 2, | 
			
		
	
		
			
				
					|  |  |  |  |   }, | 
			
		
	
		
			
				
					|  |  |  |  | }; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | const float DC_GAIN_AR0231 = 2.5; | 
			
		
	
		
			
				
					|  |  |  |  | const float DC_GAIN_OX03C10 = 7.32; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -424,10 +403,10 @@ void CameraState::config_isp(int io_mem_handle, int fence, int request_id, int b | 
			
		
	
		
			
				
					|  |  |  |  |   if (io_mem_handle != 0) { | 
			
		
	
		
			
				
					|  |  |  |  |     io_cfg[0].mem_handle[0] = io_mem_handle; | 
			
		
	
		
			
				
					|  |  |  |  |     io_cfg[0].planes[0] = (struct cam_plane_cfg){ | 
			
		
	
		
			
				
					|  |  |  |  |       .width = ci.frame_width, | 
			
		
	
		
			
				
					|  |  |  |  |       .height = ci.frame_height + ci.extra_height, | 
			
		
	
		
			
				
					|  |  |  |  |       .plane_stride = ci.frame_stride, | 
			
		
	
		
			
				
					|  |  |  |  |       .slice_height = ci.frame_height + ci.extra_height, | 
			
		
	
		
			
				
					|  |  |  |  |       .width = ci->frame_width, | 
			
		
	
		
			
				
					|  |  |  |  |       .height = ci->frame_height + ci->extra_height, | 
			
		
	
		
			
				
					|  |  |  |  |       .plane_stride = ci->frame_stride, | 
			
		
	
		
			
				
					|  |  |  |  |       .slice_height = ci->frame_height + ci->extra_height, | 
			
		
	
		
			
				
					|  |  |  |  |       .meta_stride = 0x0,  // YUV has meta(stride=0x400, size=0x5000)
 | 
			
		
	
		
			
				
					|  |  |  |  |       .meta_size = 0x0, | 
			
		
	
		
			
				
					|  |  |  |  |       .meta_offset = 0x0, | 
			
		
	
	
		
			
				
					|  |  |  | @ -517,8 +496,17 @@ void CameraState::enqueue_req_multi(int start, int n, bool dp) { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | // ******************* camera *******************
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | void CameraState::camera_set_parameters() { | 
			
		
	
		
			
				
					|  |  |  |  |   if (camera_id == CAMERA_ID_AR0231) { | 
			
		
	
		
			
				
					|  |  |  |  | struct CameraAR0231 : public CameraInfo { | 
			
		
	
		
			
				
					|  |  |  |  |   CameraAR0231() { | 
			
		
	
		
			
				
					|  |  |  |  |     frame_width = FRAME_WIDTH, | 
			
		
	
		
			
				
					|  |  |  |  |     frame_height = FRAME_HEIGHT, | 
			
		
	
		
			
				
					|  |  |  |  |     frame_stride = FRAME_STRIDE, | 
			
		
	
		
			
				
					|  |  |  |  |     extra_height = AR0231_REGISTERS_HEIGHT + AR0231_STATS_HEIGHT, | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     registers_offset = 0, | 
			
		
	
		
			
				
					|  |  |  |  |     frame_offset = AR0231_REGISTERS_HEIGHT, | 
			
		
	
		
			
				
					|  |  |  |  |     stats_offset = AR0231_REGISTERS_HEIGHT + FRAME_HEIGHT, | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     dc_gain_factor = DC_GAIN_AR0231; | 
			
		
	
		
			
				
					|  |  |  |  |     dc_gain_min_weight = DC_GAIN_MIN_WEIGHT_AR0231; | 
			
		
	
		
			
				
					|  |  |  |  |     dc_gain_max_weight = DC_GAIN_MAX_WEIGHT_AR0231; | 
			
		
	
	
		
			
				
					|  |  |  | @ -532,12 +520,23 @@ void CameraState::camera_set_parameters() { | 
			
		
	
		
			
				
					|  |  |  |  |     analog_gain_cost_delta = ANALOG_GAIN_COST_DELTA_AR0231; | 
			
		
	
		
			
				
					|  |  |  |  |     analog_gain_cost_low = ANALOG_GAIN_COST_LOW_AR0231; | 
			
		
	
		
			
				
					|  |  |  |  |     analog_gain_cost_high = ANALOG_GAIN_COST_HIGH_AR0231; | 
			
		
	
		
			
				
					|  |  |  |  |     for (int i=0; i<=analog_gain_max_idx; i++) { | 
			
		
	
		
			
				
					|  |  |  |  |     for (int i = 0; i <= analog_gain_max_idx; i++) { | 
			
		
	
		
			
				
					|  |  |  |  |       sensor_analog_gains[i] = sensor_analog_gains_AR0231[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 = TARGET_GREY_FACTOR_AR0231; | 
			
		
	
		
			
				
					|  |  |  |  |   } else if (camera_id == CAMERA_ID_OX03C10) { | 
			
		
	
		
			
				
					|  |  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  |  | }; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | struct CameraOx0310 : public CameraInfo { | 
			
		
	
		
			
				
					|  |  |  |  |   CameraOx0310() { | 
			
		
	
		
			
				
					|  |  |  |  |     frame_width = FRAME_WIDTH, | 
			
		
	
		
			
				
					|  |  |  |  |     frame_height = FRAME_HEIGHT, | 
			
		
	
		
			
				
					|  |  |  |  |     frame_stride = FRAME_STRIDE, // (0xa80*12//8)
 | 
			
		
	
		
			
				
					|  |  |  |  |     extra_height = 16, // top 2 + bot 14
 | 
			
		
	
		
			
				
					|  |  |  |  |     frame_offset = 2, | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     dc_gain_factor = DC_GAIN_OX03C10; | 
			
		
	
		
			
				
					|  |  |  |  |     dc_gain_min_weight = DC_GAIN_MIN_WEIGHT_OX03C10; | 
			
		
	
		
			
				
					|  |  |  |  |     dc_gain_max_weight = DC_GAIN_MAX_WEIGHT_OX03C10; | 
			
		
	
	
		
			
				
					|  |  |  | @ -555,19 +554,27 @@ void CameraState::camera_set_parameters() { | 
			
		
	
		
			
				
					|  |  |  |  |       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]; | 
			
		
	
		
			
				
					|  |  |  |  |     max_ev = exposure_time_max * dc_gain_factor * sensor_analog_gains[analog_gain_max_idx]; | 
			
		
	
		
			
				
					|  |  |  |  |     target_grey_factor = TARGET_GREY_FACTOR_OX03C10; | 
			
		
	
		
			
				
					|  |  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  |  | }; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | void CameraState::camera_set_parameters() { | 
			
		
	
		
			
				
					|  |  |  |  |   if (camera_id == CAMERA_ID_AR0231) { | 
			
		
	
		
			
				
					|  |  |  |  |     ci = std::make_unique<CameraAR0231>(); | 
			
		
	
		
			
				
					|  |  |  |  |   } else if (camera_id == CAMERA_ID_OX03C10) { | 
			
		
	
		
			
				
					|  |  |  |  |     ci = std::make_unique<CameraOx0310>(); | 
			
		
	
		
			
				
					|  |  |  |  |   } else { | 
			
		
	
		
			
				
					|  |  |  |  |     assert(false); | 
			
		
	
		
			
				
					|  |  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |   max_ev = exposure_time_max * dc_gain_factor * sensor_analog_gains[analog_gain_max_idx]; | 
			
		
	
		
			
				
					|  |  |  |  |   target_grey_fraction = 0.3; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |   dc_gain_enabled = false; | 
			
		
	
		
			
				
					|  |  |  |  |   dc_gain_weight = dc_gain_min_weight; | 
			
		
	
		
			
				
					|  |  |  |  |   gain_idx = analog_gain_rec_idx; | 
			
		
	
		
			
				
					|  |  |  |  |   dc_gain_weight = ci->dc_gain_min_weight; | 
			
		
	
		
			
				
					|  |  |  |  |   gain_idx = ci->analog_gain_rec_idx; | 
			
		
	
		
			
				
					|  |  |  |  |   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 * (ci->dc_gain_factor-1) / ci->dc_gain_max_weight) * ci->sensor_analog_gains[gain_idx] * exposure_time; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | void CameraState::camera_map_bufs(MultiCameraState *s) { | 
			
		
	
	
		
			
				
					|  |  |  | @ -590,10 +597,6 @@ void CameraState::camera_init(MultiCameraState *s, VisionIpcServer * v, int came | 
			
		
	
		
			
				
					|  |  |  |  |   camera_id = camera_id_; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |   LOGD("camera init %d", camera_num); | 
			
		
	
		
			
				
					|  |  |  |  |   assert(camera_id < std::size(cameras_supported)); | 
			
		
	
		
			
				
					|  |  |  |  |   ci = cameras_supported[camera_id]; | 
			
		
	
		
			
				
					|  |  |  |  |   assert(ci.frame_width != 0); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |   request_id_last = 0; | 
			
		
	
		
			
				
					|  |  |  |  |   skipped = true; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -680,16 +683,16 @@ void CameraState::camera_open(MultiCameraState *multi_cam_state_, int camera_num | 
			
		
	
		
			
				
					|  |  |  |  |     .usage_type = 0x0, | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     .left_start = 0, | 
			
		
	
		
			
				
					|  |  |  |  |     .left_stop = ci.frame_width - 1, | 
			
		
	
		
			
				
					|  |  |  |  |     .left_width = ci.frame_width, | 
			
		
	
		
			
				
					|  |  |  |  |     .left_stop = ci->frame_width - 1, | 
			
		
	
		
			
				
					|  |  |  |  |     .left_width = ci->frame_width, | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     .right_start = 0, | 
			
		
	
		
			
				
					|  |  |  |  |     .right_stop = ci.frame_width - 1, | 
			
		
	
		
			
				
					|  |  |  |  |     .right_width = ci.frame_width, | 
			
		
	
		
			
				
					|  |  |  |  |     .right_stop = ci->frame_width - 1, | 
			
		
	
		
			
				
					|  |  |  |  |     .right_width = ci->frame_width, | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     .line_start = 0, | 
			
		
	
		
			
				
					|  |  |  |  |     .line_stop = ci.frame_height + ci.extra_height - 1, | 
			
		
	
		
			
				
					|  |  |  |  |     .height = ci.frame_height + ci.extra_height, | 
			
		
	
		
			
				
					|  |  |  |  |     .line_stop = ci->frame_height + ci->extra_height - 1, | 
			
		
	
		
			
				
					|  |  |  |  |     .height = ci->frame_height + ci->extra_height, | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     .pixel_clk = 0x0, | 
			
		
	
		
			
				
					|  |  |  |  |     .batch_size = 0x0, | 
			
		
	
	
		
			
				
					|  |  |  | @ -701,8 +704,8 @@ void CameraState::camera_open(MultiCameraState *multi_cam_state_, int camera_num | 
			
		
	
		
			
				
					|  |  |  |  |     .data[0] = (struct cam_isp_out_port_info){ | 
			
		
	
		
			
				
					|  |  |  |  |       .res_type = CAM_ISP_IFE_OUT_RES_RDI_0, | 
			
		
	
		
			
				
					|  |  |  |  |       .format = CAM_FORMAT_MIPI_RAW_12, | 
			
		
	
		
			
				
					|  |  |  |  |       .width = ci.frame_width, | 
			
		
	
		
			
				
					|  |  |  |  |       .height = ci.frame_height + ci.extra_height, | 
			
		
	
		
			
				
					|  |  |  |  |       .width = ci->frame_width, | 
			
		
	
		
			
				
					|  |  |  |  |       .height = ci->frame_height + ci->extra_height, | 
			
		
	
		
			
				
					|  |  |  |  |       .comp_grp_id = 0x0, .split_point = 0x0, .secure_mode = 0x0, | 
			
		
	
		
			
				
					|  |  |  |  |     }, | 
			
		
	
		
			
				
					|  |  |  |  |   }; | 
			
		
	
	
		
			
				
					|  |  |  | @ -946,7 +949,7 @@ void CameraState::handle_camera_event(void *evdat) { | 
			
		
	
		
			
				
					|  |  |  |  |     meta_data.frame_id = main_id - idx_offset; | 
			
		
	
		
			
				
					|  |  |  |  |     meta_data.timestamp_sof = timestamp; | 
			
		
	
		
			
				
					|  |  |  |  |     exp_lock.lock(); | 
			
		
	
		
			
				
					|  |  |  |  |     meta_data.gain = analog_gain_frac * (1 + dc_gain_weight * (dc_gain_factor-1) / dc_gain_max_weight); | 
			
		
	
		
			
				
					|  |  |  |  |     meta_data.gain = analog_gain_frac * (1 + dc_gain_weight * (ci->dc_gain_factor-1) / ci->dc_gain_max_weight); | 
			
		
	
		
			
				
					|  |  |  |  |     meta_data.high_conversion_gain = dc_gain_enabled; | 
			
		
	
		
			
				
					|  |  |  |  |     meta_data.integ_lines = exposure_time; | 
			
		
	
		
			
				
					|  |  |  |  |     meta_data.measured_grey_fraction = measured_grey_fraction; | 
			
		
	
	
		
			
				
					|  |  |  | @ -972,15 +975,15 @@ void CameraState::update_exposure_score(float desired_ev, int exp_t, int exp_g_i | 
			
		
	
		
			
				
					|  |  |  |  |     // Cost of ev diff
 | 
			
		
	
		
			
				
					|  |  |  |  |     score = std::abs(desired_ev - (exp_t * exp_gain)) * 10; | 
			
		
	
		
			
				
					|  |  |  |  |     // Cost of absolute 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; | 
			
		
	
		
			
				
					|  |  |  |  |     float m = exp_g_idx > ci->analog_gain_rec_idx ? ci->analog_gain_cost_high : ci->analog_gain_cost_low; | 
			
		
	
		
			
				
					|  |  |  |  |     score += std::abs(exp_g_idx - (int)ci->analog_gain_rec_idx) * m; | 
			
		
	
		
			
				
					|  |  |  |  |     // Cost of changing gain
 | 
			
		
	
		
			
				
					|  |  |  |  |     score += std::abs(exp_g_idx - gain_idx) * (score + 1.0) / 10.0; | 
			
		
	
		
			
				
					|  |  |  |  |   } else if (camera_id == CAMERA_ID_OX03C10) { | 
			
		
	
		
			
				
					|  |  |  |  |     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) * 5.0; | 
			
		
	
		
			
				
					|  |  |  |  |     float m = exp_g_idx > ci->analog_gain_rec_idx ? ci->analog_gain_cost_high : ci->analog_gain_cost_low; | 
			
		
	
		
			
				
					|  |  |  |  |     score += std::abs(exp_g_idx - (int)ci->analog_gain_rec_idx) * m; | 
			
		
	
		
			
				
					|  |  |  |  |     score += ((1 - ci->analog_gain_cost_delta) + ci->analog_gain_cost_delta * (exp_g_idx - ci->analog_gain_min_idx) / (ci->analog_gain_max_idx - ci->analog_gain_min_idx)) * std::abs(exp_g_idx - gain_idx) * 5.0; | 
			
		
	
		
			
				
					|  |  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |   if (score < best_ev_score) { | 
			
		
	
	
		
			
				
					|  |  |  | @ -1008,10 +1011,10 @@ void CameraState::set_camera_exposure(float grey_frac) { | 
			
		
	
		
			
				
					|  |  |  |  |   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
 | 
			
		
	
		
			
				
					|  |  |  |  |   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 new_target_grey = std::clamp(0.4 - 0.3 * log2(1.0 + ci->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 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, ci->min_ev, ci->max_ev); | 
			
		
	
		
			
				
					|  |  |  |  |   float k = (1.0 - k_ev) / 3.0; | 
			
		
	
		
			
				
					|  |  |  |  |   desired_ev = (k * cur_ev[0]) + (k * cur_ev[1]) + (k * cur_ev[2]) + (k_ev * desired_ev); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -1022,16 +1025,16 @@ void CameraState::set_camera_exposure(float grey_frac) { | 
			
		
	
		
			
				
					|  |  |  |  |   // Hysteresis around high conversion gain
 | 
			
		
	
		
			
				
					|  |  |  |  |   // We usually want this on since it results in lower noise, but turn off in very bright day scenes
 | 
			
		
	
		
			
				
					|  |  |  |  |   bool enable_dc_gain = dc_gain_enabled; | 
			
		
	
		
			
				
					|  |  |  |  |   if (!enable_dc_gain && target_grey < dc_gain_on_grey) { | 
			
		
	
		
			
				
					|  |  |  |  |   if (!enable_dc_gain && target_grey < ci->dc_gain_on_grey) { | 
			
		
	
		
			
				
					|  |  |  |  |     enable_dc_gain = true; | 
			
		
	
		
			
				
					|  |  |  |  |     dc_gain_weight = dc_gain_min_weight; | 
			
		
	
		
			
				
					|  |  |  |  |   } else if (enable_dc_gain && target_grey > dc_gain_off_grey) { | 
			
		
	
		
			
				
					|  |  |  |  |     dc_gain_weight = ci->dc_gain_min_weight; | 
			
		
	
		
			
				
					|  |  |  |  |   } else if (enable_dc_gain && target_grey > ci->dc_gain_off_grey) { | 
			
		
	
		
			
				
					|  |  |  |  |     enable_dc_gain = false; | 
			
		
	
		
			
				
					|  |  |  |  |     dc_gain_weight = dc_gain_max_weight; | 
			
		
	
		
			
				
					|  |  |  |  |     dc_gain_weight = ci->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_min_weight) {dc_gain_weight -= 1;} | 
			
		
	
		
			
				
					|  |  |  |  |   if (enable_dc_gain && dc_gain_weight < ci->dc_gain_max_weight) {dc_gain_weight += 1;} | 
			
		
	
		
			
				
					|  |  |  |  |   if (!enable_dc_gain && dc_gain_weight > ci->dc_gain_min_weight) {dc_gain_weight -= 1;} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |   std::string gain_bytes, time_bytes; | 
			
		
	
		
			
				
					|  |  |  |  |   if (env_ctrl_exp_from_params) { | 
			
		
	
	
		
			
				
					|  |  |  | @ -1050,14 +1053,14 @@ void CameraState::set_camera_exposure(float grey_frac) { | 
			
		
	
		
			
				
					|  |  |  |  |   } else { | 
			
		
	
		
			
				
					|  |  |  |  |     // Simple brute force optimizer to choose sensor parameters
 | 
			
		
	
		
			
				
					|  |  |  |  |     // to reach desired EV
 | 
			
		
	
		
			
				
					|  |  |  |  |     for (int g = std::max((int)analog_gain_min_idx, gain_idx - 1); g <= std::min((int)analog_gain_max_idx, gain_idx + 1); g++) { | 
			
		
	
		
			
				
					|  |  |  |  |       float gain = sensor_analog_gains[g] * (1 + dc_gain_weight * (dc_gain_factor-1) / dc_gain_max_weight); | 
			
		
	
		
			
				
					|  |  |  |  |     for (int g = std::max((int)ci->analog_gain_min_idx, gain_idx - 1); g <= std::min((int)ci->analog_gain_max_idx, gain_idx + 1); g++) { | 
			
		
	
		
			
				
					|  |  |  |  |       float gain = ci->sensor_analog_gains[g] * (1 + dc_gain_weight * (ci->dc_gain_factor-1) / ci->dc_gain_max_weight); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |       // Compute optimal time for given gain
 | 
			
		
	
		
			
				
					|  |  |  |  |       int t = std::clamp(int(std::round(desired_ev / gain)), exposure_time_min, exposure_time_max); | 
			
		
	
		
			
				
					|  |  |  |  |       int t = std::clamp(int(std::round(desired_ev / gain)), ci->exposure_time_min, ci->exposure_time_max); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |       // Only go below recommended gain when absolutely necessary to not overexpose
 | 
			
		
	
		
			
				
					|  |  |  |  |       if (g < analog_gain_rec_idx && t > 20 && g < gain_idx) { | 
			
		
	
		
			
				
					|  |  |  |  |       if (g < ci->analog_gain_rec_idx && t > 20 && g < gain_idx) { | 
			
		
	
		
			
				
					|  |  |  |  |         continue; | 
			
		
	
		
			
				
					|  |  |  |  |       } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -1070,12 +1073,12 @@ void CameraState::set_camera_exposure(float grey_frac) { | 
			
		
	
		
			
				
					|  |  |  |  |   measured_grey_fraction = grey_frac; | 
			
		
	
		
			
				
					|  |  |  |  |   target_grey_fraction = target_grey; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |   analog_gain_frac = sensor_analog_gains[new_exp_g]; | 
			
		
	
		
			
				
					|  |  |  |  |   analog_gain_frac = ci->sensor_analog_gains[new_exp_g]; | 
			
		
	
		
			
				
					|  |  |  |  |   gain_idx = new_exp_g; | 
			
		
	
		
			
				
					|  |  |  |  |   exposure_time = new_exp_t; | 
			
		
	
		
			
				
					|  |  |  |  |   dc_gain_enabled = enable_dc_gain; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |   float gain = analog_gain_frac * (1 + dc_gain_weight * (dc_gain_factor-1) / dc_gain_max_weight); | 
			
		
	
		
			
				
					|  |  |  |  |   float gain = analog_gain_frac * (1 + dc_gain_weight * (ci->dc_gain_factor-1) / ci->dc_gain_max_weight); | 
			
		
	
		
			
				
					|  |  |  |  |   cur_ev[buf.cur_frame_data.frame_id % 3] = exposure_time * gain; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |   exp_lock.unlock(); | 
			
		
	
	
		
			
				
					|  |  |  | @ -1100,7 +1103,7 @@ void CameraState::set_camera_exposure(float grey_frac) { | 
			
		
	
		
			
				
					|  |  |  |  |     // t_HCG&t_LCG + t_VS on LPD, t_SPD on SPD
 | 
			
		
	
		
			
				
					|  |  |  |  |     uint32_t hcg_time = exposure_time; | 
			
		
	
		
			
				
					|  |  |  |  |     uint32_t lcg_time = hcg_time; | 
			
		
	
		
			
				
					|  |  |  |  |     uint32_t spd_time = std::min(std::max((uint32_t)exposure_time, (exposure_time_max + VS_TIME_MAX_OX03C10) / 3), exposure_time_max + VS_TIME_MAX_OX03C10); | 
			
		
	
		
			
				
					|  |  |  |  |     uint32_t spd_time = std::min(std::max((uint32_t)exposure_time, (ci->exposure_time_max + VS_TIME_MAX_OX03C10) / 3), ci->exposure_time_max + VS_TIME_MAX_OX03C10); | 
			
		
	
		
			
				
					|  |  |  |  |     uint32_t vs_time = std::min(std::max((uint32_t)exposure_time / 40, VS_TIME_MIN_OX03C10), VS_TIME_MAX_OX03C10); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     uint32_t real_gain = ox03c10_analog_gains_reg[new_exp_g]; | 
			
		
	
	
		
			
				
					|  |  |  | 
 |