Magic Lantern Forum

Developing Magic Lantern => Scripting Corner => Scripting API suggestions => Topic started by: garry23 on June 18, 2016, 05:53:21 PM

Title: [DONE - lens.focus updated] Lua Request/Idea
Post by: garry23 on June 18, 2016, 05:53:21 PM
David/Alex

As you prepare for the next Lua uplift in the nightlies, I was wondering if you could consider adding in an error check in lens.focus.

The error check would look for soft limit reached (macro or inf end), such that the user can take script action.

At the moment if that error is generated, the script stops as there is no way in Lua (as far as I know) to detect that error and act on it.

Cheers

Garry
Title: Re: Lua Request/Idea
Post by: dmilligan on June 18, 2016, 06:10:26 PM
I thought I already mentioned it, but the function returns (boolean) whether or not the call was successful, this is just missing from the documentation.
Title: Re: Lua Request/Idea
Post by: garry23 on June 18, 2016, 06:19:32 PM
Sorry David, I didn't pick up on that.

Does that mean I can intercept the soft focus limit error before that error stops my script?
Title: Re: Lua Request/Idea
Post by: garry23 on June 18, 2016, 06:43:03 PM
David

My Lua coding is slow as I have to test on the camera. Nevertheless I have looked at lens.focus returns and it seems to return true or false, even if soft focus limit not reached.

The code in the Lua module is this :

Code: [Select]
static int luaCB_lens_focus(lua_State * L)
{
    LUA_PARAM_INT(num_steps, 1);
    LUA_PARAM_INT_OPTIONAL(step_size, 2, 2);
    LUA_PARAM_BOOL_OPTIONAL(wait, 3, true);
    LUA_PARAM_INT_OPTIONAL(extra_delay, 4, 0);
    lua_pushboolean(L, lens_focus(num_steps, step_size, wait, extra_delay));
    return 1;
}

Which to my dumb eyes looks like it returns 1 (true?) everytime.

I'm a little confused to say the least.

So the question in my mind is: what does lens-focus return, ie what does a true or false return mean?
Title: Re: Lua Request/Idea
Post by: a1ex on June 18, 2016, 06:44:24 PM
The focus tests in api_test.lua actually stop on error. Try them.
Title: Re: Lua Request/Idea
Post by: garry23 on June 18, 2016, 06:47:39 PM
Alex

Thanks: I'll look through those.

What I'm trying to do is intercept the soft focus limit reached, before it stops Lua working, and take appropriate action.

Cheers

Garry
Title: Re: Lua Request/Idea
Post by: garry23 on June 18, 2016, 07:12:44 PM
A1ex

I looked at the api_test and I thought I got it, but when I use the following code snippet, I can't get it to run.

As I say, 'all' I'm trying to do is detect the soft limit error.

Any help/hints would be gratefully received :)

Code: [Select]
elseif keymenu.submenu["Focus bracketing?"].value == "FP2MAC" then
repeat
a1=a2
b1=b2
repeat
lens_error = lens.focus(1,1,true)
b2 = lens.dof_far
a2 = lens.dof_near
if a2 == a1 then -- move lens a bit more just to be sure
lens_error = lens.focus(1,1,true)
b2 = lens.dof_far
a2 = lens.dof_near
end
fp = lens.focus_distance
until b2 < a1 or lens_error == false
lens_error = lens.focus(-1,1,true) -- move forward one step for focus bracket overlap
take_brackets()
until lens_error == false
end
Title: Re: Lua Request/Idea
Post by: BBA on June 18, 2016, 07:17:17 PM
@garry23
I have been out travelling to Switzerland.
If I can help, please look at this piece of code I used when scanning a lens step by step testing the return of lens.focus as dmilligan had told it (thanks a lot).
...
 ret = lens.focus(num_steps, step_size, wait, extra_delay)
 stret = "false"
 if ret then stret = "true" end
...
The script gets the return of lens.focus in the "ret" variable and tests it's value.
I don't see how to join a file (I have plotted the return values to see at which step the false value is output....) I am sure I miss something.
Title: Re: Lua Request/Idea
Post by: garry23 on June 18, 2016, 07:22:51 PM
@BBA

Many thanks for trying to help.

I think I'm getting confused over what wait is doing, ie it's a bol.

'All' my script does is 'look' for lens.focus to return a false, which I'm interpreting as a soft limit reached, ie an error, however, lens.focus seems to return a false even if the lens is no where near the soft limit.

Once again, thanks for trying to help me.
Title: Re: Lua Request/Idea
Post by: BBA on June 18, 2016, 07:37:57 PM
Here is my code (if it can help).
For the moment, I don't actually see what is wrong with your code.

Code: [Select]

require('logger')
scan_log = nil

-- Declare a few global variables for the script
a1 = 0
b1 = 0
a2 = 0
b2 = 0

fp = 0
fp1 = 0
fp2 = 0
inf = 100000

ic = 0
istep = 0
num_steps = 0

delay = 3000

BB_ST1 = "TEST"
BB_ST2 = "TEST"
BB_ST3 = "TEST"
BB_ST4 = "TEST"

--  BB_move_focus (num_steps[, step_size=2[, wait=true[, extra_delay=0]]])
--  with log

function BB_move_focus(num_steps, step_size, wait, extra_delay)
 local ret = true
 local stret = "true"
 
    msleep(300) -- BBA
    fp1 = lens.focus_distance


        --  lens.focus (num_steps[, step_size=2[, wait=true[, extra_delay=0]]])
        --[[
            Moves the focus motor a specified number of steps. Only works in LV.

            Parameters:

            num_steps int
            step_size int (default 2)
            wait bool (default true)
            extra_delay int (default 0)
        --]]
   
    [color=green]ret = lens.focus(num_steps, step_size, wait, extra_delay)  -- step size fixed at 1 to count steps and detect changes
    stret = "false"
    if ret then stret = "true" end[/color]
   
    istep = istep+num_steps
    msleep(400) -- BBA
    fp2 = lens.focus_distance
    scan_log:writef("%d,\" move_focus(%d,%d) : before = \",%d,\" / after = \",%d %5s",istep,num_steps,step_size,fp1,fp2,stret)
    scan_log:writef(",\" dof near = \",%s,\" dof far = \",%s\n", lens.dof_near, lens.dof_far)
   
    return ret
   
end



function BB_scan_focus_range()
local ret = true

    menu.close()
   
    scan_log = logger("ML/logs/scan.log") -- if file already exists in /ML/LOGS dir, new log lines will be appended
   
    ic = 0                          -- steps counter
    istep = 0
   
    scan_log:writef("lens = %s\n\n",lens.name)
    BB_ST1 = tostring(camera.aperture.value)
    scan_log:writef("     aperture = %s \n",BB_ST1)
    BB_ST2 = tostring(lens.hyperfocal)
    scan_log:writef("     hyperfocal = %s mmm\n",BB_ST2)
   
    lv.start()

    msleep(delay)
   
   
    while ( ic <= 30 ) do
       
       
        fp = lens.focus_distance
       
        if fp >= inf  -- dépasser 100000
        then
            ic = ic + 1
           
        end
       
        ret = BB_move_focus(-1,1,true,0)  -- vers infini(-1), 1 step, wait for focus motor to stabilize
       
    end
       
    scan_log:close()

end

BB_scan_menu = menu.new
{
    parent = "Shoot",
    name = "Scan focus range ",
    help = "Remember: FROM Macro end TO Infinity+",
    --  depends_on = DEPENDS_ON.LIVEVIEW,
    submenu =
    {
        {
            name = "Run Script",
            help = "Does what it says after pressing SET",
            select = function(this)
                 task.create(BB_scan_focus_range)
            end,
        }
    }
}

Title: Re: Lua Request/Idea
Post by: garry23 on June 18, 2016, 07:42:10 PM
@BBA

Thanks for sharing :)

Do you assume the lens.focus return bol value is TRUE if the lens.focus functioned correctly or incorrectly?
Title: Re: Lua Request/Idea
Post by: BBA on June 18, 2016, 07:51:24 PM
About timings, you are right, mine is very slow, purposely. I have to be sure the value of focal distance has changed. I think if you don't wait enough, the lens has not got the time to send its status back, I saw it at least for the focal distance; maybe, it's also true with the boolean returned...

Quote
Do you assume the lens.focus return bol value is TRUE if the lens.focus functioned correctly or incorrectly?

If you refer to the green lines where sret is initialized and then changed, it's only a way of programming things. it is given one of the two values (yes to false) and afterwards, changed if the real value is the opposite.
Title: Re: Lua Request/Idea
Post by: garry23 on June 18, 2016, 08:22:12 PM
@BBA

I think I'll have to give up as I'm getting a headache!

This code simply will not work, ie detect the soft limit error

