I would write the LUT to a file. Do the values change at each focal length?
Perhaps you can also describe the curves with a function.
@c_joerg I think the steps vs focus distances do change as you change focus. Or, I can't convince myself they don't ;-)
In addition, sometimes, but uncorrelated, the inialisation at MFD doesn't result in a step zero at MFD.
To account for this in my script I create one set of LUTs at the favorite focal length, eg:
if lens_name() == "EF-M11-22mm f/4-5.6 IS STM" then -- calculate lens thickness from manufacturer's data
--if lens_name() == "E-M11-22mm f/4-5.6 IS STM" then -- calculate lens thickness from manufacturer's data
-- add other lenses as required, ie replace the following for your lens
-- For the above lens, 300 is the lens max magnification x 1000, ie from manufacturer's data or your measurement
-- 22000 is the lens maximun zoom, or the prime, focal length in microns
-- 150 is the lens minimum focus distance (mm), ie from manufacturer's data or your measurement
Fmax = 22000 -- Longest focal length (mm) * 1000
Mmax = 300 -- Max magnification * 1000
MFD = 150 -- Minimum Focus Distance in mm
t = hiatus() -- distance between front and rear principals
step_count = {0,98,170,204,235,262,288,313,339,361,377,398,411,428,441,450,463,471,482,486,491,499,506,512,516,521,525,529}
x_at_count = {150,160,170,180,190,210,220,240,250,280,300,330,360,400,450,500,560,630,710,810,930,1080,1270,1540,1940,2590,3840,7600}
CalFL = 11
return true
At camera start up I then look to see if a set of LUTs exist and I'm at the correct FL, reposition the lens to the MFD and see if the count there is zero. If not I use this offset to shift registered LUT counts into alignment.
If the lens doesn't have a registered LUT or the FL changes, I recreate the LUTs.
Here are the functions I use:
function set_up_lens() -- create Steps & Focus LUTs
-- This function may take a while to run for some lenses, ie with lots of steps
-- However, as long as you don't change focal length, you only need to run this once
-- You will need to call this function after any focal length change
if log == 1 then print_screen(-1) end -- switch focus bracketing logging on
call_event_proc("EFLensCom.FocusSearchNear")
call_event_proc("EFLensCom.FocusSearchNear") -- just in case ;-)
sleep(100)
call_event_proc('InitializeAdjustmentSystem')
sleep(100)
local j = 1
-- Note this function doesn't require the step count at MFD to be zero
-- It does assume, however, the LUTs don't change; other than explicity when focal length is changed
step_count[j] = call_event_proc('GetEFLensFocusPositionWithLensCom') -- doesn't seem to be different to calling 'GetEFLensFocusPositionWithoutLensCom'
x_at_count[j] = get_focus_distance_lower() -- This is the Canon reported MFD
local last_lower = get_focus_distance_lower()
print("Inialising Lens")
while get_focus_distance_upper() < inf do
call_event_proc("EFLensCom.MoveFocus", 1, 1)
sleep(25) -- this could be changed, but only through testing
if get_focus_distance_lower() > last_lower then -- just gone through a Canon focus step change
j = j + 1
step_count[j] = call_event_proc('GetEFLensFocusPositionWithLensCom')
last_lower = get_focus_distance_lower()
x_at_count[j] = last_lower
end
end
if log == 1 then -- print out LUTs
print(lens_name())
print("Focal Length: "..F:int().."mm")
print("Steps LUT")
for i = 1, #step_count do
print(step_count[i])
end
print("Focus LUT")
for i = 1, #step_count do
print(x_at_count[i])
end
end
call_event_proc("EFLensCom.FocusSearchNear")
sleep(100)
print("Lens ready")
end
function get_x_based_on_step_pos() -- estimate of focus distance in mm from the sensor plane
-- This function uses a Lagrange estimation scheme, based on a 2nd order three point interpolation assumption
local n = #step_count
local t = call_event_proc('GetEFLensFocusPositionWithLensCom') -- step value at current focus
local j = 1
for i = 2, n do
j = i - 1
if t <= step_count[i] then break end
end
if j >= (n-1) then j = n - 2 end -- handle being at the end of the LUT tables
if get_focus_distance_lower() > 81000 then -- at/beyond any useful lens data
return get_focus_distance_upper()
end
local t1 = step_count[j]
local t2 = step_count[j+1]
local t3 = step_count[j+2]
local pt = fmath.new(0)
pt = pt + (x_at_count[j]*(t-t2)*(t-t3))/((t1-t2)*(t1-t3))
pt = pt + (x_at_count[j+1]*(t-t1)*(t-t3))/((t2-t1)*(t2-t3))
pt = pt + (x_at_count[j+2]*(t-t1)*(t-t2))/((t3-t1)*(t3-t2))
return pt:int() -- focus position in mm
end
function move_by(xx) -- move from current position by xx mm
local current_focus_pos = get_x_based_on_step_pos()
while get_x_based_on_step_pos() < (current_focus_pos+xx) do
call_event_proc("EFLensCom.MoveFocus", 1, 1)
sleep(25)
end
sleep(50)
end
If I'm focus bracketing via the Lua code, I don't think we need the above, ie my current scheme is good enough, ie find the Canon focus step you are in and linearly interpolate. The LUT approach and the lagrange interpolation has value for manual focus position feedback.
I'll carry on playing ;-)