|  |  |  | @ -1101,36 +1101,48 @@ void CameraState::set_camera_exposure(float grey_frac) { | 
			
		
	
		
			
				
					|  |  |  |  |   } else if (enable_dc_gain && target_grey > 0.3) { | 
			
		
	
		
			
				
					|  |  |  |  |     enable_dc_gain = false; | 
			
		
	
		
			
				
					|  |  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  |  |   if (env_ctrl_exp_from_params) { | 
			
		
	
		
			
				
					|  |  |  |  |     // Override gain and exposure time
 | 
			
		
	
		
			
				
					|  |  |  |  |     if (buf.cur_frame_data.frame_id % 5 == 0) { | 
			
		
	
		
			
				
					|  |  |  |  |       std::string gain_bytes = Params().get("CameraDebugExpGain"); | 
			
		
	
		
			
				
					|  |  |  |  |       std::string time_bytes = Params().get("CameraDebugExpTime"); | 
			
		
	
		
			
				
					|  |  |  |  |       gain_idx = std::stoi(gain_bytes); | 
			
		
	
		
			
				
					|  |  |  |  |       exposure_time = std::stoi(time_bytes); | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  |     new_g = gain_idx; | 
			
		
	
		
			
				
					|  |  |  |  |     new_t = exposure_time; | 
			
		
	
		
			
				
					|  |  |  |  |     enable_dc_gain = false; | 
			
		
	
		
			
				
					|  |  |  |  |   } 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] * (enable_dc_gain ? DC_GAIN : 1); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |   // 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] * (enable_dc_gain ? DC_GAIN : 1); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     // Compute optimal time for given gain
 | 
			
		
	
		
			
				
					|  |  |  |  |     int t = std::clamp(int(std::round(desired_ev / gain)), EXPOSURE_TIME_MIN, EXPOSURE_TIME_MAX); | 
			
		
	
		
			
				
					|  |  |  |  |       // Compute optimal time for given gain
 | 
			
		
	
		
			
				
					|  |  |  |  |       int t = std::clamp(int(std::round(desired_ev / gain)), EXPOSURE_TIME_MIN, 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) { | 
			
		
	
		
			
				
					|  |  |  |  |       continue; | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  |       // Only go below recommended gain when absolutely necessary to not overexpose
 | 
			
		
	
		
			
				
					|  |  |  |  |       if (g < ANALOG_GAIN_REC_IDX && t > 20 && g < gain_idx) { | 
			
		
	
		
			
				
					|  |  |  |  |         continue; | 
			
		
	
		
			
				
					|  |  |  |  |       } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     // Compute error to desired ev
 | 
			
		
	
		
			
				
					|  |  |  |  |     float score = std::abs(desired_ev - (t * gain)) * 10; | 
			
		
	
		
			
				
					|  |  |  |  |       // Compute error to desired ev
 | 
			
		
	
		
			
				
					|  |  |  |  |       float score = std::abs(desired_ev - (t * gain)) * 10; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     // Going below recommended gain needs lower penalty to not overexpose
 | 
			
		
	
		
			
				
					|  |  |  |  |     float m = g > ANALOG_GAIN_REC_IDX ? 5.0 : 0.1; | 
			
		
	
		
			
				
					|  |  |  |  |     score += std::abs(g - (int)ANALOG_GAIN_REC_IDX) * m; | 
			
		
	
		
			
				
					|  |  |  |  |       // Going below recommended gain needs lower penalty to not overexpose
 | 
			
		
	
		
			
				
					|  |  |  |  |       float m = g > ANALOG_GAIN_REC_IDX ? 5.0 : 0.1; | 
			
		
	
		
			
				
					|  |  |  |  |       score += std::abs(g - (int)ANALOG_GAIN_REC_IDX) * m; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     // LOGE("cam: %d - gain: %d, t: %d (%.2f), score %.2f, score + gain %.2f, %.3f, %.3f", camera_num, g, t, desired_ev / gain, score, score + std::abs(g - gain_idx) * (score + 1.0) / 10.0, desired_ev, min_ev);
 | 
			
		
	
		
			
				
					|  |  |  |  |       // LOGE("cam: %d - gain: %d, t: %d (%.2f), score %.2f, score + gain %.2f, %.3f, %.3f", camera_num, g, t, desired_ev / gain, score, score + std::abs(g - gain_idx) * (score + 1.0) / 10.0, desired_ev, min_ev);
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     // Small penalty on changing gain
 | 
			
		
	
		
			
				
					|  |  |  |  |     score += std::abs(g - gain_idx) * (score + 1.0) / 10.0; | 
			
		
	
		
			
				
					|  |  |  |  |       // Small penalty on changing gain
 | 
			
		
	
		
			
				
					|  |  |  |  |       score += std::abs(g - gain_idx) * (score + 1.0) / 10.0; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     if (score < best_ev_score) { | 
			
		
	
		
			
				
					|  |  |  |  |       new_t = t; | 
			
		
	
		
			
				
					|  |  |  |  |       new_g = g; | 
			
		
	
		
			
				
					|  |  |  |  |       best_ev_score = score; | 
			
		
	
		
			
				
					|  |  |  |  |       if (score < best_ev_score) { | 
			
		
	
		
			
				
					|  |  |  |  |         new_t = t; | 
			
		
	
		
			
				
					|  |  |  |  |         new_g = g; | 
			
		
	
		
			
				
					|  |  |  |  |         best_ev_score = score; | 
			
		
	
		
			
				
					|  |  |  |  |       } | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  |  | 
 |