Code: [Select]
elseif keymenu.submenu["Focus bracketing?"].value == "FP2MAC" then
repeat
a1=a2
b1=b2
repeat
lens_error = lens.focus(1,1,true)
b2 = lens.dof_far
a2 = lens.dof_near
if a2 == a1 then -- move lens a bit more
lens_error = lens.focus(1,1,true)
b2 = lens.dof_far
a2 = lens.dof_near
end
fp = lens.focus_distance
until b2 < a1 or lens_error == false
lens_error = lens.focus(-1,1,true) -- move forward one step for focus bracket overlap
take_brackets()
until lens_error == false
end
Title: Re: Lua Request/Idea
Post by: a1ex on June 18, 2016, 08:31:18 PM
Minimal example (https://en.wikipedia.org/wiki/Minimal_Working_Example), please.
Title: Re: Lua Request/Idea
Post by: garry23 on June 18, 2016, 08:44:32 PM
Sorry A1ex

This test script works as I would 'hope', ie the soft limit error is displayed in LV, but the script carries on working.

Code: [Select]
function focus()
local lens_error
repeat
lens_error = lens.focus(1,1,true)
until lens_error == false
-- now move the other way having detected the soft limit
lens_error = lens.focus(-10,1,true)
end

scrnshot_menu = menu.new
{
    name = "Test",
select = function(this)
task.create(focus)
end
}

My code, below, simply refuses to work through the soft limit error :(
Title: Re: Lua Request/Idea
Post by: BBA on June 18, 2016, 09:34:49 PM
This one works
Code: [Select]
function focus()
local lens_error
 repeat
    msleep(100)
  lens_error = lens.focus(1,1,true)
    msleep(400)
 until lens_error == false
 -- now move the other way having detected the soft limit
 lens_error = lens.focus(-10,1,true)
end

scrnshot_menu = menu.new
{
    name = "Test",
  select = function(this)
   task.create(focus)
  end
}

Note : moving towards macro end (put the lens just before macro end to go faster)
Title: Re: Lua Request/Idea
Post by: BBA on June 19, 2016, 06:11:33 AM
I think the moving direction (sign of first parameter in lens.focus) should be changed.

This one works if you put the lens just before infinity: you then start the script : immediately after, switch to LV to see the error message "focus limit reached"

Code: [Select]
function focus()
local lens_error
 repeat
  lens_error = lens.focus(-1,1,true)
 until lens_error == false
 -- now move the other way having detected the soft limit
 lens_error = lens.focus(10,1,true)
end

scrnshot_menu = menu.new
{
    name = "Test",
  select = function(this)
   task.create(focus)
  end
}
Title: Re: Lua Request/Idea
Post by: garry23 on June 19, 2016, 08:36:45 AM
@BBA

First, thanks for continuing to try and help me.

Here is a test script that works:

Code: [Select]
function focus()
local stop = false
repeat
if lens.focus(1,1,true) then stop = false else stop = true end
until stop
-- now move the other way having detected the soft limit
lens.focus(-10,1,true)
end

scrnshot_menu = menu.new
{
    name = "Test",
select = function(this)
task.create(focus)
end
}

All this does is drive the lens to the macro end and stop when lens.focus return a false.

However, if i use the same approach in my full script, the above simple coding doesn't work, which implies something else is wrong, but I can't work out what.

Here is the snippet of the full script. One part of the code runs from the focus point to infinity (and works ok), the other runs from the focus point to the macro (and doesn't run: no errors just the lens.focus doesn't run).

it's a mystery.

Code: [Select]
if lens.focus_distance < inf and no_tv_error then
if keymenu.submenu["Focus bracketing?"].value == "FP2INF" then
repeat
a1=a2
b1=b2
repeat
lens.focus(-1,1,true)
b2 = lens.dof_far
a2 = lens.dof_near
fp = lens.focus_distance
until a2 > b1 or fp >= inf
lens.focus(1,1,true) -- move back one step for focus bracket overlap
take_brackets()
until fp >= inf
else
repeat
a1=a2
b1=b2
repeat
if lens.focus(1,1,true) then stop = false else stop = true end
b2 = lens.dof_far
a2 = lens.dof_near
fp = lens.focus_distance
until b2 < a1 or stop
if not stop then lens.focus(-1,1,true) end -- move forward one step for focus bracket overlap
take_brackets()
until stop == true
end
end


BTW I have tried removing all the a1 a2 b1 b2 checks, ie just using the stop and it still doesn't run :(
Title: Re: Lua Request/Idea
Post by: BBA on June 19, 2016, 09:30:55 AM
@garry23
In the 2d case, the outer repeat/until loop depends on the initial value of the variable "stop". It should be initialized to false before running that "chunk".
Title: Re: Lua Request/Idea
Post by: garry23 on June 19, 2016, 09:34:48 AM
@BBA

It is.

I'll just keep playing with the script until I find my (sic) error.

Cheers

Garry
Title: Re: Lua Request/Idea
Post by: garry23 on June 19, 2016, 09:37:06 AM
@BBA

BTW your observation is not quite right, as repeat always runs through the loop once, ie it checks at the end, not the beginning  ;)
Title: Re: Lua Request/Idea
Post by: garry23 on June 19, 2016, 10:27:04 AM
@BBA (David/A1ex)

I've worked out what is going on in my script and it pivots around this code:

Code: [Select]
repeat
if lens.focus(1,1,true) then stop = false else stop = true end
until stop

lens.focus seems to return a false when it is first called. It then returns true.

As I'm looking for a false return, and 'only' associating that with a soft limit.

I tried this, ie not waiting for focus, but still have problems as lens.focus seems to return true and false even if it is functioning, ie it must reporting other 'errors'

Code: [Select]
[code]repeat
if lens.focus(1,1,false) then stop = false else stop = true end
until stop
[/code]

Title: Re: Lua Request/Idea
Post by: a1ex on June 19, 2016, 10:48:22 AM
Hypothesis: maybe when the lens is at one endpoint (either infinity or macro), Canon firmware may report error even if you try to move in the other direction.

Does it help if you use larger steps?

Also, does it help if you execute a few focus steps without checking them?
Title: Re: Lua Request/Idea
Post by: garry23 on June 19, 2016, 11:17:19 AM
A1ex

You are thinking how I've been thinking, ie ways to work around it using 'state logic'.

BTW the problem is not at the ends.

That is, if the focus is, say, in the middle, then lens.focus seems to return a false, then a true, even if (AF) wait is false.

I'll carry on testing, but I'm moving to another 'solution' now, which I know works, ie use lens.dof_near as my 'macro stop'.
Title: Re: Lua Request/Idea
Post by: BBA on June 19, 2016, 03:46:17 PM
@garry23
To share my experiments, this very simple script has worked for me :
Code: [Select]
function move_focus_to_macro()

    repeat
    until not lens.focus(1,1,true) -- 1=towards macro end, 1 step at a time, waiting for lens to complete
   
end

scrnshot_menu = menu.new
{
    name = "Test",
  select = function(this)
   task.create(move_focus_to_macro)
  end
}

(if necessary, I had a 5dm3 and an EF24mmf1.4L II USM)
It is rather fast, so I don't think fast timings are a problem as I speculated earlier.
With another one, not so simple (and slower), a similar code is used to move the lens to macro end and then to begin scanning the lens in the opposite direction till the infinity end.

Quote
BTW your observation is not quite right, as repeat always runs through the loop once, ie it checks at the end, not the beginning  ;)

You are perfectly right; I must have been tired to write such a terrible thing ???

Title: Re: Lua Request/Idea
Post by: garry23 on June 19, 2016, 04:48:28 PM
@BBA

My all in one bracketing script is now working in two focus modes: from the FP to infinity and from the FP to the macro end.

I got it running through 'hard linking' in the macro minimum FP.

BTW here is the full script: https://gist.github.com/pigeonhill/b67462aec370495fdef8de74f303c734

Cheers

Garry
Title: Re: Lua Request/Idea
Post by: BBA on June 19, 2016, 05:41:01 PM
@garry23

Quite impressed by the way your work... I thank you very much for sharing this.

I will need some time to study it and will report any feedback. From my part, I do prefer something that works and is correct (even if I have to be wrong) don't you?

I would like to know what you mean by "registering the lens".

BTW, is it possible to attach a spreadsheet file to a forum post ? Above the "post reply window" there are insert icons (insert vimeo video url, insert image, insert hyperlink, insert mail, insert FTP link, insert table, insert code, insert quote)...

Title: Re: Lua Request/Idea
Post by: garry23 on June 19, 2016, 06:00:58 PM
@BBA

Sorry, I don't know how to attach a spreadsheet to a post  :-[

I tend to write up my work and photography on my blog at http://photography.grayheron.net/ (http://photography.grayheron.net/)

The 'registering' idea was my simple way of getting round not being able to solve the soft limit error.

All you need to do, when you go into the focus bracketing submenu is to rotate the lens to the macro end and tell the script this is the macro stop, ie all you do is press SET. This macro stop remains good whilst the camera is on.

I still haven't worked out how to store my own variables, ie when the camera switches off: next job  ;)
Title: Re: Lua Request/Idea
Post by: dmilligan on June 27, 2016, 10:16:21 PM
Still have problems with lens.focus? Does the API test work correctly?
Code: [Select]
        printf("Focus distance: %s\n",  lens.focus_distance)

        -- note: focus direction is not consistent
        -- some lenses will focus to infinity, others to macro
        printf("Focusing backward...\n")
        while lens.focus(-1,3,true) do end
        printf("Focus distance: %s\n",  lens.focus_distance)

        msleep(500)
       
        for i,step in pairs{3,2,1} do
            for j,wait in pairs{true,false} do
                printf("Focusing forward with step size %d, wait=%s...\n", step, wait)
                local steps_front = 0
                while lens.focus(1,step,true) do
                    printf(".")
                    steps_front = steps_front + 1
                end
                printf("\n")
                printf("Focus distance: %s\n",  lens.focus_distance)
               
                msleep(500)
               
                printf("Focusing backward with step size %d, wait=%s...\n", step, wait)
                local steps_back = 0
                while lens.focus(-1,step,true) do
                    printf(".")
                    steps_back = steps_back + 1
                end
                printf("\n")
                printf("Focus distance: %s\n",  lens.focus_distance)

                msleep(500)

                printf("Focus range: %s steps forward, %s steps backward. \n",  steps_front, steps_back)
            end
        end
        printf("Focus test completed.\n")

If not, does it work correctly on some camera/lenses and not on others? Which ones?

(It works fine here on 60D)
Title: Re: Lua Request/Idea
Post by: garry23 on June 27, 2016, 11:27:49 PM
Just ran the API test several times and it failed each time on a 5D3 + 24-105 F4/L in manual  mode.

Code: [Select]
===============================================================================
ML/SCRIPTS/TEST.LUA - 2016-6-27 22:18:55
===============================================================================

Strict mode tests...
Strict mode tests passed.

Generic tests...
camera = table:
  shutter = table:
    raw = 115
    apex = 7.375
    ms = 6
    value = 0.006024
  aperture = table:
    raw = 67
    apex = 7.375
    value = 12.8
    min = table:
      raw = 40
      apex = 4
      value = 4
    max = table:
      raw = 80
      apex = 9
      value = 22.6
  iso = table:
    raw = 72
    apex = 5
    value = 100
  ec = table:
    raw = 0
    value = 0
  flash_ec = table:
    raw = -5
    value = -0.624999
  kelvin = 2500
  mode = 3
  metering_mode = 3
  drive_mode = 0
  model = "Canon EOS 5D Mark III"
  model_short = "5D3"
  firmware = "1.1.3"
  temperature = 151
  state = 0
  reboot = function: p
  shoot = function: p
  bulb = function: p
event = table:
  pre_shoot = nil
  post_shoot = nil
  shoot_task = nil
  seconds_clock = nil
  keypress = nil
  custom_picture_taking = nil
  intervalometer = nil
  config_save = nil
console = table:
  write = function: p
  show = function: p
  clear = function: p
  hide = function: p
lv = table:
  enabled = true
  paused = false
  running = true
  zoom = 1
  start = function: p
  resume = function: p
  info = function: p
  stop = function: p
  pause = function: p
  wait = function: p
lens = table:
  name = "EF24-105mm f/4L IS USM"
  focal_length = 24
  focus_distance = 1820
  hyperfocal = 5649
  dof_near = 1383
  dof_far = 2659
  af = true
  af_mode = 0
  focus = function: p
display = table:
  idle = true
  height = 480
  width = 720
  screenshot = function: p
  rect = function: p
  pixel = function: p
  on = function: p
  load = function: p
  line = function: p
  off = function: p
  notify_box = function: p
  print = function: p
  draw = function: p
  clear = function: p
  circle = function: p
key = table:
  last = 0
  press = function: p
  wait = function: p
menu = table:
  visible = false
  close = function: p
  get = function: p
  block = function: p
  set = function: p
  new = function: p
  open = function: p
