Last active
July 6, 2022 05:27
-
-
Save pigeonhill/742cf84b8dd47a9de8dc5ea65ecc35b6 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--[[ | |
@title LBS-M(Rev2) | |
@chdk_version 1.6 | |
@subtitle Bracketing Options | |
#mode = 0 "Focus?" {Off X2INF Min2INF Manual Min2X SupRes} | |
#bracket = 0 "Exposure?" {Off 1(4Ev) 1(3Ev) 1(2Ev) 2(2Ev) 3(2Ev) ISO AutoX>H Wind3Ev Wind4Ev HandH AutoS>H} | |
#sky = 0 "Sky?" {Off 2Ev 3Ev 4Ev 5Ev 6Ev ETTR} | |
#ndf = 0 "ND?" [-5 30] | |
@subtitle Bracketing Settings | |
#infinity = 3 "Infinity Focus (xH)" [2 4] | |
#overlap = 15 "Overlap Blur (um)" [5 30] | |
#pmag = 1 "Assumed Pupil Mag" [1 6] | |
#hhmin = 30 "HH Min Tv (1/x s)" [10 100] | |
#isoval = 0 "X Bracketing Value" {+1/200 +2/400 +3/800 +4/1600 +5/3200} | |
#srpix = 0 "SupRes Pixel Shift?" {Off -+ ++} | |
@subtitle Other Settings | |
#dofs = 0 "DoF Display" {Blur DoFs Both} | |
#diff = 0 "Diffraction Aware?" {Off On} | |
#traf = 0 "Traffic Lights" {Off On} | |
#evmode = 0 "Exposure Help" {Off Survey ETTR} | |
#sleep_time = 0 "Delay (s)" [0 10] | |
#bookends = 1 "Bookends?" {Off On} | |
#histoon = 0 "CHDK Histogram" {Off On} | |
#screen_off = 0 "Screen?" {Off On} | |
#log = 0 "Log?" {Off On Reset} | |
#help = 0 "Console" {Off On} | |
#lens = 0 "Lens Name?" {Off On} | |
#usefd = 0 "Focus distance" {lower Upper Harmonic} | |
#ettrpl = 1 "low ETTR 1/10 %" [1 10] | |
#ettrpu = 1 "high ETTR %" [1 10] | |
#hlw = 1 "Over X Warning Bins" [1 10] | |
#bp = 0 "Black Level Sensitivity" {Normal Medium High} | |
#limit = 0 "ETTR limit" [0 10] | |
#loop = 0 "Keep running?" {No Yes} | |
Notes: | |
* This script is restricted (at the moment) to only run on the M3. | |
* Go to https://drive.google.com/drive/folders/1drk1xi6kMMIeF5xSqXgnpjGCffF8CVkd?usp=sharing for XIMR builds | |
* Focus functionality and time based ND bracketing needs a registered EF-M lens. Non registered EF-M lenses can only be used with certain exposure bracketing. | |
* The focus bracketing works best with wide angle lenses, as tele lenses will usually mean too many focus brackets ;-) | |
* Set the CHDK ALT button to anything other than m-FN (M3) or VIDEO (M10/100), as these buttons are used as a second shutter button to start bracketing | |
* Register your lens below in the lens_info() function. Note only EF-M lenses will allow full focus functionality. Non EF-M lenses may 'play up' ;-) | |
* This script is not designed for macro focus stacking; it is intended for non-macro, deep focus photography only. | |
* If you reset/delete the log, you need to set the log menu after. | |
* When paused, at the assess point, you can refocus and change focal length and aperture to see the impact on bracketing. | |
* Use the M-Fn button on the M3 to initiate bracketing, or the VIDEO button on the M10/M100. Note you must have selected a focus bracketing option. | |
* If traffic light (TL) feedback is enabled, once an image is captured, the left hand TL shows the near DoF's focus overlap state, relative to the last image captured... | |
...and the right TL shows the far DoF's overlap state relative to the last image captured. Yellow = same focus; green = a positive overlap; red = a negative overlap (a gap). | |
* Changing focal length or aperture will reset the traffic lights. | |
* The CHDK histogram can be toggled on and off by pressing the MENU button | |
* Auto ETTR by pressing the wheel right button. | |
* You can dynamically change the shutter delay by pressing and holding the up button. | |
* If auto exposure bracketing is selected, first set the exposure for the shadows; the script will auto bracket by the requested Ev step until the ETTR exposure is reached | |
* Exposure survey/help provides two options. The first provides Ev feed back on the current exposure relative to the last captured image. The second provides... | |
* ...1/3 stop feedback in the highlight area: green = <x/10% of the histogram is in that 1/3 stop; Yellow = over x/10% and less than y%; and red = over y%... | |
* ...where x and y are selected in the script's menu. Note the top 1/3 stop is divided into two 1/6 stops plus a white bar will appear if the highlight end... | |
* ...of the histogram is not zero. You can set how many bins this represents, ie 1-10. | |
* Use the "Assumed Pupil Mag" menu item to refine focus overlap insurance. Use 1 for a telephoto lens... | |
* ...for a retrofocus lens simply guess the pupil mag if you don't know it (exit/entrance ration), but round up, ie slightly over estimate for DoF insurance | |
* All UI presented distances, ie focus and DoFs, are relative to the sensor plane. | |
* Note: If the bar disappears, just do a half shutter press. | |
Release 1.094 | |
photography.grayheron.net | |
July 2022 | |
--]] | |
require "drawings" | |
props=require'propcase' | |
capmode = require("capmode") | |
bi = get_buildinfo() | |
current_focus_mode = get_focus_mode() | |
current_mode = capmode.get_name() | |
if current_focus_mode ~= 1 then set_mf(1) end | |
set_exit_key("down") | |
if histoon == 0 then set_config_value(1060,0) else set_config_value(1060,1) end | |
inf = 81000 -- infinity trap | |
dirty = true | |
set_console_autoredraw(1) | |
set_console_layout(0,0,45,3) | |
tg = 242 | |
hdmi = 0 | |
non_m = false | |
tv_str = {"32", "25.4","20","16", "12.7", "10","8", "6.3","5","4","3.2", "2.5","2", | |
"1.6", "1.3", "1", "0.8", "0.6", "0.5", "0.4", "0.3", "1/4", "1/5", "1/6", "1/8", "1/10", "1/13", | |
"1/15", "1/20", "1/25", "1/30", "1/40", "1/50", "1/60", "1/80", "1/100", "1/125", "1/160", "1/200", | |
"1/250", "1/320", "1/400", "1/500", "1/640","1/800", "1/1000", "1/1250", "1/1600","1/2000","1/2500", | |
"1/3200","1/4000", "1/5000", "1/6400", "1/8000", "1/10000", "1/12500", "1/16000", "1/20000", "1/25000", | |
"1/32000", "1/40000"} | |
step_count = {} | |
x_at_count ={} | |
CalFL = 0 | |
-- Check if OK to use | |
if not (bi.platform == "m3") then | |
print("Doesn't run on this Cam") | |
sleep(3000) | |
return | |
end | |
if get_gui_screen_width() ~= 360 then | |
print("Need an XIMR build") | |
sleep(3000) | |
return | |
end | |
if capmode.get_name() ~= "M" then | |
print("Put camera in M mode") | |
sleep(3000) | |
return | |
end | |
if log == 2 then | |
print_screen(1) | |
print("Log reset") | |
print("Change log menu") | |
sleep(3000) | |
print_screen(0) | |
return | |
end | |
function units(xx) | |
local xr ="" | |
if xx:int() > 5000 then | |
xr=(xx/1000):tostr(1).."m" | |
elseif xx:int() > 1000 then | |
xr=(xx/10):tostr(0).."cm" | |
else | |
xr=(xx):tostr(0).."mm" | |
end | |
return xr | |
end | |
function update_DoFs(xx) -- update DoF related stuff | |
h = (1000*F*F)/(n*overlap) -- short hyperfocal (mm) | |
H = h + F -- 'full' hyperfocal (mm), as measured from the lens front principal, ie NOT the sensor | |
local q = xx-t | |
u = (((q*(q-4*F)):sqrt() + q)/2):int() -- focus distance in mm from front principal | |
if xx < inf then | |
ndof = (F*F)/(u-F) | |
ndof = ndof+(h*(F-h*pmag))/(pmag*(u+h-F)) | |
ndof = (ndof+(pmag*(2*F+h+t)-F)/pmag) | |
else | |
ndof = H | |
end | |
if 2*u < H:int() then | |
fdof = (F*F)/(u-F) | |
fdof = fdof-(h*(F+h*pmag))/(pmag*(u-h-F)) | |
fdof = (fdof+(pmag*(2*F-h+t)-F)/pmag) | |
num = 0 | |
local uc = u | |
repeat | |
num = num + 1 | |
new_uc = 2*F*F*(pmag-1) + F*(uc-2*pmag*uc) + h*pmag*uc | |
new_uc = (new_uc/( F*(2*pmag-1) + pmag*(h-2*uc))) | |
uc = new_uc | |
until uc:int() >= (H/3):int() | |
num = num + 1 | |
elseif u < H:int() then | |
fdof = (F*F)/(u-F) | |
fdof = fdof-(h*(F+h*pmag))/(pmag*(u-h-F)) | |
fdof = (fdof+(pmag*(2*F-h+t)-F)/pmag) | |
num = 2 | |
else | |
fdof = fmath.new(inf+1) | |
num = 1 | |
end | |
end | |
function get_focus_distance_upper() -- returns upper focus distance in mm, ie cm*10, as 'accuracy' is 1cm from Canon | |
local x=-1 | |
if (bi.platform=="m3") and (bi.platsub=="101a") then | |
x=peek(0x00244916, 2) | |
elseif (bi.platform=="m3") and (bi.platsub=="120f") then | |
x=peek(0x0024495A, 2) | |
elseif (bi.platform=="m3") and (bi.platsub=="121a") then | |
x=peek(0x0024495A, 2) | |
elseif (bi.platform=="m10") then -- same address in 110d, 110f, 110g | |
x=peek(0x00272016, 2) | |
elseif (bi.platform=="m100") and (bi.platsub=="100a") then | |
x=peek(0x001FC7FA, 2) | |
else | |
print('Wrong platform') | |
end | |
if x == -1 then return -1 else return x*10 end | |
end | |
function get_focus_distance_lower() -- returns lower focus distance in mm, ie cm*10, as 'accuracy' is 1cm from Canon | |
local x=-1 | |
if (bi.platform=="m3") and (bi.platsub=="101a") then | |
x=peek(0x00244918, 2) | |
elseif (bi.platform=="m3") and (bi.platsub=="120f") then | |
x=peek(0x0024495C, 2) | |
elseif (bi.platform=="m3") and (bi.platsub=="121a") then | |
x=peek(0x0024495C, 2) | |
elseif (bi.platform=="m10") then -- same address in 110d, 110f, 110g | |
x=peek(0x00272018, 2) | |
elseif (bi.platform=="m100") and (bi.platsub=="100a") then | |
x=peek(0x001FC7FC, 2) | |
else | |
print('Wrong platform') | |
end | |
if x == -1 then return -1 else return x*10 end | |
end | |
function get_focus_distance() | |
local a = fmath.new(get_focus_distance_lower(),1) | |
local b = fmath.new(get_focus_distance_upper(),1) | |
if usefd == 0 then | |
return a:int() | |
elseif usefd == 1 then | |
return b:int() | |
else | |
if b:int() >= inf then | |
return b:int() | |
else | |
return ((2*a*b)/(a+b)):int() | |
end | |
end | |
end | |
function refocus_to(xx) -- Only refocuses towards infinity. Returns requested focus distance in mm | |
local current_x = x -- current focus distance in mm. Based on script's best estimation of where the focus is before moving | |
local steps_total = 0 | |
local steps = 1 | |
local last_step_count = steps_total | |
local steps_back = 0 | |
local last_step_x = current_x | |
while current_x < xx do | |
call_event_proc("EFLensCom.MoveFocus", steps, 1) -- move towards infinity by steps | |
steps_total = steps_total + steps | |
sleep(25) -- for system to catch up | |
current_x = get_x_based_on_step_pos() -- Get Canon based focus position | |
if (current_x ~= last_step_x) and (current_x < xx) then -- just went through a Canon step change | |
last_step_x = current_x | |
last_step_count = steps_total -- close enough | |
end | |
end | |
-- now fine tune position backwards if required | |
steps_back = ((current_x - xx) * (steps_total - last_step_count)) / (current_x - last_step_x) | |
if steps_back > 0 then call_event_proc("EFLensCom.MoveFocus", -steps_back, 1) end | |
sleep(25) -- for system to catch up | |
return xx -- return requested focus position, eg the 'best' estimate in mm as to focus position the script is now at | |
end | |
function lens_name() | |
local pname = 0 | |
if (bi.platform=="m3") then | |
if (bi.platsub == "101a") then | |
pname = 0x00244969 | |
else | |
pname = 0x002449ad | |
end | |
elseif (bi.platform=="m10") then | |
pname = 0x272065 | |
elseif (bi.platform=="m100") and (bi.platsub == "100a") then | |
pname = 0x1FC84E | |
end | |
local len = peek(pname-1,1) | |
local i = 0 | |
local t = {} | |
while i < len do | |
local c = peek(pname + i, 1) | |
if c == 0 then break end | |
table.insert(t, string.char(c)) | |
i = i + 1 | |
end | |
local name = table.concat(t) | |
return name | |
end | |
function restore() | |
clr = tg | |
draw.replace(obj5,"rectf",hdmi+0,0,hdmi+10,15,clr,clr) -- update left traffic light | |
draw.replace(obj6,"rectf",hdmi+350,0,hdmi+360,15,clr,clr) -- update right traffic light | |
set_prop(props.USER_TV,base_s) | |
set_prop(props.USER_AV,base_av) | |
if current_focus_mode ~= 1 then set_mf(0) end | |
if (current_mode ~= "M") then capmode.set(current_mode) end | |
set_lcd_display(1) | |
print_screen(0) | |
cls() | |
sleep(1000) | |
exit_alt() | |
end | |
function my_restore() -- currently the same as the CHDK restore function ;-) | |
clr = tg | |
draw.replace(obj5,"rectf",hdmi+0,0,hdmi+10,15,clr,clr) -- update left traffic light | |
draw.replace(obj6,"rectf",hdmi+350,0,hdmi+360,15,clr,clr) -- update right traffic light | |
set_prop(props.USER_TV,base_s) | |
set_prop(props.USER_AV,base_av) | |
if current_focus_mode ~= 1 then set_mf(0) end | |
if (current_mode ~= "M") then capmode.set(current_mode) end | |
set_lcd_display(1) | |
print_screen(0) | |
cls() | |
sleep(1000) | |
exit_alt() | |
end | |
function set_up() | |
if current_focus_mode ~= 1 then set_mf(1) end -- just in case | |
if (current_mode ~= "M") then capmode.set("M") end -- just in case | |
dof = get_dofinfo() | |
F = fmath.new(dof.focal_length,1000) -- focal length in mm (real) | |
s = get_prop(props.USER_TV) | |
base_s = s | |
base_av = get_prop(props.USER_AV) | |
base_iso = get_iso_mode() | |
n = fmath.new(av96_to_aperture(base_av),1000) -- aperture number as a real | |
s_ev = s | |
press("shoot_half") | |
repeat sleep(10) until get_shooting() | |
release("shoot_half") | |
repeat sleep(10) until (not get_shooting()) | |
last_s = s | |
end | |
function myshoot() | |
local prevcnt = hook_shoot.count() | |
local rawprevcnt = hook_raw.count() | |
press 'shoot_full_only' | |
repeat sleep(10) until prevcnt ~= hook_shoot.count() | |
release 'shoot_full_only' | |
repeat sleep(10) until rawprevcnt ~= hook_raw.count() | |
end | |
function X_bracket() -- multi image capture options | |
press("shoot_half") | |
repeat sleep(10) until get_shooting() | |
release("shoot_half") | |
repeat sleep(10) until (not get_shooting()) | |
s = get_prop(props.TV) | |
set_tv96_direct(s) -- just in case | |
set_iso_mode(base_iso) | |
if bracket == 0 then | |
snap() | |
elseif bracket == 1 then | |
snap() | |
set_tv96_direct(s - 96 * 4) | |
snap() | |
elseif bracket == 2 then | |
snap() | |
set_tv96_direct(s - 96 * 3) | |
snap() | |
elseif bracket == 3 then | |
snap() | |
set_tv96_direct(s - 96 * 2) | |
snap() | |
elseif bracket == 4 then | |
snap() | |
set_tv96_direct(s - 96 * 2) | |
snap() | |
set_tv96_direct(s - 96 * 4) | |
snap() | |
elseif bracket == 5 then | |
snap() | |
set_tv96_direct(s - 96 * 2) | |
snap() | |
set_tv96_direct(s - 96 * 4) | |
snap() | |
set_tv96_direct(s - 96 * 6) | |
snap() | |
elseif bracket == 6 then | |
local iso = get_iso_mode() | |
set_iso_mode(iso) | |
sleep(100) | |
snap() | |
local isov = iso | |
isov = isov + (isoval+1)*3 | |
if isov > 16 then isov = 16 end | |
set_iso_mode(isov) | |
snap() | |
set_iso_mode(iso) | |
elseif bracket == 7 or bracket == 11 then -- auto bracket | |
shot_histo_enable(1) | |
snap() | |
sleep(100) | |
local lower = 1024 - hlw | |
local test=get_histo_range(lower,1023) | |
local test2 = get_histo_range(128,128+bp) | |
local step = 1 | |
while test > 0 and (s + 96 * (isoval+1) * step) <= 1152 do | |
set_tv96_direct(s + 96 * (isoval+1) * step) | |
snap() | |
sleep(100) | |
test=get_histo_range(lower,1023) | |
step = step + 1 | |
end | |
step = 1 | |
if bracket == 11 then -- deal with the shadows | |
while test2 > 0 and (s - 96 * (isoval+1) * step) >= -480 do | |
set_tv96_direct(s - 96 * (isoval+1) * step) | |
snap() | |
sleep(100) | |
test2=get_histo_range(128,128+bp) | |
step = step + 1 | |
end | |
end | |
shot_histo_enable(0) | |
elseif bracket == 8 or bracket == 9 then | |
snap() | |
local iso = get_sv96() | |
set_sv96(iso+96*(bracket-5)) | |
set_tv96_direct(s + 96*(bracket-5)) | |
snap() | |
set_sv96(iso) | |
elseif bracket == 10 then | |
local tv_test = tv96_to_usec(s) -- shutter speed in us | |
if tv_test <= 1000000/hhmin then | |
print("HH Check OK") | |
snap() | |
set_tv96_direct(usec_to_tv96(1000000/hhmin)) | |
snap() | |
local iso = get_iso_mode() | |
if isoval == 1 then | |
isov = 800 | |
elseif isoval == 2 then | |
isov = 1600 | |
elseif isoval == 3 then | |
isov = 3200 | |
end | |
set_iso_mode(isov) | |
set_tv96_direct(usec_to_tv96(1000000/hhmin)) | |
snap() | |
set_iso_mode(iso) | |
else | |
print("Check Xposure") | |
end | |
end | |
set_tv96_direct(s) | |
end | |
function bookend() | |
set_tv96_direct(960) | |
if not non_m then set_av96_direct(get_max_av96()) end | |
local ecnt = get_exp_count() | |
shoot() | |
set_tv96_direct(s) | |
if not non_m then set_av96_direct(base_av) end | |
repeat sleep(10) until (get_exp_count() ~= ecnt) | |
end | |
function hiatus() | |
local M = fmath.new(Mmax,1000) | |
local Fr = fmath.new(Fmax,1000) | |
-- Note the following is an estimate of min zoomed mag, based on assuming MFD is fixed across the zoom range and a thin lens model | |
local M1 = (1+M) | |
local k = Fr/F | |
m=k*M1*M1 | |
m=m-(M1*(k:sqrt())*(k*M1*M1-4*M):sqrt()) | |
m=m-2*M | |
m=m/(2*M) | |
m4macro = m | |
t = (F * (1 + m) * (1 + m)) | |
t = MFD - t/m -- this is an estimate of the spilt thin lens thickness (mm) | |
return t | |
end | |
function lens_info() | |
MFD = 0 | |
CalFL = 0 | |
reg_step_count = {} | |
reg_x_at_count = {} | |
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 | |
reg_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} | |
reg_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 | |
elseif lens_name() == "EF-M28mm f/3.5 MACRO IS STM" then | |
Fmax = 28000 -- Longest focal length (mm) * 1000 | |
Mmax = 1000 -- Max magnification * 1000 | |
MFD = 97 -- Minimum Focus Distance in mm | |
t = hiatus() -- distance between front and rear principals | |
return true | |
elseif lens_name() == "EF-M55-200mm f/4.5-6.3 IS STM" then | |
Fmax = 200000 -- Longest focal length (mm) * 1000 | |
Mmax = 210 -- Max magnification * 1000 | |
MFD = 960 -- Minimum Focus Distance in mm | |
t = hiatus() -- distance between front and rear principals | |
return true | |
elseif lens_name() == "EF-M18-55mm f/3.5-5.6 IS STM" then | |
Fmax = 55000 -- Longest focal length (mm) * 1000 | |
Mmax = 240 -- Max magnification * 1000 | |
MFD = 150 -- Minimum Focus Distance in mm | |
t = hiatus() -- distance between front and rear principals | |
return true | |
elseif lens_name() == "EF-M15-45mm f/3.5-6.3 IS STM" then | |
Fmax = 45000 -- Longest focal length (mm) * 1000 | |
Mmax = 250 -- Max magnification * 1000 | |
MFD = 250 -- Minimum Focus Distance in mm | |
t = hiatus() -- distance between front and rear principals | |
return true | |
elseif lens_name() == "TS-E24mm f/3.5L II" then | |
Fmax = 24000 -- Longest focal length (mm) * 1000 | |
Mmax = 340 -- Max magnification * 1000 | |
MFD = 230 -- Minimum Focus Distance in mm | |
t = hiatus() -- distance between front and rear principals | |
return true | |
--[[ | |
elseif lens_name() == "10-20mm" then | |
Fmax = 20000 -- Longest focal length (mm) * 1000 | |
Mmax = 130 -- Max magnification * 1000 | |
MFD = 240 -- Minimum Focus Distance in mm | |
t = hiatus() -- distance between front and rear principals | |
return true | |
elseif lens_name() == "your lens" then | |
copy template above | |
]] | |
else -- lens not recognised | |
return false | |
end | |
end | |
function update() | |
local pos = 0 | |
if get_gui_screen_width() == 360 then | |
hdmi = 0 | |
else | |
hdmi = 60 | |
end | |
lens_info() | |
x = get_x_based_on_step_pos() | |
update_DoFs(x) -- update u and DoFs | |
draw.replace(obj1,"rectf",hdmi+0,0,hdmi+360,15,tg,tg) -- clear the info bar | |
if x > inf then | |
temp = ">>H:INF" | |
elseif u >= H:int() then | |
temp = (10*(u/H)):int() | |
if temp >= 50 then | |
temp = ">>H:"..units(fmath.new(x,1)) | |
else | |
temp = (temp/10).."."..((temp-(temp/10)*10)).."xH:"..units(fmath.new(x,1)) | |
end | |
else | |
temp = "#"..num..":"..units(fmath.new(x,1)) | |
end | |
draw.replace(obj2,"string",hdmi+10,0,temp,"white",tg) -- draw focus position info | |
local inf_blur = ((overlap*(H-F))/(u-F)) | |
if x >= inf then inf_blur = fmath.new(0,1) end | |
if diff == 1 then -- show impact of diffraction on infinity blur | |
inf_blur = (inf_blur*inf_blur + (1342*n/1000)*(1342*n/1000)):sqrt() | |
end | |
inf_blur = inf_blur:int() | |
local qqq = get_user_tv_id() | |
if get_alt_mode() and evmode == 1 and not image then -- change to Survey mode | |
local temp_s = get_user_tv96() | |
if (temp_s > 1152 or temp_s < -480) then temp = "BULB" else temp = tv_str[qqq+16].."s" end | |
temp_s = fmath.new(temp_s,96) | |
temp_s = fmath.new(s_ev,96)-temp_s | |
if (10*temp_s):int() == 0 then | |
temp_s = " "..temp_s:tostr(1) | |
elseif (10*temp_s):int() > 0 then | |
temp_s = "+"..temp_s:tostr(1) | |
else | |
temp_s = temp_s:tostr(1) | |
end | |
if (get_user_tv96() > 1152 or get_user_tv96() < -480) then | |
temp = "???Ev:BULB" | |
else | |
temp = temp_s.."Ev:"..temp | |
end | |
if (s_ev > 1152 or s_ev < -480) then temp = "???Ev:"..tv_str[qqq+16].."s" end | |
if (s_ev > 1152 or s_ev < -480) and (get_user_tv96() > 1152 or get_user_tv96() < -480) then temp = "???Ev:???" end | |
pos = 180-4*(string.len(temp)) | |
draw.replace(obj3,"string",hdmi+pos, 0,temp,"white",tg) | |
elseif get_alt_mode() and evmode == 2 then -- change to ETTR mode | |
local histo={} | |
local total = 0 | |
local top = 0 | |
local stop3 = 0 | |
local stop2 = 0 | |
local stop1 = 0 | |
local stop4 = 0 | |
local hlwc = 0 | |
histo,total=get_live_histo() | |
for i = 229,255,1 do stop3 = stop3 + histo[i] end -- get the total count in the requested 1/3 stop | |
for i = 206,228,1 do stop2 = stop2 + histo[i] end -- get the total count in the requested 1/3 stop | |
for i = 185,205,1 do stop1 = stop1 + histo[i] end -- get the total count in the requested 1/3 stop | |
for i = 242,255,1 do stop4 = stop4 + histo[i] end -- get the total count in the requested zone | |
for i = 256-hlw,255,1 do hlwc = hlwc + histo[i] end -- get the total count in the requested zone | |
draw.replace(obj3,"string",hdmi+pos, 0,"",tg,tg) | |
clr = "green_light" | |
if stop1 == 0 then | |
clr = "grey_dark" | |
elseif stop1 >= (ettrpl*total)/1000 and stop1 < (ettrpu*total)/100 then | |
clr = "yellow_light" | |
elseif stop1 >= (ettrpu*total)/100 then | |
clr = "red_light" | |
end | |
draw.replace(obj7,"rectf",hdmi+145,0,hdmi+175,15,tg,clr,2) | |
clr = "green_light" | |
if stop2 == 0 then | |
clr = "grey_dark" | |
elseif stop2 >= (ettrpl*total)/1000 and stop2 < (ettrpu*total)/100 then | |
clr = "yellow_light" | |
elseif stop2 >= (ettrpu*total)/100 then | |
clr = "red_light" | |
end | |
draw.replace(obj8,"rectf",hdmi+175,0,hdmi+205,15,tg,clr,2) | |
clr = "green_light" | |
if stop3 == 0 then | |
clr = "grey_dark" | |
elseif stop3 >= (ettrpl*total)/1000 and stop3 < (ettrpu*total)/100 then | |
clr = "yellow_light" | |
elseif stop3 >= (ettrpu*total)/100 then | |
clr = "red_light" | |
end | |
draw.replace(obj9,"rectf",hdmi+205,0,hdmi+235,15,tg,clr,2) | |
clr = "green_light" | |
if stop4 == 0 then | |
clr = "grey_dark" | |
elseif stop4 >= (ettrpl*total)/1000 and stop3 < (ettrpu*total)/100 then | |
clr = "yellow_light" | |
elseif stop4 >= (ettrpu*total)/100 then | |
clr = "red_light" | |
end | |
draw.replace(obj10,"rectf",hdmi+222,2,hdmi+235,13,clr,clr,1) | |
clr = "white" | |
if hlwc == 0 then clr = tg end | |
draw.replace(obj11,"rectf",hdmi+238,2,hdmi+242,13,clr,clr) | |
elseif get_alt_mode() and evmode == 0 then | |
if (get_user_tv96() > 1152 or get_user_tv96() < -480) then temp = "BULB" else temp = tv_str[qqq+16].."s" end | |
temp = F:int().."mm:"..temp | |
pos = 180-4*(string.len(temp)) | |
draw.replace(obj3,"string",hdmi+pos, 0,temp,"white",tg) | |
elseif get_alt_mode() and evmode == 3 then | |
temp = get_x_based_on_step_pos() | |
if temp < inf then temp = temp.."mm" else temp = "INF" end | |
pos = 180-4*(string.len(temp)) | |
draw.replace(obj3,"string",hdmi+pos, 0,temp,"white",tg) | |
end | |
if dofs == 0 then | |
temp = units(ndof)..":"..inf_blur.."um" | |
elseif dofs == 2 then | |
if u < H:int() then | |
temp = units(ndof)..":"..units(fdof) | |
else | |
temp = units(ndof)..":"..inf_blur.."um" | |
end | |
elseif dofs == 1 then | |
if u < H:int() then | |
temp = units(ndof)..":"..units(fdof) | |
else | |
temp = units(ndof)..":INF" | |
end | |
end | |
pos = 350-8*(string.len(temp)) | |
draw.replace(obj4,"string",hdmi+pos,0,temp,"white",tg) | |
if traf == 1 and image then -- display traffic lights | |
local clr = tg | |
if x == last_image_x then | |
clr = "yellow" | |
elseif (ndof >= last_image_ndof) and (ndof <= last_image_fdof) then | |
clr = "green" | |
elseif (ndof > last_image_fdof) or (ndof < last_image_ndof) then | |
clr = "red" | |
end | |
draw.replace(obj5,"rectf",hdmi+0,0,hdmi+10,15,clr,clr) -- update left traffic light | |
if x == last_image_x then | |
clr = "yellow" | |
elseif (fdof <= last_image_fdof) and (fdof >= last_image_ndof) then | |
clr = "green" | |
elseif (fdof > last_image_fdof) or (fdof < last_image_ndof) then | |
clr = "red" | |
end | |
draw.replace(obj6,"rectf",hdmi+350,0,hdmi+360,15,clr,clr) -- update right traffic light | |
local ee = (F*(pmag-1))/(pmag) -- pupil extension in mm | |
local blur = ee*(u+last_image_u)-2*u*last_image_u | |
blur = blur + F*(u+last_image_u-2*ee) | |
blur = blur*n | |
blur = ((1000*F*F*(u-last_image_u))/blur):int() -- blur at overlap in microns | |
if blur < 0 then blur = -blur end | |
if x < inf then | |
temp = F:int().."mm:"..blur.."um" | |
else | |
temp = F:int().."mm:".."???" | |
end | |
pos = 180-4*(string.len(temp)) | |
draw.replace(obj3,"string",pos, 0,temp,"white",tg) | |
else | |
clr = tg | |
draw.replace(obj5,"rectf",hdmi+0,0,hdmi+10,15,clr,clr) -- update left traffic light | |
draw.replace(obj6,"rectf",hdmi+350,0,hdmi+360,15,clr,clr) -- update right traffic light | |
end | |
draw.overdraw() | |
dirty = false | |
end | |
function non_m_update() | |
local pos = 0 | |
if get_gui_screen_width() == 360 then | |
hdmi = 0 | |
else | |
hdmi = 60 | |
end | |
draw.replace(obj1,"rectf",hdmi+0,0,hdmi+360,15,tg,tg) -- clear the info bar | |
local qqq = get_user_tv_id() | |
if get_alt_mode() and evmode == 1 and not image then -- change to Ev or Exp feedback | |
local temp_s = get_user_tv96() | |
if (temp_s > 1152 or temp_s < -480) then temp = "BULB" else temp = tv_str[qqq+16].."s" end | |
temp_s = fmath.new(temp_s,96) | |
temp_s = fmath.new(s_ev,96)-temp_s | |
if (10*temp_s):int() == 0 then | |
temp_s = " "..temp_s:tostr(1) | |
elseif (10*temp_s):int() > 0 then | |
temp_s = "+"..temp_s:tostr(1) | |
else | |
temp_s = temp_s:tostr(1) | |
end | |
if (get_user_tv96() > 1152 or get_user_tv96() < -480) then | |
temp = "???Ev:BULB" | |
else | |
temp = temp_s.."Ev:"..temp | |
end | |
if (s_ev > 1152 or s_ev < -480) then temp = "???Ev:"..tv_str[qqq+16].."s" end | |
if (s_ev > 1152 or s_ev < -480) and (get_user_tv96() > 1152 or get_user_tv96() < -480) then temp = "???Ev:???" end | |
elseif get_alt_mode() and evmode == 2 then -- change to ETTR mode | |
local histo={} | |
local total = 0 | |
local top = 0 | |
local stop3 = 0 | |
local stop2 = 0 | |
local stop1 = 0 | |
local stop4 = 0 | |
local hlwc = 0 | |
histo,total=get_live_histo() | |
for i = 229,255,1 do stop3 = stop3 + histo[i] end -- get the total count in the requested 1/3 stop | |
for i = 206,228,1 do stop2 = stop2 + histo[i] end -- get the total count in the requested 1/3 stop | |
for i = 185,205,1 do stop1 = stop1 + histo[i] end -- get the total count in the requested 1/3 stop | |
for i = 242,255,1 do stop4 = stop4 + histo[i] end -- get the total count in the requested zone | |
for i = 256-hlw,255,1 do hlwc = hlwc + histo[i] end -- get the total count in the requested zone | |
draw.replace(obj3,"string",hdmi+pos, 0,"",tg,tg) | |
clr = "green_light" | |
if stop1 == 0 then | |
clr = "grey_dark" | |
elseif stop1 >= (ettrpl*total)/1000 and stop1 < (ettrpu*total)/100 then | |
clr = "yellow_light" | |
elseif stop1 >= (ettrpu*total)/100 then | |
clr = "red_light" | |
end | |
draw.replace(obj7,"rectf",hdmi+145,0,hdmi+175,15,tg,clr,2) | |
clr = "green_light" | |
if stop2 == 0 then | |
clr = "grey_dark" | |
elseif stop2 >= (ettrpl*total)/1000 and stop2 < (ettrpu*total)/100 then | |
clr = "yellow_light" | |
elseif stop2 >= (ettrpu*total)/100 then | |
clr = "red_light" | |
end | |
draw.replace(obj8,"rectf",hdmi+175,0,hdmi+205,15,tg,clr,2) | |
clr = "green_light" | |
if stop3 == 0 then | |
clr = "grey_dark" | |
elseif stop3 >= (ettrpl*total)/1000 and stop3 < (ettrpu*total)/100 then | |
clr = "yellow_light" | |
elseif stop3 >= (ettrpu*total)/100 then | |
clr = "red_light" | |
end | |
draw.replace(obj9,"rectf",hdmi+205,0,hdmi+235,15,tg,clr,2) | |
clr = "green_light" | |
if stop4 == 0 then | |
clr = "grey_dark" | |
elseif stop4 >= (ettrpl*total)/1000 and stop3 < (ettrpu*total)/100 then | |
clr = "yellow_light" | |
elseif stop4 >= (ettrpu*total)/100 then | |
clr = "red_light" | |
end | |
draw.replace(obj10,"rectf",hdmi+222,2,hdmi+235,13,clr,clr,1) | |
clr = "white" | |
if hlwc == 0 then clr = tg end | |
draw.replace(obj11,"rectf",hdmi+238,2,hdmi+242,13,clr,clr) | |
temp = "" | |
else | |
if (get_user_tv96() > 1152 or get_user_tv96() < -480) then temp = "BULB" else temp = tv_str[qqq+16].."s" end | |
temp = "??mm:"..temp | |
end | |
pos = 180-4*(string.len(temp)) | |
draw.replace(obj3,"string",hdmi+pos, 0,temp,"white",tg) | |
draw.overdraw() | |
dirty = false | |
end | |
function snap() -- single image capture | |
press("shoot_half") | |
repeat sleep(10) until (get_shooting()) | |
myshoot() | |
release("shoot_half") | |
repeat sleep(10) until (not get_shooting()) | |
end | |
function check_focus_etc() | |
dof = get_dofinfo() | |
local test_x = get_x_based_on_step_pos() | |
local test_n = fmath.new(av96_to_aperture(get_user_av96()),1000) | |
local test_F = fmath.new(dof.focal_length,1000) | |
if test_F:int() ~= F:int() or test_n:int() ~= n:int() then | |
dirty = true | |
image = false | |
elseif test_x ~= x then | |
dirty = true | |
end | |
if test_F:int() ~= F:int() and CalFL ~= 0 then | |
repeat | |
F = test_F | |
sleep(1000) | |
dof = get_dofinfo() | |
test_F = fmath.new(dof.focal_length,1000) | |
until test_F:int() == F:int() | |
if #reg_step_count > 0 and F:int() == CalFL then | |
call_event_proc("EFLensCom.FocusSearchNear") | |
call_event_proc("EFLensCom.FocusSearchNear") | |
sleep(100) | |
offset = call_event_proc('GetEFLensFocusPositionWithLensCom') | |
print("offset = "..offset) | |
for i = 1, #reg_step_count do | |
step_count[i] = reg_step_count[i] + offset | |
x_at_count[i] = reg_x_at_count[i] | |
end | |
else | |
set_up_lens() | |
end | |
end | |
dirty = true | |
F = test_F | |
n = test_n | |
x = test_x | |
end | |
function check_buttons_etc() | |
wait_click(50) -- check for a button press | |
do | |
local iso = get_iso_mode() | |
local tv = get_prop(props.USER_TV) | |
snapped = false | |
if is_key("up") and get_alt_mode() then -- Change delay time | |
while (is_pressed("up")) do | |
sleep(500) | |
sleep_time = sleep_time + 1 | |
if sleep_time > 10 then sleep_time = 0 end | |
print("delay ="..sleep_time.."s") | |
end | |
release("up") | |
elseif is_key("right") and get_alt_mode() then -- ETTR requested | |
set_ETTR() | |
elseif is_key("set") and get_alt_mode() then | |
click("set") | |
elseif is_key("left") and get_alt_mode() then | |
click("left") | |
elseif is_key("shoot_half") and get_alt_mode() then -- do a manual refresh of the info bar | |
s_ev = get_user_tv96() | |
dirty = true | |
elseif ((is_key("print") and bi.platform=="m3") or (is_key("video") and ((bi.platform=="m10") or (bi.platform=="m100")))) and get_alt_mode() then | |
if mode == 3 or mode == 0 then -- take an exposure bracket set | |
set_up() | |
sleep(sleep_time*1000) | |
if bookends == 1 then bookend() end | |
X_bracket() | |
ND_test() | |
if sky == 6 then -- take an auto ETTR exposure bracket for the sky | |
set_ETTR() | |
snap() | |
print("Sky X") | |
elseif sky > 0 then -- take a single exposure shot for the sky | |
set_tv96_direct(s + 96*(sky+1)) | |
snap() | |
print("Sky X") | |
end | |
if bookends == 1 then bookend() end | |
snapped = true | |
last_image_ndof = ndof | |
last_image_fdof = fdof | |
last_image_x = x | |
last_image_u = u | |
finish = false | |
image = true | |
dirty = true | |
elseif mode == 5 then -- take a superres set (make sure you set the move logic in the menu) | |
set_up() | |
if bookends == 1 then bookend() end | |
sleep(sleep_time*1000) | |
set_tv96_direct(s) | |
if ndf > 0 then i = ndf end | |
if ndf == -1 or ndf == 0 then | |
i = 2 | |
elseif ndf == -2 then | |
i = 4 | |
elseif ndf == -3 then | |
i = 8 | |
elseif ndf == -4 then | |
i = 16 | |
elseif ndf == -5 then | |
i = 32 | |
end | |
if ndf ~= 0 then | |
if srpix == 1 then -- move focus to new start | |
for j = 1, i/2 do | |
call_event_proc("EFLensCom.MoveFocus", -1, 1) | |
sleep(50) | |
end | |
end | |
for j = 1, i do | |
snap() | |
sleep(1000) | |
if srpix ~= 0 and get_x_based_on_step_pos() < inf then | |
call_event_proc("EFLensCom.MoveFocus",1,1) -- move smallest step you can towards infinity | |
sleep(50) | |
end | |
end | |
end | |
update() | |
last_image_ndof = ndof | |
last_image_fdof = fdof | |
last_image_x = x | |
last_image_u = u | |
finish = false | |
image = true | |
dirty = true | |
if sky == 6 then | |
set_ETTR() | |
snap() | |
print("Sky X") | |
elseif sky > 0 then -- take a single exposure shot for the sky | |
set_tv96_direct(s + 96*(sky+1)) | |
snap() | |
print("Sky X") | |
end | |
snapped = true | |
if bookends == 1 then bookend() end | |
elseif mode > 0 then -- do some auto focus bracketing | |
finish = true | |
end | |
elseif is_key("menu") and get_alt_mode() then | |
if get_config_value(1060) == 0 then set_config_value(1060,1) else set_config_value(1060,0) end | |
dirty = true | |
elseif is_key("display") and get_alt_mode() then | |
click("display") | |
dirty = true | |
end | |
if snapped then | |
set_iso_mode(base_iso) | |
set_prop(props.USER_TV,tv) | |
end | |
if get_alt_mode() ~= last_alt_state then -- ALT state changed | |
last_alt_state = get_alt_mode() | |
image = false | |
s_ev = get_user_tv96() -- reset ev feedback | |
dirty = true | |
end | |
if (last_s ~= get_user_tv96()) then | |
dirty = true | |
last_s = get_user_tv96() | |
end | |
end | |
end | |
function set_ETTR() | |
do | |
local histo={} | |
local total = 0 | |
histo,total=get_live_histo() | |
total = 0 | |
local max = #histo | |
local start = max-hlw | |
for i = start,(max-1),1 do total = total + histo[i] end -- get the total count in the requested quartiles | |
local sl = 50 | |
if total <= 0 then -- underexposed | |
repeat | |
wheel_left() | |
sleep(sl) | |
histo,total=get_live_histo() | |
total = 0 | |
for i = start,(max-1),1 do total = total + histo[i] end | |
until total > limit or get_prop(props.USER_TV) <= -480 | |
end | |
if total > limit then | |
repeat | |
wheel_right() | |
sleep(sl) | |
histo,total=get_live_histo() | |
total = 0 | |
for i = start,(max-1),1 do total = total + histo[i] end | |
until total <= limit or get_prop(props.USER_TV) >= 1056 | |
end | |
s = get_prop(props.USER_TV) | |
set_user_tv96(s) | |
press("shoot_half") | |
repeat sleep(10) until get_shooting() | |
release("shoot_half") | |
repeat sleep(10) until (not get_shooting()) | |
return | |
end | |
end | |
function ND_test() | |
if ndf > 0 and not non_m then -- capture an ND sim bracket subset based on time | |
base_shutter_time = tv96_to_usec(base_s) | |
max_av = get_max_av96() | |
current_av = get_av96() | |
if base_shutter_time < 1000000*ndf then | |
if bookends == 1 then bookend() end -- additional bookends for ND brackets | |
del_av = max_av - current_av -- max av shift available in ev | |
del_tv = base_s - usec_to_tv96(ndf*1000000) -- required tv shift in ev | |
if del_tv < del_av then -- adjust things | |
temp_av = (current_av+del_tv) | |
temp = base_s - del_tv -- adjust shutter time to match aperture | |
else | |
temp_av = max_av -- set to max | |
temp = base_s - del_av -- adjust shutter time to match aperture | |
end | |
if temp < -480 then -- max shutter of 30s: just in case | |
temp = -480 | |
end | |
i = 1 + (ndf*1000000)/tv96_to_usec(temp) | |
print(i.." ND brackets") | |
for j = 1, i do | |
set_tv96_direct(temp) | |
set_av96(temp_av) | |
snap() | |
end | |
if bookends == 1 then bookend() end | |
set_av96(current_av) | |
set_tv96(base_s) | |
end | |
elseif ndf > 0 and non_m then -- can't capture an ND sim bracket subset based on time (should never get here, but just in case) | |
print("Use -ND option") | |
elseif ndf <0 then -- capture an ND sim bracket subset based on ND filter | |
if bookends == 1 then bookend() end | |
if ndf == -1 then | |
i = 2 | |
elseif ndf == -2 then | |
i = 4 | |
elseif ndf == -3 then | |
i = 8 | |
elseif ndf == -4 then | |
i = 16 | |
elseif ndf == -5 then | |
i = 32 | |
end | |
print(i.." ND brackets") | |
for j = 1, i do | |
snap() | |
end | |
if bookends == 1 then bookend() end | |
end | |
end | |
function macro_bracket() | |
local freq = fmath.new(550,1000000) -- change if infra red | |
local macro_dof = (4*freq*(n*n*(1+m4macro)*(1+m4macro)))/(m4macro*m4macro) -- diffraction limited macro DoF estimate | |
print("Macro DoF = "..(1000*macro_dof):int().."um") | |
local x_end = get_x_based_on_step_pos() | |
if x_end <= MFD then | |
print("Reset end focus") | |
sleep(3000) | |
return 0 | |
end | |
local steps = ((x_end - MFD)/macro_dof):int() | |
local i = 0 | |
local current_x = get_x_based_on_step_pos() | |
while current_x > MFD do | |
call_event_proc("EFLensCom.MoveFocus", -1, 1) -- move smallest step you can towards MFD | |
i = 1 + i | |
current_x = get_x_based_on_step_pos() | |
sleep(25) -- for system to catch up | |
end | |
print("Total steps = "..i) | |
local jump = i/steps | |
if jump <= 0 then jump = 1 end | |
print("# of brackets = "..steps) | |
if steps <= 0 then steps = 1 end | |
for i = 1, steps do | |
call_event_proc("EFLensCom.MoveFocus", jump, 1) | |
sleep(25) | |
X_bracket() | |
end | |
return 1 | |
end | |
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") | |
test = get_focus_distance_upper() | |
print(test) | |
ii = 0 | |
while get_focus_distance_upper() < inf do | |
call_event_proc("EFLensCom.MoveFocus", 1, 1) | |
ii = ii +1 | |
test = get_focus_distance_lower() | |
test2 = call_event_proc('GetEFLensFocusPositionWithLensCom') | |
print(ii.."/"..test.."/"..test2) | |
sleep(50) -- 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 | |
if CalFL == 0 then return get_focus_distance() end -- don't use focus LUTs | |
local nn = #step_count | |
local t = call_event_proc('GetEFLensFocusPositionWithLensCom') -- step value at current focus | |
local j = 1 | |
for i = 1, nn do | |
j = i - 1 | |
if t == step_count[i] then | |
return x_at_count[i] | |
end | |
if t < step_count[i] then break end | |
end | |
if get_focus_distance_lower() > 81000 then -- at/beyond any useful lens data | |
return get_focus_distance_upper() | |
end | |
-- handle being at the end of the LUT tables | |
if j >= (nn-1) then j = nn - 2 elseif j < 1 then j = 1 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 | |
--[[ NOT USED | |
function move_to(xx) | |
local n = #step_count | |
local t = call_event_proc('GetEFLensFocusPositionWithLensCom') -- step value at current focus | |
local current_focus_pos = get_x_based_on_step_pos() | |
local j = 1 | |
for i = 2, n do | |
j = i - 1 | |
if xx <= x_at_count[i] then break end | |
end | |
if j >= (n-1) then j = n - 2 end -- handle being at the end of the LUT tables | |
local t1 = x_at_count[j] | |
local t2 = x_at_count[j+1] | |
local t3 = x_at_count[j+2] | |
local pt = fmath.new(0) | |
pt = pt + (step_count[j]*(xx-t2)*(xx-t3))/((t1-t2)*(t1-t3)) | |
pt = pt + (step_count[j+1]*(xx-t1)*(xx-t3))/((t2-t1)*(t2-t3)) | |
pt = pt + (step_count[j+2]*(xx-t1)*(xx-t2))/((t3-t1)*(t3-t2)) | |
pt = pt:int() | |
pt = pt - t | |
for i = 1, pt do | |
call_event_proc("EFLensCom.MoveFocus", 1, 1) | |
sleep(25) | |
end | |
sleep(25) | |
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 | |
-- Main Section | |
if log == 1 then print_screen(-1) end | |
if lens == 1 then | |
print_screen(-1) | |
print(lens_name()) | |
sleep(3000) | |
return | |
end | |
set_up() | |
if lens_info() == false then -- don't run | |
print("Need an M lens") | |
sleep(3000) | |
return | |
elseif CalFL ~= 0 then -- use focus LUTs | |
call_event_proc("EFLensCom.FocusSearchNear") | |
call_event_proc("EFLensCom.FocusSearchNear") | |
sleep(100) | |
call_event_proc('FA.Create') | |
call_event_proc('InitializeAdjustmentSystem') | |
--call_event_proc("EFLensCom.GetFocusPitch") | |
sleep(100) | |
if #reg_step_count > 0 and F:int() == CalFL then | |
offset = call_event_proc('GetEFLensFocusPositionWithLensCom') | |
print("offset = "..offset) | |
for i = 1, #reg_step_count do | |
step_count[i] = reg_step_count[i] + offset | |
x_at_count[i] = reg_x_at_count[i] | |
end | |
else | |
set_up_lens() | |
end | |
-- else dont use focus LUTs | |
end | |
x = get_x_based_on_step_pos() | |
print_screen(0) -- switch off logging until bracketing | |
if help == 0 then -- then switch off console display | |
set_console_layout(0,0,1,0) | |
print("") | |
set_console_autoredraw(-1) | |
else | |
set_console_layout(0,0,45,2) | |
end | |
-- Set up the bar drawing objects | |
obj1 = draw.add("rectf", 0, 0, 0, 0, tg,tg) | |
obj2 = draw.add("string", 0, 0, "","white",tg) | |
obj3 = draw.add("string", 0,0,"","white",tg) | |
obj4 = draw.add("string",0,0,"","white",tg) | |
obj5 = draw.add("rectf", 0, 0, 0, 0, tg,tg) | |
obj6 = draw.add("rectf", 0, 0, 0, 0, tg,tg) | |
obj7 = draw.add("rectf", 0, 0, 0, 0, tg,tg) | |
obj8 = draw.add("rectf", 0, 0, 0, 0, tg,tg) | |
obj9 = draw.add("rectf", 0, 0, 0, 0, tg,tg) | |
obj10 = draw.add("rectf", 0, 0, 0, 0, tg,tg) | |
obj11 = draw.add("rectf", 0, 0, 0, 0, tg,tg) | |
last_alt_state = get_alt_mode() | |
image = false -- no image taken yet | |
last_image_ndof = fmath.new(0) | |
last_image_fdof = fmath.new(0) | |
last_image_x = fmath.new(0) | |
last_image_u = fmath.new(0) | |
ecnt = get_exp_count() | |
finish = false | |
histo={} | |
repeat -- exit script via ALT exit button | |
repeat -- stay here while in asssess/shooting mode. THIS IS THE PIVOT POINT OF THE SCRIPT | |
if not non_m then check_focus_etc() end | |
check_buttons_etc() | |
if screen_needs_refresh() then dirty = true end | |
if dirty and not non_m then update() end | |
if dirty and non_m then non_m_update() end | |
sleep(300) | |
until finish -- then take menu requested custom brackets | |
if log == 1 then print_screen(-1) end -- switch focus bracketing logging on | |
if mode == 2 or mode == 4 then -- move to focus minimum | |
if mode == 4 and x > H:int() then | |
x_end = 2*H:int() | |
else | |
x_end = get_x_based_on_step_pos() | |
end | |
repeat | |
x = get_x_based_on_step_pos() | |
call_event_proc("EFLensCom.FocusSearchNear") | |
sleep(50) | |
until x == get_x_based_on_step_pos() | |
update_DoFs(x) | |
end | |
set_up() -- for focus bracketing | |
if log == 1 then | |
set_console_autoredraw(-1) | |
print_screen(-1) | |
print("...") | |
print(os.date()) | |
print("Diffraction Aware: "..diff) | |
print("Overlap Blur: "..overlap.."um") | |
print("Assumed Pupil Mag: "..pmag) | |
set_console_autoredraw(1) | |
end | |
t1=os.time() -- start the clock | |
draw.clear() | |
print_screen(0) | |
print("Bracketing Started") | |
if bookends == 1 then bookend() end | |
t1=sleep_time-(os.time()-t1) | |
if t1 > 0 then sleep(t1*1000) end | |
if screen_off == 0 then set_lcd_display(0) end | |
if mode == 6 then | |
macro_bracket() | |
if bookends == 1 then bookend() end | |
my_restore() | |
return | |
end | |
x = get_x_based_on_step_pos() | |
print("FB #1 @ "..units(fmath.new(x))) | |
X_bracket() -- First exposure(s) | |
del_u = 0 | |
i = 1 | |
while (u < (H/3):int()) do -- capture the rest of the focus brackets up to H/3 | |
-- Note that focus bracketing is calculated/updated in u space, but actual refocusing is in x space | |
-- All console feedback is in x space, ie distance estimates measured from the sensor | |
new_u = 2*F*F*(pmag-1) + F*(u-2*pmag*u) + h*pmag*u | |
new_u = (new_u/( F*(2*pmag-1) + pmag*(h-2*u))) -- new u in mm, using DOFIS model | |
if new_u:int() <= u then new_u = u + 5 end -- move at least 5mm, just in case. Remember: script is not designed for macro work! | |
del_u = (new_u - u) | |
u = new_u:int() | |
xtemp = (u + F + (F*F)/(u-F) + t) -- next focus bracket estimate in x space: in mm from f(1+m)+t+u | |
if mode == 4 then | |
if xtemp:int() > x_end then | |
print("last image @ "..units(fmath.new(get_x_based_on_step_pos()))) | |
X_bracket() | |
break | |
end | |
end | |
move_by(del_u:int()) | |
i = i + 1 -- keep track of number of images taken | |
print("FB #"..i.." @ "..units(fmath.new(get_x_based_on_step_pos()))) | |
X_bracket() | |
x = xtemp:int() | |
end | |
if u < H:int() and mode ~= 4 then -- take image(s) at H | |
temp = ((F*F)/(H-F) + F + t + H) | |
temp = H:int() - u | |
move_by(temp) | |
print("@H = "..get_x_based_on_step_pos().."mm") | |
X_bracket() | |
end | |
if u < infinity*H:int() and mode ~= 4 then -- take image(s) at infinity*H | |
temp = ((F*F)/(infinity*H-F) + F + t + infinity*H):int() | |
if temp > inf then -- adjust as at/beyond lens infinity | |
repeat | |
infinity = infinity - 1 | |
temp = ((F*F)/(infinity*H-F) + F + t + infinity*H):int() | |
until temp < inf or infinity == 2 | |
end | |
temp = temp - get_x_based_on_step_pos() | |
move_by(temp) | |
print("@"..infinity.."xH = "..temp.."mm") | |
X_bracket() | |
end | |
ND_test() | |
if sky == 6 then -- take an auto ETTR exposure bracket for the sky | |
set_ETTR() | |
snap() | |
set_tv96_direct(base_s) | |
print("Sky X") | |
elseif sky > 0 then -- take a single exposure shot for the sky | |
set_tv96_direct(s + 96*(sky+1)) | |
snap() | |
set_tv96_direct(base_s) | |
print("Sky X") | |
end | |
if bookends == 1 then bookend() end | |
finish = false | |
until loop == 0 | |
my_restore() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment