M3 etc focus move - page 4 - General Help and Assistance on using CHDK stable releases - CHDK Forum

M3 etc focus move

  • 48 Replies
  • 6831 Views
Re: M3 etc focus move
« Reply #30 on: 02 / July / 2022, 09:15:17 »
Advertisements
Just a quick update on things.
I've updated my Landscape Bracketing Script to a Rev-2 version: M3 only.
It's still a work in progress, but its stable enough to share: https://gist.github.com/pigeonhill/742cf84b8dd47a9de8dc5ea65ecc35b6
The script does the same as the Rev 1 version, but all the focus feedback and moving is now based on the Focus LUTs, which gives finer resolution, ie mm not cms, ie towards the macro end where there are more steps/cm, say.
« Last Edit: 03 / July / 2022, 01:54:09 by pigeonhill »

Re: M3 etc focus move
« Reply #31 on: 03 / July / 2022, 02:37:43 »
While working on this https://chdk.setepontos.com/index.php?topic=14554.10 I noticed a EOS M cams have a function PrintFALensInfoData, which gets a bunch of lens related values and outputs them,
One of the values AbsDisFar, which I believe is what we called focus_distance_upper elsewhere. Other include FocusPos and FocusPosSize, which seem like they might be relevant.

If someone can do the following with chdkptp (or equivalent standalone Lua), I'd be interested to see the resulting AdjLog.txt
Code: [Select]
=return call_event_proc('FA.Create')
=return call_event_proc('StartLogOut',-2,0x1000,0)
=return call_event_proc('PrintFALensInfoData')
=return call_event_proc('OutputLogToFile')
download AdjLog.txt
If PrintFALensInfoData returns -1, you call
Code: [Select]
=return call_event_proc('InitializeAdjustmentSystem')
and call PrintFALensInfoData again.
You could call PrintFALensInfoData after setting focus to the ends of the available range.

Other possibly relevant eventprocs are GetEFLensFocusPositionWithoutLensCom and GetEFLensFocusPositionWithLensCom
I think these should both return the position, and print it AdjLog.txt if enabled.

@reyalp

At the moment I’ve implemented a rather brute force way of characterising the lens, ie stepping through every step and capturing the steps at every Canon focus change. This then allows me to use these data in two look up tables, and then, knowing the step I’m at, carry out a 2nd order interpolation for the focus at the step I’m at.

The downside is having to characterise the lens at each camera start up, or when focal length changes, which can take 10s of seconds.

I wonder if you have come across any Canon functions that explicitly hold that data, ie the upper and lower focus distances, and the step value at those distances.

Or we we doomed to creating the focus LUTs ourselves.

Cheers

Garry
« Last Edit: 03 / July / 2022, 02:46:52 by pigeonhill »

*

Offline c_joerg

  • *****
  • 1251
Re: M3 etc focus move
« Reply #32 on: 03 / July / 2022, 15:03:49 »
I would write the LUT to a file. Do the values ​​change at each focal length?

Perhaps you can also describe the curves with a function.
M100 100a, M3 121a, G9x II (1.00c), 2*G1x (101a,100e), S110 (103a), SX50 (100c), SX230 (101a), S45,
Flickr https://www.flickr.com/photos/136329431@N06/albums
YouTube https://www.youtube.com/channel/UCrTH0tHy9OYTVDzWIvXEMlw/videos?shelf_id=0&view=0&sort=dd

Re: M3 etc focus move
« Reply #33 on: 03 / July / 2022, 15:31:03 »
I would write the LUT to a file. Do the values ​​change at each focal length?

Perhaps you can also describe the curves with a function.

@c_joerg

I think the steps vs focus distances do change as you change focus. Or, I can't convince myself they don't ;-)

In addition, sometimes, but uncorrelated, the inialisation at MFD doesn't result in a step zero at MFD.

To account for this in my script I create one set of LUTs at the favorite focal length, eg:

Code: [Select]
if lens_name() == "EF-M11-22mm f/4-5.6 IS STM" then -- calculate lens thickness from manufacturer's data
    --if lens_name() == "E-M11-22mm f/4-5.6 IS STM" then -- calculate lens thickness from manufacturer's data
        -- add other lenses as required, ie replace the following for your lens
        -- For the above lens, 300 is the lens max magnification x 1000, ie from manufacturer's data or your measurement
        -- 22000 is the lens maximun zoom, or the prime, focal length in microns
        -- 150 is the lens minimum focus distance (mm), ie from manufacturer's data or your measurement
        Fmax = 22000 -- Longest focal length (mm) * 1000
        Mmax = 300 -- Max magnification * 1000
        MFD = 150 -- Minimum Focus Distance in mm
        t = hiatus() -- distance between front and rear principals
        step_count = {0,98,170,204,235,262,288,313,339,361,377,398,411,428,441,450,463,471,482,486,491,499,506,512,516,521,525,529}
        x_at_count = {150,160,170,180,190,210,220,240,250,280,300,330,360,400,450,500,560,630,710,810,930,1080,1270,1540,1940,2590,3840,7600}
        CalFL = 11
        return true