testmenu = userdata:
  value = 0
  name = "Script API tests"
  help = "Various tests for the Lua scripting API."
  help2 = "When adding new Lua APIs, tests for them should go here."
  advanced = 0
  depends_on = 0
  edit_mode = 0
  hidden = false
  icon_type = 5
  jhidden = false
  max = 0
  min = 0
  selected = true
  shidden = false
  starred = false
  submenu_height = 0
  submenu_width = 0
  unit = 0
  works_best_in = 0
  run_in_separate_task = 0
  select = function: p
  update = nil
  info = nil
  rinfo = nil
  warning = nil
movie = table:
  recording = false
  start = function: p
  stop = function: p
dryos = table:
  clock = 29
  ms_clock = 29777
  prefix = "2P6A"
  dcim_dir = table:
    exists = true
    create = function: p
    children = function: p
    files = function: p
    parent = table:
      exists = true
      create = function: p
      children = function: p
      files = function: p
      parent = table:
        exists = true
        create = function: p
        children = function: p
        files = function: p
        parent = nil
        path = "B:/"
      path = "B:/DCIM/"
    path = "B:/DCIM/100EOS5D/"
  config_dir = table:
    exists = true
    create = function: p
    children = function: p
    files = function: p
    parent = table:
      exists = true
      create = function: p
      children = function: p
      files = function: p
      parent = table:
        exists = true
        create = function: p
        children = function: p
        files = function: p
        parent = nil
        path = "A:/"
      path = "ML/"
    path = "ML/SETTINGS/"
  ml_card = table:
    cluster_size = 32768
    drive_letter = "A"
    file_number = 2459
    folder_number = 100
    free_space = 27909408
    type = "CF"
    path = "A:/"
    _card_ptr = userdata
  shooting_card = table:
    cluster_size = 131072
    drive_letter = "B"
    file_number = 2459
    folder_number = 100
    free_space = 51559424
    type = "SD"
    path = "B:/"
    _card_ptr = userdata
  date = table:
    month = 6
    min = 18
    yday = 179
    isdst = false
    sec = 57
    year = 2016
    day = 27
    hour = 22
    wday = 2
  directory = function: p
  call = function: p
  remove = function: p
interval = table:
  time = 0
  count = 0
  running = 0
  stop = function: p
battery = table:
  level = 51
  id = 3
  performance = 3
  time = 3519
  drain_rate = 52
task = table:
  create = function: p
  yield = function: p
property = table:
Generic tests completed.

Module tests...
Copy test: autoexec.bin -> tmp.bin
Copy test OK
Append test: tmp.txt
Append test OK
Testing exposure settings, module 'camera'...
Camera    : Canon EOS 5D Mark III (5D3) 1.1.3
Lens      : EF24-105mm f/4L IS USM
Shoot mode: 3
Shutter   : ‚160 (raw 115, 0.006024s, 6ms, apex 7.375)
Aperture  : 12 (raw 67, f/12.8, apex 7.375)
Av range  : 4.0..22 (raw 40..80, f/4..f/22.6, apex 4..9)
ISO       : 100 (raw 72, 100, apex 5)
EC        : 0.0 (raw 0, 0 EV)
Flash EC  : -0.6 (raw -5, -0.624999 EV)
Setting shutter to random values...

===============================================================================
ML/SCRIPTS/TEST.LUA - 2016-6-27 22:22:03
===============================================================================

Strict mode tests...
Strict mode tests passed.

Generic tests...
camera = table:
  shutter = table:
    raw = 125
    apex = 8.624999
    ms = 3
    value = 0.002532
  aperture = table:
    raw = 67
    apex = 7.375
    value = 12.8
    min = table:
      raw = 40
      apex = 4
      value = 4
    max = table:
      raw = 80
      apex = 9
      value = 22.6
  iso = table:
    raw = 72
    apex = 5
    value = 100
  ec = table:
    raw = 0
    value = 0
  flash_ec = table:
    raw = -5
    value = -0.624999
  kelvin = 2500
  mode = 3
  metering_mode = 3
  drive_mode = 0
  model = "Canon EOS 5D Mark III"
  model_short = "5D3"
  firmware = "1.1.3"
  temperature = 152
  state = 0
  shoot = function: p
  bulb = function: p
  reboot = function: p
event = table:
  pre_shoot = nil
  post_shoot = nil
  shoot_task = nil
  seconds_clock = nil
  keypress = nil
  custom_picture_taking = nil
  intervalometer = nil
  config_save = nil
console = table:
  write = function: p
  clear = function: p
  hide = function: p
  show = function: p
lv = table:
  enabled = true
  paused = false
  running = true
  zoom = 1
  stop = function: p
  resume = function: p
  pause = function: p
  start = function: p
  info = function: p
  wait = function: p
lens = table:
  name = "EF24-105mm f/4L IS USM"
  focal_length = 24
  focus_distance = 1060
  hyperfocal = 5649
  dof_near = 895
  dof_far = 1298
  af = true
  af_mode = 0
  focus = function: p
display = table:
  idle = true
  height = 480
  width = 720
  rect = function: p
  notify_box = function: p
  on = function: p
  draw = function: p
  off = function: p
  pixel = function: p
  load = function: p
  print = function: p
  circle = function: p
  screenshot = function: p
  line = function: p
  clear = function: p
key = table:
  last = 0
  press = function: p
  wait = function: p
menu = table:
  visible = false
  new = function: p
  get = function: p
  open = function: p
  set = function: p
  block = function: p
  close = function: p
testmenu = userdata:
  value = 0
  name = "Script API tests"
  help = "Various tests for the Lua scripting API."
  help2 = "When adding new Lua APIs, tests for them should go here."
  advanced = 0
  depends_on = 0
  edit_mode = 0
  hidden = false
  icon_type = 5
  jhidden = false
  max = 0
  min = 0
  selected = true
  shidden = false
  starred = false
  submenu_height = 0
  submenu_width = 0
  unit = 0
  works_best_in = 0
  run_in_separate_task = 0
  select = function: p
  update = nil
  info = nil
  rinfo = nil
  warning = nil
movie = table:
  recording = false
  start = function: p
  stop = function: p
dryos = table:
  clock = 23
  ms_clock = 23938
  prefix = "2P6A"
  dcim_dir = table:
    exists = true
    create = function: p
    children = function: p
    files = function: p
    parent = table:
      exists = true
      create = function: p
      children = function: p
      files = function: p
      parent = table:
        exists = true
        create = function: p
        children = function: p
        files = function: p
        parent = nil
        path = "B:/"
      path = "B:/DCIM/"
    path = "B:/DCIM/100EOS5D/"
  config_dir = table:
    exists = true
    create = function: p
    children = function: p
    files = function: p
    parent = table:
      exists = true
      create = function: p
      children = function: p
      files = function: p
      parent = table:
        exists = true
        create = function: p
        children = function: p
        files = function: p
        parent = nil
        path = "A:/"
      path = "ML/"
    path = "ML/SETTINGS/"
  ml_card = table:
    cluster_size = 32768
    drive_letter = "A"
    file_number = 2459
    folder_number = 100
    free_space = 27909408
    type = "CF"
    _card_ptr = userdata
    path = "A:/"
  shooting_card = table:
    cluster_size = 131072
    drive_letter = "B"
    file_number = 2459
    folder_number = 100
    free_space = 51559424
    type = "SD"
    _card_ptr = userdata
    path = "B:/"
  date = table:
    wday = 2
    yday = 179
    isdst = false
    min = 22
    sec = 4
    month = 6
    hour = 22
    day = 27
    year = 2016
  remove = function: p
  call = function: p
  directory = function: p
interval = table:
  time = 0
  count = 0
  running = 0
  stop = function: p
battery = table:
  level = 50
  id = 3
  performance = 3
  time = 3450
  drain_rate = 52
task = table:
  create = function: p
  yield = function: p
property = table:
Generic tests completed.

Module tests...
Copy test: autoexec.bin -> tmp.bin
Copy test OK
Append test: tmp.txt
Append test OK
Testing exposure settings, module 'camera'...
Camera    : Canon EOS 5D Mark III (5D3) 1.1.3
Lens      : EF24-105mm f/4L IS USM
Shoot mode: 3
Shutter   : ‚400 (raw 125, 0.002532s, 3ms, apex 8.624999)
Aperture  : 12 (raw 67, f/12.8, apex 7.375)
Av range  : 4.0..22 (raw 40..80, f/4..f/22.6, apex 4..9)
ISO       : 100 (raw 72, 100, apex 5)
EC        : 0.0 (raw 0, 0 EV)
Flash EC  : -0.6 (raw -5, -0.624999 EV)
Setting shutter to random values...
Title: Re: Lua Request/Idea
Post by: a1ex on June 28, 2016, 08:23:17 AM
The test log is incomplete => auto power off was enabled?
Title: Re: Lua Request/Idea
Post by: garry23 on June 28, 2016, 09:03:21 AM
Script fails at Lua 213 "shutter"

BTW Auto Power is OFF
Title: Re: Lua Request/Idea
Post by: garry23 on June 28, 2016, 09:21:16 AM
OK worked it out: Expo Override was ON.

All tests worked.

BTW Your lens.focus works, ie doesn't generate a soft focus error: but mine does  >:(

I use lens.focus(1,1,false) as I thought setting false meant the lens wouldn't wait for focus: is that correct?
Title: Re: Lua Request/Idea
Post by: a1ex on June 28, 2016, 09:33:00 AM
Script fails at Lua 213 "shutter"

That means, you found a bug in the API test script: it doesn't log errors.

I use lens.focus(1,1,false) as I thought setting false meant the lens wouldn't wait for focus: is that correct?

Disabling the wait flag should give smoother motion (as the focus commands are queued), but I'm not sure how well error handling works in this case. If in doubt, enable this flag (so it focuses one step at a time and waits for confirmation).
Title: Re: Lua Request/Idea
Post by: garry23 on June 28, 2016, 09:43:30 AM
A1ex

Post crossed. API script runs ok if Expo Override OFF.

Here is the relevant piece of my script that is not 'working'.

Code: [Select]
soft_err = true
repeat
soft_err = lens.focus(1,1,true)
until soft_err == false

It stops straight away, implying lens.focus is returning false.

I can't work it out :(
Title: Re: Lua Request/Idea
Post by: a1ex on June 28, 2016, 09:46:47 AM
From api_test.lua:

Code: [Select]
    while lens.focus(-1,3,true) do end

Does this one work?
Title: Re: Lua Request/Idea
Post by: garry23 on June 28, 2016, 10:21:04 AM
I'll do some checking tonight and report back.

Cheers
Title: Re: Lua Request/Idea
Post by: BBA on June 28, 2016, 05:47:27 PM
focus test posted by dmilligan works fine for me (with 5DmIII and 35mm f2 IS USM) (except, as already noted, the lens move direction which is, in this case, the opposite one)
Title: Re: Lua Request/Idea
Post by: garry23 on June 30, 2016, 08:44:16 AM
@BBA (A1ex/David)

