|
|
@ -1710,9 +1710,6 @@ static void parse_autofocus(CameraState *s, uint8_t *d) { |
|
|
|
int good_count = 0; |
|
|
|
int good_count = 0; |
|
|
|
int16_t max_focus = -32767; |
|
|
|
int16_t max_focus = -32767; |
|
|
|
int avg_focus = 0; |
|
|
|
int avg_focus = 0; |
|
|
|
// force to max if not able to determine focus for long
|
|
|
|
|
|
|
|
const int patience_cnt = 20; |
|
|
|
|
|
|
|
static int nan_cnt = 0; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*printf("FOCUS: ");
|
|
|
|
/*printf("FOCUS: ");
|
|
|
|
for (int i = 0; i < 0x10; i++) { |
|
|
|
for (int i = 0; i < 0x10; i++) { |
|
|
@ -1720,56 +1717,41 @@ static void parse_autofocus(CameraState *s, uint8_t *d) { |
|
|
|
}*/ |
|
|
|
}*/ |
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < NUM_FOCUS; i++) { |
|
|
|
for (int i = 0; i < NUM_FOCUS; i++) { |
|
|
|
int pd_idx = (i+1)*5; |
|
|
|
int doff = i*5+5; |
|
|
|
s->confidence[i] = d[pd_idx]; |
|
|
|
s->confidence[i] = d[doff]; |
|
|
|
int16_t focus_delta = d[pd_idx+1]; |
|
|
|
int16_t focus_t = (d[doff+1] << 3) | (d[doff+2] >> 5); |
|
|
|
if (focus_delta >= 128) focus_delta = - (256 - focus_delta); |
|
|
|
if (focus_t >= 1024) focus_t = -(2048-focus_t); |
|
|
|
s->focus[i] = focus_delta; |
|
|
|
s->focus[i] = focus_t; |
|
|
|
|
|
|
|
//printf("%x->%d ", d[doff], focus_t);
|
|
|
|
if (s->confidence[i] > 64) { |
|
|
|
if (s->confidence[i] > 0x20) { |
|
|
|
good_count++; |
|
|
|
good_count++; |
|
|
|
max_focus = max(max_focus, s->focus[i]); |
|
|
|
max_focus = max(max_focus, s->focus[i]); |
|
|
|
avg_focus += s->focus[i]; |
|
|
|
avg_focus += s->focus[i]; |
|
|
|
// printf("%d\n", s->focus[i]);
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (good_count < 7) { |
|
|
|
//printf("\n");
|
|
|
|
|
|
|
|
if (good_count < 4) { |
|
|
|
s->focus_err = nan(""); |
|
|
|
s->focus_err = nan(""); |
|
|
|
nan_cnt += 1; |
|
|
|
|
|
|
|
if (nan_cnt > patience_cnt) { |
|
|
|
|
|
|
|
s->focus_err = 16; |
|
|
|
|
|
|
|
nan_cnt = 0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
avg_focus /= good_count; |
|
|
|
avg_focus /= good_count; |
|
|
|
|
|
|
|
|
|
|
|
if (abs(avg_focus - max_focus) > 32) { |
|
|
|
// outlier rejection
|
|
|
|
if (nan_cnt < patience_cnt) { |
|
|
|
if (abs(avg_focus - max_focus) > 200) { |
|
|
|
s->focus_err = nan(""); |
|
|
|
s->focus_err = nan(""); |
|
|
|
nan_cnt += 1; |
|
|
|
return; |
|
|
|
return; |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
s->focus_err = 16; |
|
|
|
|
|
|
|
// s->focus_err = max_focus*8.0;
|
|
|
|
|
|
|
|
nan_cnt = 0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
s->focus_err = max_focus; |
|
|
|
|
|
|
|
nan_cnt = 0; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
// printf("fe=%f\n", s->focus_err);
|
|
|
|
|
|
|
|
|
|
|
|
s->focus_err = max_focus*1.0; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void do_autofocus(CameraState *s) { |
|
|
|
static void do_autofocus(CameraState *s) { |
|
|
|
// params for focus P controller
|
|
|
|
// params for focus PI controller
|
|
|
|
const float focus_kp = 0.1; |
|
|
|
const float focus_kp = 0.005; |
|
|
|
|
|
|
|
|
|
|
|
float err = s->focus_err; |
|
|
|
float err = s->focus_err; |
|
|
|
// don't allow big change
|
|
|
|
|
|
|
|
err = clamp(err, -16, 16); |
|
|
|
|
|
|
|
float sag = (s->last_sag_acc_z/9.8) * 128; |
|
|
|
float sag = (s->last_sag_acc_z/9.8) * 128; |
|
|
|
|
|
|
|
|
|
|
|
const int dac_up = s->device == DEVICE_LP3? 634:456; |
|
|
|
const int dac_up = s->device == DEVICE_LP3? 634:456; |
|
|
@ -1793,7 +1775,6 @@ static void do_autofocus(CameraState *s) { |
|
|
|
LOGD(debug);*/ |
|
|
|
LOGD(debug);*/ |
|
|
|
|
|
|
|
|
|
|
|
actuator_move(s, target); |
|
|
|
actuator_move(s, target); |
|
|
|
// printf("ltp=%f, clp=%d\n",s->lens_true_pos,s->cur_lens_pos);
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -2084,6 +2065,7 @@ static void* ops_thread(void* arg) { |
|
|
|
if (cmsg.type == CAMERA_MSG_AUTOEXPOSE) { |
|
|
|
if (cmsg.type == CAMERA_MSG_AUTOEXPOSE) { |
|
|
|
if (cmsg.camera_num == 0) { |
|
|
|
if (cmsg.camera_num == 0) { |
|
|
|
do_autoexposure(&s->rear, cmsg.grey_frac); |
|
|
|
do_autoexposure(&s->rear, cmsg.grey_frac); |
|
|
|
|
|
|
|
do_autofocus(&s->rear); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
do_autoexposure(&s->front, cmsg.grey_frac); |
|
|
|
do_autoexposure(&s->front, cmsg.grey_frac); |
|
|
|
} |
|
|
|
} |
|
|
@ -2182,11 +2164,7 @@ void cameras_run(DualCameraState *s) { |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
uint8_t *d = c->ss[buffer].bufs[buf_idx].addr; |
|
|
|
uint8_t *d = c->ss[buffer].bufs[buf_idx].addr; |
|
|
|
if (buffer == 1) { |
|
|
|
if (buffer == 1) { |
|
|
|
// FILE *df = fopen("/sdcard/focus_buf","wb");
|
|
|
|
|
|
|
|
// fwrite(d, c->ss[buffer].bufs[buf_idx].len, sizeof(uint8_t), df);
|
|
|
|
|
|
|
|
// fclose(df);
|
|
|
|
|
|
|
|
parse_autofocus(c, d); |
|
|
|
parse_autofocus(c, d); |
|
|
|
do_autofocus(&s->rear); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
c->ss[buffer].qbuf_info[buf_idx].dirty_buf = 1; |
|
|
|
c->ss[buffer].qbuf_info[buf_idx].dirty_buf = 1; |
|
|
|
ioctl(c->isp_fd, VIDIOC_MSM_ISP_ENQUEUE_BUF, &c->ss[buffer].qbuf_info[buf_idx]); |
|
|
|
ioctl(c->isp_fd, VIDIOC_MSM_ISP_ENQUEUE_BUF, &c->ss[buffer].qbuf_info[buf_idx]); |
|
|
@ -2232,4 +2210,4 @@ void cameras_run(DualCameraState *s) { |
|
|
|
void cameras_close(DualCameraState *s) { |
|
|
|
void cameras_close(DualCameraState *s) { |
|
|
|
camera_close(&s->rear); |
|
|
|
camera_close(&s->rear); |
|
|
|
camera_close(&s->front); |
|
|
|
camera_close(&s->front); |
|
|
|
} |
|
|
|
} |