At camera start up I then look to see if a set of LUTs exist and I'm at the correct FL, reposition the lens to the MFD and see if the count there is zero. If not I use this offset to shift registered LUT counts into alignment.

If the lens doesn't  have a registered LUT or the FL changes, I recreate the LUTs.
Here are the functions I use:

Code: [Select]
function set_up_lens() -- create Steps & Focus LUTs
-- This function may take a while to run for some lenses, ie with lots of steps
-- However, as long as you don't change focal length, you only need to run this once
-- You will need to call this function after any focal length change
if log == 1 then print_screen(-1) end -- switch focus bracketing logging on
    call_event_proc("EFLensCom.FocusSearchNear")
    call_event_proc("EFLensCom.FocusSearchNear") -- just in case ;-)
    sleep(100)
    call_event_proc('InitializeAdjustmentSystem')
    sleep(100)
    local j = 1
-- Note this function doesn't require the step count at MFD to be zero
-- It does assume, however, the LUTs don't change; other than explicity when focal length is changed
    step_count[j] = call_event_proc('GetEFLensFocusPositionWithLensCom') -- doesn't seem to be different to calling 'GetEFLensFocusPositionWithoutLensCom'
    x_at_count[j] = get_focus_distance_lower() -- This is the Canon reported MFD
    local last_lower = get_focus_distance_lower()
    print("Inialising Lens")
    while get_focus_distance_upper() < inf do
        call_event_proc("EFLensCom.MoveFocus", 1, 1)
        sleep(25) -- this could be changed, but only through testing
        if get_focus_distance_lower() > last_lower then -- just gone through a Canon focus step change
            j = j + 1
            step_count[j] = call_event_proc('GetEFLensFocusPositionWithLensCom')
            last_lower = get_focus_distance_lower()
            x_at_count[j] = last_lower
        end
    end
    if log == 1 then -- print out LUTs
        print(lens_name())
        print("Focal Length: "..F:int().."mm")
        print("Steps LUT")
        for i = 1, #step_count do
            print(step_count[i])
        end
        print("Focus LUT")
        for i = 1, #step_count do
            print(x_at_count[i])
        end
    end
    call_event_proc("EFLensCom.FocusSearchNear")
    sleep(100)
    print("Lens ready")
end
   
function get_x_based_on_step_pos() -- estimate of focus distance in mm from the sensor plane
-- This function uses a Lagrange estimation scheme, based on a 2nd order three point interpolation assumption
    local n = #step_count
    local t = call_event_proc('GetEFLensFocusPositionWithLensCom') -- step value at current focus
    local j = 1
    for i = 2, n do
        j = i - 1
        if t <= step_count[i] then break end
    end
    if j >= (n-1) then j = n - 2 end -- handle being at the end of the LUT tables
    if get_focus_distance_lower() > 81000 then -- at/beyond any useful lens data
        return get_focus_distance_upper()
    end
    local t1 = step_count[j]
    local t2 = step_count[j+1]
    local t3 = step_count[j+2]
    local pt = fmath.new(0)
    pt = pt + (x_at_count[j]*(t-t2)*(t-t3))/((t1-t2)*(t1-t3))
    pt = pt + (x_at_count[j+1]*(t-t1)*(t-t3))/((t2-t1)*(t2-t3))
    pt = pt + (x_at_count[j+2]*(t-t1)*(t-t2))/((t3-t1)*(t3-t2))
    return pt:int() -- focus position in mm
end

function move_by(xx) -- move from current position by xx mm
    local current_focus_pos = get_x_based_on_step_pos()
    while get_x_based_on_step_pos() < (current_focus_pos+xx) do
        call_event_proc("EFLensCom.MoveFocus", 1, 1)
        sleep(25)
    end
    sleep(50)
end
If I'm focus bracketing via the Lua code, I don't think we need the above, ie my current scheme is good enough, ie find the Canon focus step you are in and linearly interpolate. The LUT approach and the lagrange interpolation has value for manual focus position feedback.
I'll carry on playing ;-)

*

Offline reyalp

  • ******
  • 14126
Re: M3 etc focus move
« Reply #34 on: 03 / July / 2022, 18:37:27 »
I wonder if you have come across any Canon functions that explicitly hold that data, ie the upper and lower focus distances, and the step value at those distances.
I have not. I'm pretty sure the distance and lens position values are independent values obtained from the MCU on the lens, so whatever conversion happens is in the lens firmware. I haven't seen anything in the camera firmware that suggests a way to get distance values for positions other than the current position.