I have convinced myself my original script is corrupting things, but I don't know why.

The following test script works as expected, ie detects the soft limit reached:

Code: [Select]
soft_err = true
b2 = lens.dof_far
a2 = lens.dof_near
fp = lens.focus_distance


function move(direction)
local a1 = 0
local b1 = 0
if direction == -1 then -- focus stack ti infinity soft stop
repeat
a1 = a2
b1 = b2
repeat
soft_err = lens.focus(-1,1,false)
b2 = lens.dof_far
a2 = lens.dof_near
fp = lens.focus_distance
until a2> b1 or soft_err == false
msleep(1000)
until soft_err == false
else  -- focus stack to macro soft stop
repeat
a1 = a2
b1 = b2
repeat
soft_err = lens.focus(1,1,false)
b2 = lens.dof_far
a2 = lens.dof_near
fp = lens.focus_distance
until b2 < a1 or soft_err == false
msleep(1000)
until soft_err == false
end
end

function start() -- test out focus stacking works through the soft stop error return
move(-1)
move(1)
move(-1)
end

scrnshot_menu = menu.new
{
    name = "Test",
select = function(this)
task.create(start)
end
}


The only 'problem' I see is that if lens.focus generates another error, my script will detect that but assume the soft limit has been reached. That is I can't differentiate lens.focus error code returns.

For this reason I had to use false in lens.focus, as it could generate a focus error if I use true.

I think I will redo my focus & exposure bracketing script, starting from the above test script.

Cheers

Garry
Title: Re: Lua Request/Idea
Post by: BBA on June 30, 2016, 12:36:24 PM
@garry23

I am glad you found some working solution. As A1ex said, try to simplify as much as possible.

I don't know why you have to use lens.focus with "no wait" (false) option. I wondered the other day, if you didn't use special Canon focus settings in your 5dmIII as you are a specialist (birds photographs?). In my case, I only use default settings as the focus settings may be quite complicated for me: I haven't had time to study them : I didn't find out as lens.focus is a low level command and the very sophisticated Canon settings seem to work at a higher level.

I don't know if lens.focus can return false in other circumstances then when the software limits are reached. It is a good question! I am not used enough to best lua programming practices to know if it would be a good practice (Imho, I would differentiate the returns...). I would love to know how to best deal with errors in lua.

From my experiments, the focal point returned by lens.focus is a step function https://en.wikipedia.org/wiki/Step_function (https://en.wikipedia.org/wiki/Step_function) (which I can understand) and not a continuous one https://en.wikipedia.org/wiki/Continuous_function (https://en.wikipedia.org/wiki/Continuous_function). We have to know that because it changes the behavior of your algorithm.

Your algorithm works perfectly with a continuous function. With a step function, it detects the discontinuities (steps) which is very good and effective overall  (there are enough steps), but can lead, in theory, to focus overlapping problems (dof, diffraction,...) (to be more studied).
Don't worry : if needed, I think this can be solved by interpolating between steps and forcing more pictures when approaching infinity (I can help if needed).
Title: Re: Lua Request/Idea
Post by: garry23 on June 30, 2016, 05:36:21 PM
@BBA

BTW in the test code I left out handling focus overlaps, eg in the 'real' code I do something like this:

Code: [Select]
if direction == -1 then -- focus stack ti infinity soft stop
repeat
a1 = a2
b1 = b2
repeat
soft_err = lens.focus(-1,1,false)
b2 = lens.dof_far
a2 = lens.dof_near
fp = lens.focus_distance
until a2> b1 or soft_err == false
                                lens.focus(1,1,false) -- move back to ensure focus overlap
msleep(1000)
until soft_err == false
Title: Re: Lua Request/Idea
Post by: BBA on June 30, 2016, 08:42:41 PM
You are right and this is very logical (with a continuous function). In our case, this is done at each step boundary which translates all the pictures by one step to macro end.

Also, logically, if you decrease the coc, the number of pictures to be taken should increase (automatically). Inversely if you dramatically increase the coc, at the limit, only one picture could be sufficient, couldn't it ? Here, imho, the number of pictures taken should not change as much.
But, there isn't to worry very much as there are many steps (range of 22 steps for the EF 24mm f/1.4 II USM  + 1 at both ends if we use the software limit).
Title: Re: Lua Request/Idea
Post by: garry23 on June 30, 2016, 10:33:21 PM
I hope David or A1ex read this as I've worked out what is causing my script to fail. Here is the test script:

Code: [Select]
soft_err = true
b2 = lens.dof_far
a2 = lens.dof_near
fp = lens.focus_distance


function move(direction)
local a1 = 0
local b1 = 0
if direction == -1 then -- focus stack ti infinity soft stop
repeat
a1 = a2
b1 = b2
repeat
soft_err = lens.focus(-1,1,false)
b2 = lens.dof_far
a2 = lens.dof_near
fp = lens.focus_distance
until a2> b1 or soft_err == false
msleep(1000)
until soft_err == false
else  -- focus stack to macro soft stop
repeat
a1 = a2
b1 = b2
repeat
soft_err = lens.focus(1,1,false)
b2 = lens.dof_far
a2 = lens.dof_near
fp = lens.focus_distance
until b2 < a1 or soft_err == false
camera.shoot(64, false)
until soft_err == false
end
end

function start() -- test out focus stacking works through the soft stop error return
move(-1)
move(1)
move(-1)
end

scrnshot_menu = menu.new
{
    name = "Test",
select = function(this)
task.create(start)
end
}

If I don't use camera.shoot(64, false), ie dummy it out with a msleep(1000), say, as in the block of code above the camera.shoot(64, false) call, all is well.

As soon as camera.shoot(64, false) is called in the above, the script stops, ie camera.shoot(64, false) seems to cause lens.focus to return a false.

Does anyone have any insight as to the logic here?
Title: Re: Lua Request/Idea
Post by: BBA on July 01, 2016, 11:39:05 AM
@garry23

Lest's suppose you replace 64 (as wait time) in shoot with 1000 as in msleep.
I wonder: when you call lens.focus with false, the focus commands are queued, let's say 30 times lens.focus per step. Then the camera.shoot is called with a wait time of 64 (ms?).
Maybe if you give a little more time to camera.shoot so the focus commands can be unqueued ?
Title: Re: Lua Request/Idea
Post by: a1ex on July 01, 2016, 11:50:51 AM
When calling lens.focus, are you in LiveView?
Title: Re: Lua Request/Idea
Post by: garry23 on July 01, 2016, 02:52:40 PM
A1ex

Yes. The script runs in LV.

Cheers

Garry
Title: Re: Lua Request/Idea
Post by: garry23 on July 01, 2016, 05:15:17 PM
@BBA

I think I understand what you are saying, however, the need is to find a way forward without using AF.

In my focus stacking script I do not want the lens AF to do any work: for two reasons.

First, I'm focusing at the 'correct' FP.

Second, in a low contrast scene the focus may not be found.

Bottom line: I need to find a way for lens.focus to work with camera.shoot when both have AF as false.
Title: Re: Lua Request/Idea
Post by: a1ex on July 01, 2016, 05:54:06 PM
garry23: to make sure you are doing each lens.focus call in LiveView, try this:

Code: [Select]
assert(lv)
lens.focus(...)
Title: Re: Lua Request/Idea
Post by: garry23 on July 01, 2016, 06:09:57 PM
@A1ex

Tried the assert but same result.

If camera.shoot is called, it then appears to trigger lens.focus to return a false.

BTW here is the test script with the assert added in:

Code: [Select]
soft_err = true
b2 = lens.dof_far
a2 = lens.dof_near
fp = lens.focus_distance


function move(direction)
local a1 = 0
local b1 = 0
if direction == -1 then -- focus stack ti infinity soft stop
repeat
a1 = a2
b1 = b2
repeat
assert(lv)
soft_err = lens.focus(-1,1,false)
b2 = lens.dof_far
a2 = lens.dof_near
fp = lens.focus_distance
until a2> b1 or soft_err == false
msleep(1000)
until soft_err == false
else  -- focus stack to macro soft stop
repeat
a1 = a2
b1 = b2
repeat
assert(lv)
soft_err = lens.focus(1,1,false)
b2 = lens.dof_far
a2 = lens.dof_near
fp = lens.focus_distance
until b2 < a1 or soft_err == false
camera.shoot(64, false)
until soft_err == false
end
end

function start() -- test out focus stacking works through the soft stop error return
move(-1)
move(1)
move(-1)
end

scrnshot_menu = menu.new
{
    name = "Test",
select = function(this)
task.create(start)
end
}
Title: Re: Lua Request/Idea
Post by: a1ex on July 01, 2016, 07:17:29 PM
That means, the assert doesn't get triggered, correct?

After taking a picture, you should wait for it to finish and return to LiveView before sending more focus commands. The assert above checks just for that, but since it didn't trigger, it looks like the camera already returned to LiveView.

You could add a large delay after taking the picture, maybe it helps. I'm not able to try it right now, but I'll add an API test for this scenario as well.
Title: Re: Lua Request/Idea
Post by: garry23 on July 01, 2016, 07:24:02 PM
@A1ex

Thanks for the pointers. I'll play around with things this weekend and see if I can divine a solution  ;)
Title: Re: Lua Request/Idea
Post by: BBA on July 01, 2016, 10:07:08 PM
@garry23

I didn't mean to shoot with AF, which would "blow the focus stack away".

I only meant that lens.focus is called with "false" = without waiting for it (this command) to finish before continuing =>  many commands could be queued because of the repeat loop.

But.. lens.focus returns a value to the soft_err variable whose value must be tested for the repeat loop (except when b2<a1) :  doesn't it imply that it is necessary to wait for the lens.focus command to finish at each loop ?
Title: Re: Lua Request/Idea
Post by: garry23 on July 02, 2016, 08:10:36 AM
@BBA/A1ex/David

Final confirmation: I've tried various delays and focus steps, but calling camera.shoot seems to generate a false return from lens.focus.

I've used this short test script to 'prove' the above:

Code: [Select]
soft_err = true
b2 = lens.dof_far
a2 = lens.dof_near


function move(direction)
lv.start()
local a1 = 0
local b1 = 0
local fp = lens.focus_distance
local old_fp = fp
if direction == -1 then -- test focus stack to infinity soft stop
a1 = a2
b1 = b2
fp = lens.focus_distance
repeat
lv.resume() -- just to be sure
old_fp = fp
soft_err = lens.focus(-1,3,false)
b2 = lens.dof_far
a2 = lens.dof_near
fp = lens.focus_distance
until a2> b1 or soft_err == false
msleep(1000)  -- this works
-- camera.shoot(64, false)  -- this doesn't
else  -- test focus stack to macro soft stop
a1 = a2
b1 = b2
fp = lens.focus_distance
repeat
lv.resume() -- just to be sure
old_fp = fp
soft_err = lens.focus(1,3,false)
b2 = lens.dof_far
a2 = lens.dof_near
fp = lens.focus_distance
until b2 < a1 or soft_err == false
-- msleep(1000)  -- this works
camera.shoot(64, false)  -- this doesn't
end
end

