00001 #include "Lens.h"
00002 #include "../Frame.h"
00003 #include "V4L2Sensor.h"
00004
00005 #include <stdio.h>
00006 #include <stdlib.h>
00007 #include <sys/types.h>
00008 #include <sys/stat.h>
00009 #include <sys/ioctl.h>
00010 #include <fcntl.h>
00011
00012 #include <linux/videodev2.h>
00013 #include <limits>
00014
00015 namespace FCam { namespace N900 {
00016
00017 Lens::Lens() : lensHistory(512) {
00018
00019
00020 setFocus(0, -1);
00021 }
00022
00023 Lens::~Lens() {
00024 }
00025
00026
00027 int Lens::ioctlGet(unsigned key) {
00028 struct v4l2_control ctrl;
00029 ctrl.id = key;
00030 int fd = V4L2Sensor::instance("/dev/video0")->getFD();
00031 if (fd < 0) {
00032 V4L2Sensor::instance("/dev/video0")->open();
00033 fd = V4L2Sensor::instance("/dev/video0")->getFD();
00034 }
00035 if (ioctl(fd, VIDIOC_G_CTRL, &ctrl) < 0) {
00036 perror("VIDIOC_G_CTRL");
00037 return -1;
00038 }
00039 return ctrl.value;
00040 }
00041
00042 int Lens::ioctlSet(unsigned key, int val) {
00043 struct v4l2_control ctrl;
00044 ctrl.id = key;
00045 ctrl.value = val;
00046 int fd = V4L2Sensor::instance("/dev/video0")->getFD();
00047 if (fd < 0) {
00048 V4L2Sensor::instance("/dev/video0")->open();
00049 fd = V4L2Sensor::instance("/dev/video0")->getFD();
00050 }
00051 if (ioctl(fd, VIDIOC_S_CTRL, &ctrl) < 0) {
00052 perror("VIDIOC_S_CTRL");
00053 return -1;
00054 }
00055 if (ioctl(fd, VIDIOC_G_CTRL, &ctrl) < 0) {
00056 perror("VIDIOC_G_CTRL");
00057 return -1;
00058 }
00059 return ctrl.value;
00060 }
00061
00062
00063 void Lens::setFocus(float f, float speed = -1) {
00064
00065
00066
00067 if (speed < 0) speed = maxFocusSpeed();
00068 if (speed < minFocusSpeed()) speed = minFocusSpeed();
00069 if (speed > maxFocusSpeed()) speed = maxFocusSpeed();
00070
00071
00072 ioctlSet(V4L2_CID_FOCUS_AD5820_RAMP_MODE, 0);
00073
00074
00075
00076 int val = ioctlSet(V4L2_CID_FOCUS_AD5820_RAMP_TIME, 1000000.0f/diopterRateToTickRate(speed));
00077
00078 float focusSpeed = tickRateToDiopterRate(1000000.0f / val);
00079
00080
00081 if (f < farFocus()) f = farFocus();
00082 if (f > nearFocus()) f = nearFocus();
00083
00084 int ticks = dioptersToTicks(f);
00085
00086 int oldTicks = ioctlGet(V4L2_CID_FOCUS_ABSOLUTE);
00087 float oldDiopters = ticksToDiopters(oldTicks);
00088
00089
00090 int newTicks = ioctlSet(V4L2_CID_FOCUS_ABSOLUTE, ticks);
00091
00092 Time start = Time::now();
00093
00094
00095 f = ticksToDiopters(newTicks);
00096 float dDiopters = f - oldDiopters;
00097 if (dDiopters < 0) dDiopters = -dDiopters;
00098
00099
00100 Time end = start + 1000000 * dDiopters / focusSpeed;
00101
00102
00103
00104
00105
00106
00107
00108 LensState s;
00109 s.time = start;
00110 s.position = oldDiopters;
00111 lensHistory.push(s);
00112 s.time = end;
00113 s.position = f;
00114 lensHistory.push(s);
00115 }
00116
00117 float Lens::getFocus() {
00118 return getFocus(Time::now());
00119 }
00120
00121 float Lens::getFocus(Time t) {
00122 if (lensHistory.size() && t > lensHistory[0].time) {
00123 return lensHistory[0].position;
00124 }
00125
00126 for (size_t i = 0; i < lensHistory.size()-1; i++) {
00127 if (t < lensHistory[i+1].time) continue;
00128 if (t < lensHistory[i].time) {
00129
00130 float alpha = float(t - lensHistory[i+1].time)/(lensHistory[i].time - lensHistory[i+1].time);
00131 return alpha * lensHistory[i].position + (1-alpha) * lensHistory[i+1].position;
00132 }
00133 }
00134
00135
00136 printf("Lens position at time %d %d is unknown!\n", t.s(), t.us());
00137 return std::numeric_limits<float>::quiet_NaN();
00138 }
00139
00140 bool Lens::focusChanging() {
00141 Time t = Time::now();
00142 return (lensHistory.size()) && (lensHistory[0].time > t);
00143 }
00144
00145 float Lens::minFocusSpeed() {
00146
00147 return tickRateToDiopterRate(1/0.003200f);
00148 }
00149
00150 float Lens::maxFocusSpeed() {
00151
00152 return tickRateToDiopterRate(1/0.000050f);
00153 }
00154
00155
00156 float Lens::ticksToDiopters(int ticks) {
00157 float d = 0.029f*(ticks-165);
00158
00159
00160 if (d < 0.0f) d = 0.0f;
00161 if (d > 20.0f) d = 20.0f;
00162 return d;
00163 }
00164
00165 int Lens::dioptersToTicks(float diopter) {
00166 return (int)(diopter*34.483f + 165.5f);
00167 }
00168
00169
00170 float Lens::tickRateToDiopterRate(int ticks) {
00171 return ticks * 0.029f;
00172 }
00173
00174 int Lens::diopterRateToTickRate(float diopter) {
00175 return (int)(diopter*34.482f + 0.5f);
00176 }
00177
00178
00179 void Lens::tagFrame(FCam::Frame *f) {
00180 if (!f) {
00181 return;
00182 }
00183
00184 Lens::Tags *tags = new Lens::Tags;
00185
00186 tags->initialFocus = getFocus(f->exposureStartTime);
00187 tags->finalFocus = getFocus(f->exposureEndTime);
00188 tags->focus = (tags->initialFocus + tags->finalFocus)/2;
00189 tags->focusSpeed = (1000000.0f * (tags->finalFocus - tags->initialFocus)/
00190 (f->exposureEndTime - f->exposureStartTime));
00191
00192 tags->zoom = tags->initialZoom = tags->finalZoom = getZoom();
00193 tags->zoomSpeed = 0;
00194
00195 tags->aperture = tags->initialAperture = tags->finalAperture = getAperture();
00196 tags->apertureSpeed = 0;
00197
00198 f->addTags(this, tags);
00199 }
00200
00201 }}