Skip to content

Autofocus improvements #270

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 33 additions & 20 deletions src/ipa/rpi/common/ipa_base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -237,25 +237,6 @@ int32_t IpaBase::configure(const IPACameraSensorInfo &sensorInfo, const ConfigPa
agcStatus.analogueGain = defaultAnalogueGain;
applyAGC(&agcStatus, ctrls);

/*
* Set the lens to the default (typically hyperfocal) position
* on first start.
*/
if (lensPresent_) {
RPiController::AfAlgorithm *af =
dynamic_cast<RPiController::AfAlgorithm *>(controller_.getAlgorithm("af"));

if (af) {
float defaultPos =
ipaAfControls.at(&controls::LensPosition).def().get<float>();
ControlList lensCtrl(lensCtrls_);
int32_t hwpos;

af->setLensPosition(defaultPos, &hwpos);
lensCtrl.set(V4L2_CID_FOCUS_ABSOLUTE, hwpos);
result->lensControls = std::move(lensCtrl);
}
}
}

result->sensorControls = std::move(ctrls);
Expand Down Expand Up @@ -285,8 +266,20 @@ int32_t IpaBase::configure(const IPACameraSensorInfo &sensorInfo, const ConfigPa
ctrlMap.merge(ControlInfoMap::Map(ipaColourControls));

/* Declare Autofocus controls, only if we have a controllable lens */
if (lensPresent_)
if (lensPresent_) {
ctrlMap.merge(ControlInfoMap::Map(ipaAfControls));
RPiController::AfAlgorithm *af =
dynamic_cast<RPiController::AfAlgorithm *>(controller_.getAlgorithm("af"));
if (af) {
double min, max, dflt;
af->getLensLimits(min, max);
dflt = af->getDefaultLensPosition();
ctrlMap[&controls::LensPosition] =
ControlInfo(static_cast<float>(min),
static_cast<float>(max),
static_cast<float>(dflt));
}
}

result->controlInfo = ControlInfoMap(std::move(ctrlMap), controls::controls);

Expand Down Expand Up @@ -324,6 +317,26 @@ void IpaBase::start(const ControlList &controls, StartResult *result)
/* Make a note of this as it tells us the HDR status of the first few frames. */
hdrStatus_ = agcStatus.hdr;

/*
* AF: If no lens position was specified, drive lens to a default position.
* This had to be deferred (not initialised by a constructor) until here
* to ensure that exactly ONE starting position is sent to the lens driver.
* It should be the static API default, not dependent on AF range or mode.
*/
if (firstStart_ && lensPresent_) {
RPiController::AfAlgorithm *af = dynamic_cast<RPiController::AfAlgorithm *>(
controller_.getAlgorithm("af"));
if (af && !af->getLensPosition()) {
int32_t hwpos;
double pos = af->getDefaultLensPosition();
if (af->setLensPosition(pos, &hwpos, true)) {
ControlList lensCtrls(lensCtrls_);
lensCtrls.set(V4L2_CID_FOCUS_ABSOLUTE, hwpos);
setLensControls.emit(lensCtrls);
}
}
}

/*
* Initialise frame counts, and decide how many frames must be hidden or
* "mistrusted", which depends on whether this is a startup from cold,
Expand Down
8 changes: 7 additions & 1 deletion src/ipa/rpi/controller/af_algorithm.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ class AfAlgorithm : public Algorithm
*
* getMode() is provided mainly for validating controls.
* getLensPosition() is provided for populating DeviceStatus.
*
* getDefaultlensPosition() and getLensLimits() were added for
* populating ControlInfoMap. They return the static API limits
* which should be independent of the current range or mode.
*/

enum AfRange { AfRangeNormal = 0,
Expand Down Expand Up @@ -66,7 +70,9 @@ class AfAlgorithm : public Algorithm
}
virtual void setMode(AfMode mode) = 0;
virtual AfMode getMode() const = 0;
virtual bool setLensPosition(double dioptres, int32_t *hwpos) = 0;
virtual double getDefaultLensPosition() const = 0;
virtual void getLensLimits(double &min, double &max) const = 0;
virtual bool setLensPosition(double dioptres, int32_t *hwpos, bool force = false) = 0;
virtual std::optional<double> getLensPosition() const = 0;
virtual void triggerScan() = 0;
virtual void cancelScan() = 0;
Expand Down
Loading