function start() -- test out focus stacking works through the soft stop error return
move(-1)
move(1)
move(-1)
end

scrnshot_menu = menu.new
{
    name = "Test",
select = function(this)
task.create(start)
end
}

The script stops after the first camera.shoot generates a lens.focus false return.
Title: Re: Lua Request/Idea
Post by: BBA on July 02, 2016, 12:05:10 PM
? Don't you think it would be easier with a simplified algorithm ?
Unless you really want to know what goes wrong, but maybe it will go wrong when simplified too.

cf. above, fp is a step function : we only need to test when it's value changes (no need to work with intervals a1b1 and a2b2 anymore) , something like
Code: [Select]
fp1=lens.focus_distance
shoot()
while true do -- loop to scan when to shoot
   soft = lens.focus(dir,1,false) -- go in given direction
   fp2=lens.focus_distance -- check new focal point

   if fp2<>fp1 then shoot() end -- new step of step function -> shoot
   if soft then shoot() break end -- software limit reached --> shoot & leave

   fp2=fp1
end

function shoot()
   msleep
   camera.shoot
   msleep
end
Maybe there are errors but we have less things to check...
Title: Re: Lua Request/Idea
Post by: garry23 on July 02, 2016, 12:15:34 PM
@BBA

Just for you  :)

This still fails after camera.shoot

Code: [Select]
soft_err = true


function move(direction)
lv.start()
if direction == -1 then -- test focus stack to infinity soft stop
repeat
lv.resume() -- just to be sure
soft_err = lens.focus(-1,3,false)
until soft_err == false
msleep(1000)  -- this works
-- camera.shoot(64, false)  -- this doesn't
else  -- test focus stack to macro soft stop
repeat
lv.resume() -- just to be sure
soft_err = lens.focus(1,3,false)
until soft_err == false
-- msleep(1000)  -- this works
camera.shoot(64, false)  -- this doesn't
end
end

function start() -- test out focus stacking works through the soft stop error return
move(-1)
move(1)
move(-1)
end

scrnshot_menu = menu.new
{
    name = "Test",
select = function(this)
task.create(start)
end
}
Title: Re: Lua Request/Idea
Post by: BBA on July 02, 2016, 12:47:30 PM
@garry23

I will try with "true" in "lens.focus" ( lens.focus(_,_,true) ) because mine doesn't work either with "false" : it doesn't "see" the step changes.
What if you use both "sleep" and "camera.shoot" like "sleep(1000) camera.shoot(64,false) sleep(2000)".
And if you use "true" in "lens.focus" like me ?
Title: Re: Lua Request/Idea
Post by: garry23 on July 02, 2016, 12:59:31 PM
@BBA

I tried various delays, and none worked, but I would welcome you trying.

Cheers

Garry
Title: Re: Lua Request/Idea
Post by: BBA on July 02, 2016, 01:34:33 PM
To share

I got 2 errors in the console: the same error "twice in a row":

Lua semaphore timeout: menu.updt (100ms)
Lua semaphore timeout: menu.updt (100ms)

my script with logging:

Code: [Select]
require('logger')
focus_log = nil

fp1 = 0
fp2 = 0
soft_err= false

function move( dir)
 
  printf(" start move : fp1,fp2 =  %s , %s  direction  = %s \n",fp1,fp2,dir)
  fp1 = lens.focus_distance
  shoot()
 
  while true do
   
    soft_err=false
    msleep(200)
    soft_err = lens.focus(dir,1)
    msleep(200)
    fp2 = lens.focus_distance
    msleep(200)
    printf(" loop : fp1,fp2 =  %s , %s    soft_err focus = %s \n",fp1,fp2,soft_err)
   
    if not fp2==fp1 then  -- if new step (step function)
      printf(" - fp2<>fp1 : fp1,fp2 =  %s , %s    soft_err focus = %s \n",fp1,fp2,soft_err)
      shoot()
    end
 
    if soft_err then -- if focus limit reached
      printf(" - soft_err focus reached : fp1,fp2 =  %s , %s    soft_err focus = %s \n",fp1,fp2,soft_err)
      shoot()
      break
    end
   
    fp1 = fp2
   
  end
end


function printf( format_string, ...)
    focus_log:writef( format_string, ...)
end

function shoot()
      msleep(1000) -- wait for other tasks to finish
      printf("   shoot : fp1,fp2 =  %s , %s    soft_err focus = %s \n",fp1,fp2,soft_err)
      camera.shoot(64, false)
      msleep(3000) -- wait for camera.shoot to finish
end

function start()
  lv.start()
  focus_log = logger("test_wt.log")
  move(-1)
  move(1)
  move(-1)
  focus_log:close()
 end
 
scrnshot_menu = menu.new
{
    name = "Test",
    select = function(this)
       task.create(start)
   end
}
 
Title: Re: Lua Request/Idea
Post by: garry23 on July 02, 2016, 02:15:06 PM
@BBA

My gut feeling is that there is something happening 'behind' the scenes and that you and I mucking about in Lua scripting will not find.

Let's hope the gurus can work it out  ;)

Cheers

Garry
Title: Re: Lua Request/Idea
Post by: BBA on July 02, 2016, 02:17:45 PM
@garry23

When I try your script:
- one picture is taken
- immediately after, the live view mode is left (is it ?) (mirror sound)
and the script seems to have stopped.

Is it the same as you ?

I need to go for some food.
Title: Re: Lua Request/Idea
Post by: garry23 on July 02, 2016, 02:32:37 PM
Yes that's the problem.

Replace camera.shoot with, say, msleep and the s rapt completes fine.
Title: Re: Lua Request/Idea
Post by: BBA on July 02, 2016, 09:06:52 PM
This one works.
I don't exactly know why but I have added another test just before the lens move (fp2 too late in case fp2=lens.focus_distance is refreshed later); it appears that it is this test that triggers the shots !
It is to be simplified (debug, strong typing, slow timings)
In the infinity range, a photo is taken at each step of the focus motor (manage infinity shots : to be modified)
Here is the script (to share if needed)
Code: [Select]

-- strict type : number/string not interchangeable
-- timings : 2nd chance for fp2

require('logger')
focus_log = nil

soft_limit = false

infinity = 100000
epsilon = 0.00001

dir=0

function move()
 
  local fp1,fp2 = 0,0
  local st_fp1,st_fp2 = "void","void"
  local st_dir = "void"
  local istep = 0

  st_fp2 = tostring(fp2)
  st_dir = tostring(dir)
 
  fp2 = tonumber(lens.focus_distance)
  st_fp2 = tostring( fp2)
  printf(" --- start move : fp1,fp2 =  %s , %s  direction  = %s \n",st_fp1,st_fp2,st_dir)
 
  istep = 0
 
  while true do
   
    msleep(100) -- to let things stabilize if needed
   
    fp2 = tonumber(lens.focus_distance)
    st_fp2 = tostring( fp2)
    printf("- reenter loop : step = %s - fp1,fp2 =  %s , %s \n",istep, st_fp1, st_fp2)
   
    if ( tonumber(fp1) < tonumber(fp2) ) then -- last time test if fp2 was refreshed too late
      printf("     - fp2<>fp1 (fp2 too late) fp1,fp2 =  %s , %s \n",st_fp1,st_fp2)
      shoot()
    elseif (tonumber(fp2) > infinity) and soft_limit then -- near infinity
      printf("     - near infinity (fp2 too late) fp1,fp2 =  %s , %s \n",st_fp1,st_fp2)
      manage_infinity_shots()
      break
    elseif not soft_limit then
      printf("     - near infinity (fp2 too late) error : did not manage infinity shots")
      break
    end
   
    fp1 = tonumber(fp2) -- transfer values just before the move
    st_fp1 = tostring( fp1)
   
    -- move
    soft_limit = lens.focus( dir, 1, true) -- HERE it is !!!!!!!!!!!!!!!!!!!!!!
   
    istep = istep+1
    msleep(100) -- with hope to get fp2 refreshed
   
    fp2 = tonumber(lens.focus_distance)
    st_fp2=tostring( fp2)
   
    printf("- loop after lens move: step = %s - fp1,fp2 =  %s , %s \n",istep, st_fp1,st_fp2)
   
   
    if ( tonumber(fp1) < tonumber(fp2) )  then  -- if new big step (step function)
      printf("     - fp2<>fp1 : fp1,fp2 =  %s , %s \n",st_fp1,st_fp2)
      shoot()
      fp1 = tonumber(fp2)
      st_fp1 = tostring( fp1)
    elseif (tonumber(fp2) > infinity) and soft_limit then -- near infinity
      printf("     - near infinity : fp1,fp2 =  %s , %s \n",st_fp1,st_fp2)
      manage_infinity_shots()
      break
    elseif not soft_limit then
      printf("     - near infinity : error : did not manage infinity shots")
      break
    end
   
  end
  printf(" end of move : fp1,fp2 =  %s , %s \n",st_fp1,st_fp2)
 
end

-- new algorithm to be implemented for infinity range
function manage_infinity_shots()
  while lens.focus( dir, 1, true) do
    shoot()
  end
end

function printf( format_string, ...)
    focus_log:writef( format_string, ...)
end

function shoot()
      msleep(1000) -- wait for other tasks to finish
      printf("   shoot \n")
      camera.shoot(64, false)
      msleep(3000) -- wait for camera.shoot to finish
end
 
function start()
  lv.start()
  focus_log = logger("test_wt.log")
  dir = -1
  move()
  dir = 1
  --move()
  dir = -1
  --move()
  focus_log:close()
 end
 
 scrnshot_menu = menu.new
{
  name = "myTest",
  select = function(this)
   task.create(start)
  end
}

If needed, the log to show that the "fp2 too late" is used !

Code: [Select]

===============================================================================
ML/SCRIPTS/TSTSTACK.LUA - 2016-7-2 20:25:01
===============================================================================

 --- start move : fp1,fp2 =  void , 380  direction  = -1
- reenter loop : step = 0 - fp1,fp2 =  void , 380
     - fp2<>fp1 (fp2 too late) fp1,fp2 =  void , 380
   shoot
- loop after lens move: step = 1 - fp1,fp2 =  380 , 380
- reenter loop : step = 1 - fp1,fp2 =  380 , 380
- loop after lens move: step = 2 - fp1,fp2 =  380 , 380
- reenter loop : step = 2 - fp1,fp2 =  380 , 400
     - fp2<>fp1 (fp2 too late) fp1,fp2 =  380 , 400
   shoot