Canon does offer lens firmware updates (e.g. https://www.usa.canon.com/internet/portal/us/home/support/details/lenses/ef/standard-zoom/ef-m-15-45mm-is-stm?subtab=downloads-firmware), so reverse engineering there could potentially be productive. There has also been some work on the protocol https://gist.github.com/marcan/858c242db2fc595da1e0bb70a05192fc https://www.magiclantern.fm/forum/index.php?topic=3796.0

(edit: ML forum also looked at firmware https://www.magiclantern.fm/forum/index.php?topic=20969.0)

edit:
One other function I noticed is EFLensCom.GetFocusPitch. This prints a string like
"Focus Pitch = %lf mm/pulse", but does not return the value. I'm not clear these values refer to, is mm phisical movement in the lens? Is "pulse" a position unit, or something totally different? Perhaps seeing the values would shed some light.

You could log this value using uart redirection
Code: [Select]
-- start of script
uartr=require("uartr")
uartr.start("A/UART.LOG", 1)
... other code
call_event_proc("EFLensCom.GetFocusPitch")
...

-- end of script
uartr.stop()
« Last Edit: 03 / July / 2022, 18:55:38 by reyalp »
Don't forget what the H stands for.

Re: M3 etc focus move
« Reply #35 on: 04 / July / 2022, 01:29:16 »
@reyalp

Thanks.

I inserted the uartr calls, but I don't seem to get any log file in the CHDK LOG folder.

Got this:

Code: [Select]
uartr.lua: start UART redirection
Focus Pitch = 0.000000 mm/pulse
uartr.lua: stop UART redirection

Not much help I'm afraid ;-)

Cheers

Garry

PS

Also got this record during a lens move:

Quote
uartr.lua: start UART redirection

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Focus Move Complete!!

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Focus Move Complete!!

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Target: 1, Speed: 1

Focus Pitch = 0.000000 mm/pulse

Focus Move Complete!!
uartr.lua: stop UART redirection
« Last Edit: 04 / July / 2022, 01:56:08 by pigeonhill »

Re: M3 etc focus move
« Reply #36 on: 04 / July / 2022, 15:43:46 »
I've reached a stopping point now, which is captured in this version of my Landscape Bracketing Script:
https://gist.github.com/pigeonhill/742cf84b8dd47a9de8dc5ea65ecc35b6

The best I can do is register the two Focus LUT tables at a single focal length, THE focal length in the case of a prime.

The script looks to see if a registered FLUT and focal length match the current FL, and, if this is the case, the FLUT is used.

If the FLUT doesn't exist, then it is created, which on my M3 takes about 15 seconds with my 11-22mm lens.

A new FLUT is created if the FL changes, but if this FL matches the registered FLUT then this used, ie FLUTs are not created at the registered FL.

The script also checks that the MFD count equals the FLUT value at MFD. If it doesn't then FLUT is adjusted, ie offset. The offset is reported.
« Last Edit: 04 / July / 2022, 15:46:31 by pigeonhill »

*

Offline reyalp

  • ******
  • 14126
Re: M3 etc focus move
« Reply #37 on: 04 / July / 2022, 18:27:14 »
Not much help I'm afraid ;-)
Yeah, whatever it is, it doesn't seem very useful  ???

Thanks for testing.

I'm still trying to figure out what I can reasonably make available in Lua script, but it's quite hard to understand without having a camera to test.
Don't forget what the H stands for.

*

Offline Caefix

  • *****
  • 948
  • Sorry, busy deleting test shots...
Re: M3 etc focus move
« Reply #38 on: 05 / July / 2022, 13:12:03 »

I've reached a stopping point now, ...  :-*


The next need is some get_zoom(). Can it be derivated somehow?
EFM 11-22, 15-45 & 18-150 have in common 0x3f=64 zoom_steps.

Code: [Select]
ZoomPos                    : 0x3f
 ZoomPosSize                : 0x3f
What was the relation between subj_distance/LUT & get_zoom() ... :blink:
All lifetime is a loan from eternity.

Re: M3 etc focus move
« Reply #39 on: 05 / July / 2022, 14:12:48 »

I've reached a stopping point now, ...  :-*


The next need is some get_zoom(). Can it be derivated somehow?
EFM 11-22, 15-45 & 18-150 have in common 0x3f=64 zoom_steps.

Code: [Select]
ZoomPos                    : 0x3f
 ZoomPosSize                : 0x3f
What was the relation between subj_distance/LUT & get_zoom() ... :blink:

@Caefix

I don't think the problem is the number of upper/lower steps, the 'issue' for me, in creating the Focus LUTs, is the number of total steps. For example, the 11-22mm, at 11mm, has some 530 steps to move through to locate the upper/lower change points, whereas the 28mm macro, at 1:1, has some 2200!!!

So the macro will benifit from pre-registering the LUTs, but I'm still looking at the difference between 1:1 and the extended macro setting.
« Last Edit: 05 / July / 2022, 14:52:06 by pigeonhill »

 

Related Topics


SimplePortal © 2008-2014, SimplePortal