- loop after lens move: step = 3 - fp1,fp2 =  400 , 400
- reenter loop : step = 3 - fp1,fp2 =  400 , 400
- loop after lens move: step = 4 - fp1,fp2 =  400 , 400
- reenter loop : step = 4 - fp1,fp2 =  400 , 400
- loop after lens move: step = 5 - fp1,fp2 =  400 , 400
- reenter loop : step = 5 - fp1,fp2 =  400 , 400
- loop after lens move: step = 6 - fp1,fp2 =  400 , 400
- reenter loop : step = 6 - fp1,fp2 =  400 , 400
- loop after lens move: step = 7 - fp1,fp2 =  400 , 400
- reenter loop : step = 7 - fp1,fp2 =  400 , 400
- loop after lens move: step = 8 - fp1,fp2 =  400 , 400
- reenter loop : step = 8 - fp1,fp2 =  400 , 400
- loop after lens move: step = 9 - fp1,fp2 =  400 , 400
- reenter loop : step = 9 - fp1,fp2 =  400 , 400
- loop after lens move: step = 10 - fp1,fp2 =  400 , 400
- reenter loop : step = 10 - fp1,fp2 =  400 , 400
- loop after lens move: step = 11 - fp1,fp2 =  400 , 400
- reenter loop : step = 11 - fp1,fp2 =  400 , 400
- loop after lens move: step = 12 - fp1,fp2 =  400 , 400
- reenter loop : step = 12 - fp1,fp2 =  400 , 400
- loop after lens move: step = 13 - fp1,fp2 =  400 , 400
- reenter loop : step = 13 - fp1,fp2 =  400 , 400
- loop after lens move: step = 14 - fp1,fp2 =  400 , 400
- reenter loop : step = 14 - fp1,fp2 =  400 , 400
- loop after lens move: step = 15 - fp1,fp2 =  400 , 400
- reenter loop : step = 15 - fp1,fp2 =  400 , 400
- loop after lens move: step = 16 - fp1,fp2 =  400 , 400
- reenter loop : step = 16 - fp1,fp2 =  400 , 400
- loop after lens move: step = 17 - fp1,fp2 =  400 , 400
- reenter loop : step = 17 - fp1,fp2 =  400 , 400
- loop after lens move: step = 18 - fp1,fp2 =  400 , 400
- reenter loop : step = 18 - fp1,fp2 =  400 , 400
- loop after lens move: step = 19 - fp1,fp2 =  400 , 400
- reenter loop : step = 19 - fp1,fp2 =  400 , 400
- loop after lens move: step = 20 - fp1,fp2 =  400 , 400
- reenter loop : step = 20 - fp1,fp2 =  400 , 400
- loop after lens move: step = 21 - fp1,fp2 =  400 , 400
- reenter loop : step = 21 - fp1,fp2 =  400 , 400
- loop after lens move: step = 22 - fp1,fp2 =  400 , 400
- reenter loop : step = 22 - fp1,fp2 =  400 , 400
- loop after lens move: step = 23 - fp1,fp2 =  400 , 400
- reenter loop : step = 23 - fp1,fp2 =  400 , 400
- loop after lens move: step = 24 - fp1,fp2 =  400 , 400
- reenter loop : step = 24 - fp1,fp2 =  400 , 400
- loop after lens move: step = 25 - fp1,fp2 =  400 , 400
- reenter loop : step = 25 - fp1,fp2 =  400 , 400
- loop after lens move: step = 26 - fp1,fp2 =  400 , 400
- reenter loop : step = 26 - fp1,fp2 =  400 , 400
- loop after lens move: step = 27 - fp1,fp2 =  400 , 400
- reenter loop : step = 27 - fp1,fp2 =  400 , 400
- loop after lens move: step = 28 - fp1,fp2 =  400 , 400
- reenter loop : step = 28 - fp1,fp2 =  400 , 400
- loop after lens move: step = 29 - fp1,fp2 =  400 , 400
- reenter loop : step = 29 - fp1,fp2 =  400 , 400
- loop after lens move: step = 30 - fp1,fp2 =  400 , 400
- reenter loop : step = 30 - fp1,fp2 =  400 , 400
- loop after lens move: step = 31 - fp1,fp2 =  400 , 400
- reenter loop : step = 31 - fp1,fp2 =  400 , 400
- loop after lens move: step = 32 - fp1,fp2 =  400 , 400
- reenter loop : step = 32 - fp1,fp2 =  400 , 400
- loop after lens move: step = 33 - fp1,fp2 =  400 , 400
- reenter loop : step = 33 - fp1,fp2 =  400 , 400
- loop after lens move: step = 34 - fp1,fp2 =  400 , 400
- reenter loop : step = 34 - fp1,fp2 =  400 , 400
- loop after lens move: step = 35 - fp1,fp2 =  400 , 400
- reenter loop : step = 35 - fp1,fp2 =  400 , 400
- loop after lens move: step = 36 - fp1,fp2 =  400 , 430
     - fp2<>fp1 : fp1,fp2 =  400 , 430
   shoot
- reenter loop : step = 36 - fp1,fp2 =  430 , 430
- loop after lens move: step = 37 - fp1,fp2 =  430 , 430
- reenter loop : step = 37 - fp1,fp2 =  430 , 430
- loop after lens move: step = 38 - fp1,fp2 =  430 , 430
- reenter loop : step = 38 - fp1,fp2 =  430 , 430
- loop after lens move: step = 39 - fp1,fp2 =  430 , 430
- reenter loop : step = 39 - fp1,fp2 =  430 , 430
- loop after lens move: step = 40 - fp1,fp2 =  430 , 430
- reenter loop : step = 40 - fp1,fp2 =  430 , 430
- loop after lens move: step = 41 - fp1,fp2 =  430 , 430
- reenter loop : step = 41 - fp1,fp2 =  430 , 430
- loop after lens move: step = 42 - fp1,fp2 =  430 , 430
- reenter loop : step = 42 - fp1,fp2 =  430 , 430
- loop after lens move: step = 43 - fp1,fp2 =  430 , 430
- reenter loop : step = 43 - fp1,fp2 =  430 , 430
- loop after lens move: step = 44 - fp1,fp2 =  430 , 430
- reenter loop : step = 44 - fp1,fp2 =  430 , 430
- loop after lens move: step = 45 - fp1,fp2 =  430 , 430
- reenter loop : step = 45 - fp1,fp2 =  430 , 430
- loop after lens move: step = 46 - fp1,fp2 =  430 , 430
- reenter loop : step = 46 - fp1,fp2 =  430 , 430
- loop after lens move: step = 47 - fp1,fp2 =  430 , 430
- reenter loop : step = 47 - fp1,fp2 =  430 , 430
- loop after lens move: step = 48 - fp1,fp2 =  430 , 430
- reenter loop : step = 48 - fp1,fp2 =  430 , 430
- loop after lens move: step = 49 - fp1,fp2 =  430 , 430
- reenter loop : step = 49 - fp1,fp2 =  430 , 430
- loop after lens move: step = 50 - fp1,fp2 =  430 , 430
- reenter loop : step = 50 - fp1,fp2 =  430 , 430
- loop after lens move: step = 51 - fp1,fp2 =  430 , 430
- reenter loop : step = 51 - fp1,fp2 =  430 , 430
- loop after lens move: step = 52 - fp1,fp2 =  430 , 430
- reenter loop : step = 52 - fp1,fp2 =  430 , 430
- loop after lens move: step = 53 - fp1,fp2 =  430 , 430
- reenter loop : step = 53 - fp1,fp2 =  430 , 430
- loop after lens move: step = 54 - fp1,fp2 =  430 , 430
- reenter loop : step = 54 - fp1,fp2 =  430 , 430
- loop after lens move: step = 55 - fp1,fp2 =  430 , 430
- reenter loop : step = 55 - fp1,fp2 =  430 , 430
- loop after lens move: step = 56 - fp1,fp2 =  430 , 430
- reenter loop : step = 56 - fp1,fp2 =  430 , 430
- loop after lens move: step = 57 - fp1,fp2 =  430 , 430
- reenter loop : step = 57 - fp1,fp2 =  430 , 430
- loop after lens move: step = 58 - fp1,fp2 =  430 , 430
- reenter loop : step = 58 - fp1,fp2 =  430 , 430
- loop after lens move: step = 59 - fp1,fp2 =  430 , 430
- reenter loop : step = 59 - fp1,fp2 =  430 , 430
- loop after lens move: step = 60 - fp1,fp2 =  430 , 430
- reenter loop : step = 60 - fp1,fp2 =  430 , 430
- loop after lens move: step = 61 - fp1,fp2 =  430 , 430
- reenter loop : step = 61 - fp1,fp2 =  430 , 430
- loop after lens move: step = 62 - fp1,fp2 =  430 , 430
- reenter loop : step = 62 - fp1,fp2 =  430 , 430
- loop after lens move: step = 63 - fp1,fp2 =  430 , 430
- reenter loop : step = 63 - fp1,fp2 =  430 , 430
- loop after lens move: step = 64 - fp1,fp2 =  430 , 430
- reenter loop : step = 64 - fp1,fp2 =  430 , 430
- loop after lens move: step = 65 - fp1,fp2 =  430 , 430
- reenter loop : step = 65 - fp1,fp2 =  430 , 430
- loop after lens move: step = 66 - fp1,fp2 =  430 , 430
- reenter loop : step = 66 - fp1,fp2 =  430 , 470
     - fp2<>fp1 (fp2 too late) fp1,fp2 =  430 , 470
   shoot
- loop after lens move: step = 67 - fp1,fp2 =  470 , 430
- reenter loop : step = 67 - fp1,fp2 =  470 , 470
- loop after lens move: step = 68 - fp1,fp2 =  470 , 470
- reenter loop : step = 68 - fp1,fp2 =  470 , 470
- loop after lens move: step = 69 - fp1,fp2 =  470 , 470
 
......



- loop after lens move: step = 368 - fp1,fp2 =  5950 , 5950
- reenter loop : step = 368 - fp1,fp2 =  5950 , 5950
- loop after lens move: step = 369 - fp1,fp2 =  5950 , 5950
- reenter loop : step = 369 - fp1,fp2 =  5950 , 5950
- loop after lens move: step = 370 - fp1,fp2 =  5950 , 5950
- reenter loop : step = 370 - fp1,fp2 =  5950 , 5950
- loop after lens move: step = 371 - fp1,fp2 =  5950 , 5950
- reenter loop : step = 371 - fp1,fp2 =  5950 , 5950
- loop after lens move: step = 372 - fp1,fp2 =  5950 , 5950
- reenter loop : step = 372 - fp1,fp2 =  5950 , 5950
- loop after lens move: step = 373 - fp1,fp2 =  5950 , 5950
- reenter loop : step = 373 - fp1,fp2 =  5950 , 5950
- loop after lens move: step = 374 - fp1,fp2 =  5950 , 5950
- reenter loop : step = 374 - fp1,fp2 =  5950 , 5950
- loop after lens move: step = 375 - fp1,fp2 =  5950 , 5950
- reenter loop : step = 375 - fp1,fp2 =  5950 , 5950
- loop after lens move: step = 376 - fp1,fp2 =  5950 , 5950
- reenter loop : step = 376 - fp1,fp2 =  5950 , 655350
     - fp2<>fp1 (fp2 too late) fp1,fp2 =  5950 , 655350
   shoot
- loop after lens move: step = 377 - fp1,fp2 =  655350 , 655350
     - near infinity : fp1,fp2 =  655350 , 655350
   shoot
   shoot
   shoot
   shoot
   shoot
   shoot
   shoot
   shoot
   shoot
   shoot
   shoot
   shoot
   shoot
   shoot
   shoot
   shoot
   shoot
   shoot
   shoot
   shoot
   shoot
   shoot
   shoot
   shoot
   shoot
   shoot
   shoot
   shoot
   shoot
   shoot
   shoot
   shoot
   shoot
   shoot
   shoot
   shoot
   shoot
   shoot
   shoot
   shoot
   shoot
   shoot
   shoot
   shoot
   shoot
   shoot
   shoot
   shoot
   shoot
 end of move : fp1,fp2 =  655350 , 655350
Title: Re: Lua Request/Idea
Post by: garry23 on July 02, 2016, 09:38:42 PM
@BBA

I looked at your script, but it will require me to backout the 'real meat' from all the logger stuff.

Any chance of a minimalist version without any logger stuff?

I can then look at your ideas and play around with them.

Cheers

Garry
Title: Re: Lua Request/Idea
Post by: garry23 on July 02, 2016, 10:02:41 PM
@BBA

Actually it didn't take me long to work out your 'solution', ie a delay before and after camera.shoot.

Here is my working focus stacking test script:

Code: [Select]
soft_err = true
b2 = lens.dof_far
a2 = lens.dof_near

function shoot()
      msleep(1000) -- wait for other tasks to finish
      camera.shoot(64, false)
      msleep(3000) -- wait for camera.shoot to finish
end

function move(direction)
lv.start()
local a1 = 0
local b1 = 0
if direction == -1 then -- focus stack to infinity soft stop
repeat
a1 = a2
b1 = b2
repeat
lv.resume()
soft_err = lens.focus(-1,1,false)
b2 = lens.dof_far
a2 = lens.dof_near
until a2> b1 or soft_err == false
shoot()
until soft_err == false
else  -- focus stack to macro soft stop
repeat
a1 = a2
b1 = b2
repeat
lv.resume()
soft_err = lens.focus(1,1,false)
b2 = lens.dof_far
a2 = lens.dof_near
until b2 < a1 or soft_err == false
shoot()
until soft_err == false
end
end

function start() -- test out focus stacking works through the soft stop error return
move(-1)
move(1)
move(-1)
end

scrnshot_menu = menu.new
{
    name = "Test",
select = function(this)
task.create(start)
end
}

I must say, it would be 'nice' if the Lua backend handled the delays, rather than having to do it with msleeps. I don't know if 1000 and 3000 are 'optimum' and will work with all cameras?

Thanks for all your work and feedback.

I build your 'recipe' into my full focus stacking script.

Cheers

Garry
Title: Re: Lua Request/Idea
Post by: dmilligan on July 02, 2016, 10:08:54 PM
Why would you want to remove all the "logger stuff" at this point? BBA has the right idea here. When you're trying to debug and understand a problem with code, logging is extremely helpful (sometimes the best and/or only alternative to having a "live debugger" attached). It helps you know what actually happened, and helps eliminate potentially false assumptions you have made.

I like to say you have to write to to write code. In other words there's often a lot of code that you write that will never be in the "production version" that you use to simply inform and debug the writing of the actual "production code".
Title: Re: Lua Request/Idea
Post by: garry23 on July 02, 2016, 10:21:27 PM
Sorry I wasn't being insulting, it was just all the logger  code 'got in the way' of me reading the script.

I now believe the 'problem' is that lens.focus doesn't wait for camera.shoot to do it's stuff, this is why the 'hard' delays help.

I still wonder if such delay/checks should be hard wired in.

Thanks to BBA at least I should be able to get my full script working.

Once again, my comment on longer was more a reflection of my ignorance.

Cheers

Garry
Title: Re: Lua Request/Idea
Post by: garry23 on July 03, 2016, 08:30:55 AM
@BBA

Thanks to your experimenting, I now have my script up and running: https://gist.github.com/pigeonhill/6620121ebe1548eb1bdaa6bea8598fac (https://gist.github.com/pigeonhill/6620121ebe1548eb1bdaa6bea8598fac)

This is an all in one bracketing script and I have tested it ONLY on a 5D3.

It works for me and my workflow.

The only observation I have for the developers is that, as you found out, I need to code in delays to make the lens.focus work with the camera.shoot. My concern with this approach is that it could be camera specific. It would better, IMHO, if lens.focus and camera.shoot where 'aware' of each other and handled their interactions in the 'backend'.

Once again thanks for your feedback and help.

BTW I find you only need the delay after you call camera.shoot and a 2s delay works on my 5D3
Title: Re: Lua Request/Idea
Post by: garry23 on July 03, 2016, 10:55:44 AM
@BBA

I little more insight.

As I say, the delay before the camera.shoot does nothing, ie the script works with it at zero.

The delay after camera.shoot is critical.

If I use msleep(1000) the script fails on my 5D3.

If I use msleep(2000) the script works.

If I use msleep(2000) and Dual-ISO is on the script fails.

I need to raise the delay to msleep(4000) to use Dual-ISO.

I guess the more ML needs to process 'stuff', eg Dual-ISO, the longer the delay to ensure lens.focus is fit to run.

Cheers

Garry
Title: Re: Lua Request/Idea
Post by: BBA on July 03, 2016, 11:48:17 AM
@garry23/dmilligan

I have been asleep for a while. I was glad to have something working ... which had to be further improved.
I like to know what happens really behind the scenes. I have often found that I could be completely wrong without analyzing in the details.
It is often too much precautions at the beginning, till something is found.

Thanks for experimenting with the delays : it will help to further improve and go as fast as possible. Maybe it would be possible to test if some variable stabilizes to know that the camera.shoot or something else is complete.
I don't know if the "type precautions" like tonumber and tostring have to remain : I put them because the test fp1<>fp2 after the move did not work at all. I thought it could be comparing apples with peers (as Lua is not a strict "typed" language, some side effect...). I may be completely wrong on this.
I have in mind (read somewhere) that lens.focus_distance could be updated later. This is a problem as the algorithm depends on its value: we don't know if it has not changed because it will not change anyway or because we question it too fast for it to have changed.
Title: Re: Lua Request/Idea
Post by: garry23 on July 03, 2016, 12:22:48 PM
@BBA

I had already thought along your lines (great minds think a like  ;)) and came up with this camera-independent delay, rather than use msleep.

Code: [Select]
shoot()
repeat
err = lens.focus(1,1,false)
until err


This works on my 5D3  :)

All the repeat does is hang around until lens.focus returns a true, ie is not 'insulted' by camera.shoot anymore.
Title: Re: Lua Request/Idea
Post by: BBA on July 03, 2016, 01:25:45 PM
@garry23

So, the boolean value returned by lens.focus has two significances intermixed
In your code snippet:
1) the loop can be endless if the lens stepping motor cannot move anymore in the "asked" direction
2) you have to move the lens one step in the opposite direction when there is no task running for which a lens move could be harmful.
In this last case, it sounds like a "ressource" has to been taken by concurrent tasks to have access to the lens move.
Title: Re: Lua Request/Idea
Post by: garry23 on July 03, 2016, 02:10:36 PM
@BBA

Agreed, but I only use this err test after I have taken an image, eg like in this snippet of my script

Code: [Select]
my_shoot()
repeat
err = lens.focus(-1,1,false)
msleep(1000)
until err
err = lens.focus(1,1,false)
Seems to work  ;)
Title: Re: Lua Request/Idea
Post by: a1ex on July 03, 2016, 02:11:53 PM
@garry23: can you try the following waiting sequence after taking a picture?

Code: [Select]
while not lv.running do msleep(100) end
lv.wait(1)

This waits until Canon code goes back to LiveView (as reported by Canon property system) after taking a picture, then it makes sure LiveView is fully initialized and running (it waits for one LiveView frame).

BTW, my assert test above should have been "assert(lv.running)" instead of "assert(lv)".
Title: Re: Lua Request/Idea
Post by: garry23 on July 03, 2016, 02:21:20 PM
@A1ex

Tried your code snippet and got a lv.wait timeout error
Title: Re: Lua Request/Idea
Post by: garry23 on July 03, 2016, 02:23:35 PM
...sorry tried again and no error, but no fix, ie script stops.
Title: Re: Lua Request/Idea
Post by: a1ex on July 03, 2016, 02:45:37 PM
Hm... maybe lv.wait(5) or adding some small delay after that?

(I'm not able to try it myself right now)
Title: Re: Lua Request/Idea
Post by: garry23 on July 03, 2016, 03:07:52 PM
@A1ex

I tried this, but no luck:

Code: [Select]
while not lv.running do msleep(100) end
lv.wait(5)
msleep(200)

where as this approach to delaying works:

Code: [Select]
repeat -- until lens is ready to continue
err = lens.focus(-1,1,false)
msleep(1000)
until err
err = lens.focus(1,1,false)

Title: Re: Lua Request/Idea
Post by: BBA on July 03, 2016, 05:06:36 PM
@garry23

to report my trial (If you have spare time, as working on a way to detect "camera.shoot's" end is also very important, for all of us! )

I just tried your new full script (which is user friendly  :)  thanks for sharing ! ) : I have only used the stack focusing, Ev bracketing and bookend (which I think useful) capabilities.
In landscape conditions (going from a few meters to, maybe, a few hundreds of meters range), with FP2INF, and starting with a blurred image towards macro end.
2 brackets of 2 images were taken but the focus point did not move enough to deblur the pictures.

Bottom line : I think it should have taken more brackets towards infinity end.
It seems everything else went fine and fast :  the message "script finished" + beeps at the end.
Title: Re: Lua Request/Idea
Post by: garry23 on July 03, 2016, 05:19:47 PM
@BBA

Have you got the ML depth of field settings at their optimum, ie diffraction aware is on.

I don't understand what you are saying, as if the lens moves from the FP to INF or MAC, a full set of correctly overlapping focus stacks will be taken.

All you need to do then is post process: I use Helicon Focus.

BTW there is some interesting reading here: http://www.georgedouvos.com/douvos/Image_Sharpness_vs_Aperture.html (http://www.georgedouvos.com/douvos/Image_Sharpness_vs_Aperture.html)
Title: Re: Lua Request/Idea
Post by: BBA on July 03, 2016, 05:37:05 PM
@garry23

Maybe I missed something. I can't check for now, I'll retry later.

Thanks !
Title: Re: Lua Request/Idea
Post by: a1ex on July 03, 2016, 05:39:00 PM
Those graphs are very interesting. I'd definitely like to have an option to display them in ML.
Title: Re: Lua Request/Idea
Post by: garry23 on July 03, 2016, 06:06:52 PM
@BBA

what camera are you using. As I say, my script works on my 5D3.

@A1ex

The DoF equations that I originally put into ML, that you optimised, and my script, achieves what the last curve in the URL implies, ie an optimised focus bracket set, ready for post processing.

Title: Re: Lua Request/Idea
Post by: garry23 on July 03, 2016, 06:13:04 PM
@BBA

Forgot to add the number of focus bracket required to get from, say, macro end to INF is very dependent on FL and aperture.

On a wide angle lens at say F/11 you wont need many.

The secret is to select the optimum aperture for IQ.
Title: Re: Lua Request/Idea
Post by: a1ex on July 03, 2016, 06:32:20 PM
The DoF equations that I originally put into ML, that you optimised, and my script, achieves what the last curve in the URL implies, ie an optimised focus bracket set, ready for post processing.

I know that. What I meant was to show these graphs on the camera screen, since they convey a lot more information about the depth of field than the current method (focus distance and far/near limits).
Title: Re: Lua Request/Idea
Post by: BBA on July 03, 2016, 06:36:31 PM
@garry23

I have checked: diffraction-aware = ON; It is correct
I have a 5D3.
Aperture number is 5.6. Focal length = 200 mm
Believe me the problem is not there : the picture is heavily blurred because the lens barrel is turned to focus near macro end.

The FP should move towards infinity thanks to the script.

Quote
as if the lens moves from the FP to INF

This is the problem, I am afraid  >:( 
downloaded the script again (version 3 "Auto Bracketing.lua") to be sure...

Tried 5 times
Maybe it works on your camera but not on mine ?????
I feel sorry to have to report bad news...
Title: Re: Lua Request/Idea
Post by: garry23 on July 03, 2016, 06:37:58 PM
@A1ex

I know what you are saying, however, once the user has a specified CoC, I'm not sure seeing the curve is that useful.

I use the following simple formula to estimate the required blur circle in microns:
 
Blur Spot (microns) = (C x M) / (P x L)

Where C is the size of the (cropped) image on the sensor; M is the distance ratio compared to a ‘normal’ 10in viewing distance, ie if you intend to view at, say, 24 inches away, M would be 2.4; P is the print size; and L is the number of line pairs per mm that you are using as your ‘eye sight’ criterion (typically between 5 to 8). Note you should keep C and P in the same units, eg mm or in or whatever.

As an example, let’s assume we are looking to create a 16 x 20 in (ie about 500mm wide) print, that will be seen in a gallery (so we will use 8 lp/mm) at the closest viewing distance of, say, 24in, and that our image is taken from a slightly cropped area of our full frame image, with a cropped (sensor) dimension of about 30mm (out of the 36mm total sensor width).

The suggested blur spot may be estimated as: 30 x 2.4 / (500 x 8) = 0.018mm (18 microns).

Obviously this is much smaller than is suggested by the generic web number, ie some 29 microns. By the way, the 29 micron (generic number) may now be seen as indicative of 5 lp/mm viewed at 10in; in other words the web-based advice is at the lower end of our acceptable sharpness and eye sight. In other words, OK for snaps and blogs, but maybe not judges!
Title: Re: Lua Request/Idea
Post by: garry23 on July 03, 2016, 06:47:33 PM
@BBA

I think I know what is going on: I just tried my 70-200 F/4L at 200.

If you start at the full macro end the DoF near and far are so close to each other, the script can't handle it.

If you move off the macro and increase aperture to, say, F/11, the script runs fine. BUT, and it is a big but, you will end up taking a hell of a lot of images.

Bottom line: at long FLs, focus stacking will be problematic. Just be aware of this and adjust accordingly, ie move focus away from the full macro end, increase aperture to the optimum for stacking, and reduce FL if you can.
Title: Re: Lua Request/Idea
Post by: BBA on July 03, 2016, 07:01:32 PM
@garry23

I'll leave it quiet for now.

Thanks again for your informations about focusing, you seem to know a lot on this subject.
Title: Re: Lua Request/Idea
Post by: garry23 on July 03, 2016, 10:58:31 PM
@BBA

I thought I would add in a little helper to my script : You can download this version here: https://gist.github.com/pigeonhill/6620121ebe1548eb1bdaa6bea8598fac (https://gist.github.com/pigeonhill/6620121ebe1548eb1bdaa6bea8598fac)

This version estimates (sic) the number of focus brackets that will be taken from the FP to the hyperfocal point and shows this number in the menu.

It dynamically updates in the menu, so you can see the impact of FL.

For example put the focus near the macro end and change the focal length. You will be surprised! At 200mm F/5.6 you will need some 110 brackets!!!

In other words, use focus bracketing with WA lenses.

BTW my delay algorithm is a bit flaky at the macro end: I'll be trying to make it more robust  :)
Title: Re: Lua Request/Idea
Post by: garry23 on July 04, 2016, 10:05:30 AM
@BBA

Off to the dentist now  :(

Here is the latest, most stable version of my script: https://gist.github.com/pigeonhill/6620121ebe1548eb1bdaa6bea8598fac (https://gist.github.com/pigeonhill/6620121ebe1548eb1bdaa6bea8598fac)

BTW I found a 'trick' to test if the lens is ready:

Code: [Select]
local err = false
repeat
err = lens.focus(0,1,false)
msleep(1000)
until err

I would welcome any further testing of my script by you: but watch those long lenses. Best use WA lenses.
Title: Re: Lua Request/Idea
Post by: BBA on July 04, 2016, 12:08:39 PM
@garry23

Wow ! Your trick is genial   :) !
It doesn't require a lens move => seems perfect.

(Side note : I don't know if camera.shoot doesn't return something undocumented too ???)

I love the idea of "estimating" the number of focus brackets beforehand  :) ; I'll test it for sure and report to you.

I have many questions on focusing and it's use in your script, but I have a hard time writing them...  :-\ :

- I would love to see equations of focal point, near focus, far focus where diffraction is taken into account ?

- do you know the (approximate) formula of the focal point distance in function of the rotation of the focus barrel ; this is important in the near infinity range even if it is approximate. Or, do you have another idea of what could be done in that range. My concern is that it is no more possible to "interpolate" with "infinity"  ???... we have to extrapolate as correctly as possible... The variation of the focal distance becomes more and more important and less and less precise for one single step move: the "near focus" is the only variable that remains "finite" and tends to hyperfocal/2 ? Have others found an (obviously incomplete) answer to this question ?

- I will try if the number of brackets estimated is (approximately) what actually occurs (it's fair, isn't it  ;) )

- this one... : if I use AF and focus on an object, do you think the exact lens focusing point can lie between two stepping motor positions ? In other words, the AF can be more precise than the discrete nature of a stepping motor which,  say with lens.focus(1,1),  will go from one position to the next but cannot go in between (the first argument is an integer, not a real number (evident)). Or in other words, is lens.focus(1,1) the smallest step achievable by the lens focusing mechanism ? (I know it is Canon expertise but we can have ideas on the subject: phase focusing loop/ nowadays, everything is digital,...)   

- the same question arises with manual focus as the manual move is "analogical" rather than digital, or is it converted anyway into digital move ? (It depends on the lens but for new L lenses, for instance)

 :-[
 
Title: Re: Lua Request/Idea
Post by: BBA on July 04, 2016, 04:02:10 PM
@garry23

First report on V3 R1.25 :

My yesterday concerns (number of brackets taken) are gone  :) , I chose to try in the same conditions with the same long lens at 200 mm.

I have seen the number of brackets updating when turning the lens : I think it is very useful for beginners.

It is not useful to start when the whole picture is blurry as those pictures will have to be thrown away. Even further, those unnecessary picture may leave unwanted side effects : the perimeter of light sources, of greater diameter because they are out of focus, may remain visible in the stack focus processing result for instance.   

I have to test further but I needed to tell you that.

@garry23

to report my trial (If you have spare time, as working on a way to detect "camera.shoot's" end is also very important, for all of us! )

I just tried your new full script (which is user friendly  :)  thanks for sharing ! ) : I have only used the stack focusing, Ev bracketing and bookend (which I think useful) capabilities.
In landscape conditions (going from a few meters to, maybe, a few hundreds of meters range), with FP2INF, and starting with a blurred image towards macro end.
2 brackets of 2 images were taken but the focus point did not move enough to deblur the pictures.

Bottom line : I think it should have taken more brackets towards infinity end.
It seems everything else went fine and fast :  the message "script finished" + beeps at the end.

Title: Re: Lua Request/Idea
Post by: garry23 on July 04, 2016, 06:36:19 PM
@BBA

Thanks for all your testing.

BTW here is a short piece I wrote a while ago on DoF equations: http://photography.grayheron.net/2015/04/customising-magic-lantern.html (http://photography.grayheron.net/2015/04/customising-magic-lantern.html)

The key thing to note is the far DoF is much greater than the near. Unlike macro which is symmetric.

As for how many images you need. In theory once you focus at the hyperfocal distance, for the criteria you have selected, eg blur spot (or CoC), you are there. However, most would say also grab an image at 'infinity'. Thus I decided to stop bracketing at infinity, not the HFD.

As for workflow, I suggest you have three options (which I use):

Option A: Put the lens at infinity or macro and let the script grab the brackets to achieve a full set of focus brackets.
Option B: Focus on the nearest object and let the script grab the images to infinity;
Option C: Focus on the furthest object and let the script grab the images to the macro soft stop

In all cases note the number of focus brackets required in the menu feedback when focused at the macro. Also, focus bracketing a full set with a long lens is not the best use of the script, eg you will end up with too many brackets and there is a trade off with time, ie wind and clouds moving.

My experience is, up to 6 is about the limit; but it is your choice.

Bottom line: my script, using the diffraction corrected DoFs is about the best landscape (not macro) focus bracketing you can do: IMHO  ;)

BTW you can't get simpler than this - no lens movement: or can you  ;)

Code: [Select]
repeat
msleep(1000)
until lens.focus(0,1,false)

Not sure if msleep(1000) is 'optimum'

Title: Re: Lua Request/Idea
Post by: garry23 on July 04, 2016, 11:59:54 PM
@BBA

And so to bed, after some cleaning up and error checking added: https://gist.github.com/pigeonhill/6620121ebe1548eb1bdaa6bea8598fac (https://gist.github.com/pigeonhill/6620121ebe1548eb1bdaa6bea8598fac)
Title: Re: Lua Request/Idea
Post by: garry23 on July 06, 2016, 12:04:11 AM
@BBA

A post on my blog just for you  ;)

http://photography.grayheron.net/2016/07/rev-3.html (http://photography.grayheron.net/2016/07/rev-3.html)