Lens movement/focus control - page 2 - General Help and Assistance on using CHDK stable releases - CHDK Forum

Lens movement/focus control

  • 34 Replies
  • 406 Views
*

Offline reyalp

  • ******
  • 13826
Re: Lens movement/focus control
« Reply #10 on: 24 / January / 2023, 15:01:17 »
Advertisements
Thus used in Lua as: call_event_proc("MoveFocusPosition_FW", n, m), where I'm guessing n is signed, ie direction, and m is speed?
First, note _FW in the csv isn't part of the actual name, it's something added by the sig finder for convoluted historical reasons. So if you want to use call_event_proc, the name is MoveFocusPosition. It also may need to be registered.

It looks like MoveFocusPosition is registered by InitializeAdjustmentFunction and/or InitializeAdjustmentSystem (these functions register an overlapping set of functions, with System initializing more), which are in turn registered by FA.Create. Note the InitializeAdjustment* functions are known to have side effects on some cams, triggering crashes on half press and things like that.

The meaning of MoveFocusPosition arguments isn't immediately clear to me, but it only appears to take one, which is presumably a position. Whether it is absolute or relative is unclear. It calls GetFocusLensPullInMaxSpeed, which might suggest it simply moves at max speed.

Quote
GetCurrentFocusPosition_FW = 0xfc3b9fa1
j = call_func_ptr(GetCurrentFocusPosition_FW)
That should probably work. I would generally prefer using eventprocs when possible, because:
1) Typos are less catastrophic (return -1 rather than instant crash or executing the wrong code)
2) Not camera + firmware specific (avoids #1 if you use on the wrong camera)
3) For functions that accept arguments, calling by pointer often requires additional logic, or using a different, underlying function, because eventproc functions generally expect to receive a single pointer with all the arguments. This is handled automatically when you use call_event_proc
4) Sometimes the registration does other initialization required by the functions

On the flip side, sometimes the registration functions have negative side effects, as mentioned above.

The mfvals.lua script in the first thread I linked earlier (https://chdk.setepontos.com/index.php?topic=11078.msg130083#msg130083) has an example of using GetFocusLensCurrentPosition as an eventproc. The registration function is Mecha.Create, which also registers many other lens related function. Unlike the "Adjustment" functions mentioned above, I'm not aware of Mecha.Create having negative side effects.

Quote
Find out the step value where I'm focused
Move to the macro end, ie move until the current step value is the same at the last one, and record the value
Move to infinity, ie until the current step value is the same as the last one, and record the value
FWIW, Mecha.Create registers GetFocusLensMoveMaxPosition and GetFocusLensMoveMinPosition as well as MoveLensToFirstPoint and MoveLensToTerminatePoint which sound suggestive


Quote
Thus I know the lens full throw (MFD to infinity) in steps and can move by a specified number of steps using call_event_proc("MoveFocusPosition_FW", n, m), with n as the number of steps, ie 12 or -15, and m = 1, say
I'd suggest starting with GetFocusLensMoveMaxPosition and GetFocusLensMoveMinPosition and see if they give values that look compatible with GetCurrentFocusPosition (that is, if you move focus through the range using canon MF, does *Current* move approximately between the reported min and max)

If so, then I might try one of the MoveFocusLens* functions registered by Mecha.Create, but some additional examination is probably in order before blindly calling them. I'll try to take a look a bit later and post here.
Don't forget what the H stands for.

Re: Lens movement/focus control
« Reply #11 on: 24 / January / 2023, 15:19:26 »
@reyalp


Great info, many thanks.




*

Offline reyalp

  • ******
  • 13826
Re: Lens movement/focus control
« Reply #12 on: 25 / January / 2023, 00:11:02 »
Some notes:
Attached is a list of focus related eventprocs registered by Mecha.Create (found via function at fc65fab8 in the 100c firmware)
There may be others registered by other functions called by Mecha.Create, but this group seemed to be the core focus related ones.

Of these, the following appear of interest:
GetFocusLensMoveMaxPosition
GetFocusLensMoveMinPosition

GetFocusLensCurrentPosition

MoveFocusLensWithPosition

The three Get functions take no arguments. From my testing on elph180, the Min and Max values do not change based on zoom. On that camera, they are 40 and 1840 respectively, and GetFocusLensCurrentPosition returns numbers in this range.

From observation with set_focus, smaller position values correspond to longer subject distances.

Moving on to MoveFocusLensWithPosition
WARNING: High risk of hardware damage ahead. You break it, you fix it

There was some previous experimentation with this function discussed in the ixus160 thread but be warned not everything posted there is correct or safe, and even if it is correct on the camera discussed in that thread, it doesn't mean it's correct on yours.

As discussed in that thread, MoveFocusLensWithPosition takes three arguments. The first is a position, in the same units as the Get function discussed above.

The second is speed. Zero appears to be handled as a special case, and does a fast speed, similar to camera auto focus.

Contra the discussion in the ixus160, I found 100 was very slow (10 was imperceptibly slow and hit timeout errors). 1000 was still quite slow. It could perhaps be position units per second.

The third is unknown, but judging from firmware code (both elph180 and g5x) there are distinct cases for 1, 2, or any other value. I only tried 0, since the "any other value" case appeared simplest in the code.

I tested with the camera in MF mode (via set_mf(true)) since trying to set it with AF active seems like asking for trouble.

Generally speaking, it worked. Focus can be moved by position, through full range specified by the Min and Max functions, at any focal length.

This means that the lens can be moved far outside the normal / useful SD range, which brings us to the fun part. In my final test, with the camera at max zoom, I set the position to 40, which worked, and made everything out of focus. Then I switched to play (which doesn't immediately retract the lens) and turned the camera off.
The lens started to retract, but didn't retract completely.
Crashing with the lens out is fairly common, and normally sorts itself on the next reboot, so I powered the camera back on… and the lens mechanism buzzed an twitched, and then the camera displayed "Lens Error" and shut down again, with the lens still out.
Powering cycling several more times failed to retract the lens.
Eventually with some light percussive maintenance (which may or may not have made any difference), I was able to boot into rec mode (again, unclear if attempting to boot into rec made any difference), and shut down cleanly, with the lens retracting normally.

Contra hacki's comment in this ixus160 thread, I strongly suspect this was triggered by having the lens in an abnormal position at shutdown (since I don't think the camera crashed) (edit: see below), although I can't completely rule out other possibilities.

All that said, I would be quite reluctant to experiment with this on an expensive camera. If I did, I would try to restrict the "position" values used to something close to the range accessible via the Canon MF menu or set_focus().

edit:
I later determined that elph180 (sometimes?) crashes leaving MF mode, so there was likely a crash during shutdown. Whether the MoveFocusLensWithPosition was a factor is unclear.
« Last Edit: 25 / January / 2023, 17:33:07 by reyalp »
Don't forget what the H stands for.

Re: Lens movement/focus control
« Reply #13 on: 25 / January / 2023, 00:40:58 »
@reyalp


Once again, I really appreciate your info. There is enough here for me to experiment, ie at my risk ;-)


One matter that still confuses me with the P&S CHDK world is the use of ‘zoom’.


Zoom to me is focal length change, ie not focus position change. Is that what CHDK means? That is zoom means change focal length?


*

Offline reyalp

  • ******
  • 13826
Re: Lens movement/focus control
« Reply #14 on: 25 / January / 2023, 00:49:55 »
One matter that still confuses me with the P&S CHDK world is the use of ‘zoom’.

Zoom to me is focal length change, ie not focus position change. Is that what CHDK means? That is zoom means change focal length?
Yes, in CHDK zoom means focal length, completely in the normal photography sense of the word (max zoom = longest telephoto, min zoom = widest wide angle). The relevance to focus distance is the that the available / useful range of focus distance depends on focal length.
Don't forget what the H stands for.

Re: Lens movement/focus control
« Reply #15 on: 25 / January / 2023, 00:52:04 »
Cheers

Re: Lens movement/focus control
« Reply #16 on: 25 / January / 2023, 09:21:25 »
@reyalp

Have started testing, sloely ;-)

I can get postioal info return, and, as expocted, unless I start at MFD or infinity, neither of the extremes are 0. As expected.

No problem for me.

What is strange, after reading your post, is when I use pos=call_event_proc('GetFocusLensMoveMinPosition') or pos=call_event_proc('GetFocusLensMoveMaxPosition'), I get -3200 or 3200 returned and the lens doesn't move. I'm in MF mode.

I was expecting to see the lens move.

Any insight? Before I press on with my testing.

Cheers

Garry

*

Offline c_joerg

  • *****
  • 1236
Re: Lens movement/focus control
« Reply #17 on: 25 / January / 2023, 11:36:02 »
I wouldn't expect a get function to move anything, even if move is in the name.
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: Lens movement/focus control
« Reply #18 on: 25 / January / 2023, 12:02:45 »
@c_joerg

Nor would I ;-)

I guess I read too much into what @reyalp was saying.

Anyway plouging on now :-)

Re: Lens movement/focus control
« Reply #19 on: 25 / January / 2023, 12:49:07 »
@reyalp

Thanks to your help I've made progress and believe I'm ready to code up a new script for focus and exposure bracketing.

All the focus bracketing is done on the image side, eg know the position where you are and how many brackets you need to take, and move the approipate number of lens steps (same every focus bracket as we are moving on the image side) until you reach infinity.

In the attached test script. you explicitly say how many you wish to take. In the real script the position you are at is the only info that is required.

Strangely in this demo script I can't seem to get the get_dofinfo giving me the focus position. It always seems to return 0.

Don't know if you have time to look over the short code to see if I've done something stupid.

Cheers

Garry

Code: [Select]
--[[
@title Focus Test
@chdk_version 1.6

#brackets = 1 "#Focus Brackets" [1 8]

Jan 2023
--]]

props=require'propcase'
capmode = require("capmode")
bi = get_buildinfo()
current_focus_mode = get_focus_mode()
if current_focus_mode ~= 1 then set_mf(1) end

set_config_value(2151,0) -- switching these two off means we are measuring distance 'from the lens': ...
set_config_value(2152,0) -- ...this is the 'best' we can do without knowing the position of the front principal plane and pupil magnification

function check_buttons_etc() -- only used for manually testing
    wait_click(50) -- check for a button press
    do
        if is_key("up") and get_alt_mode() then
            print("Just testing")
            pos=call_event_proc('GetFocusLensCurrentPosition')
            print("Pos="..pos)
        elseif is_key("down") and get_alt_mode() then
            error('Test Ended')
        elseif is_key("left") and get_alt_mode() then -- move to MFD
            repeat
                test = call_event_proc('GetFocusLensCurrentPosition')
                qq=call_event_proc('MoveFocusLensWithPosition',-100,0,0)
                sleep(10)
            until test == call_event_proc('GetFocusLensCurrentPosition')
        elseif is_key("right") and get_alt_mode() then -- move to infinity
            repeat
                test = call_event_proc('GetFocusLensCurrentPosition')
                qq=call_event_proc('MoveFocusLensWithPosition',100,0,0)
                sleep(10)
            until test == call_event_proc('GetFocusLensCurrentPosition')
        elseif is_key("display") and get_alt_mode() then
            del = 100
            qq=call_event_proc('MoveFocusLensWithPosition',del,0,0)
        end
    end
end

function calibrate_focus()
    -- move to infinity
    repeat
        test = call_event_proc('GetFocusLensCurrentPosition')
        qq=call_event_proc('MoveFocusLensWithPosition',100,0,0)
        sleep(10)
    until test == call_event_proc('GetFocusLensCurrentPosition')
    max = test

    -- now move to MFD
    repeat
        test = call_event_proc('GetFocusLensCurrentPosition')
        qq=call_event_proc('MoveFocusLensWithPosition',-100,0,0)
        sleep(10)
    until test == call_event_proc('GetFocusLensCurrentPosition')
    min = test
   
        dof = get_dofinfo()
        mfd = dof.focus

   
end

-- Main Section

if call_event_proc('Mecha.Create') == -1 then
if call_event_proc('MechaRegisterEventProcedure')  == -1 then
error('Mecha.Create / MechaRegisterEventProcedure failed')
end
end

calibrate_focus() -- ending up at MFD
print("infinity position = "..max)
print("MFD positon = "..min)
print("MFD(mm)="..mfd) -- seems to always be zero! Strange :-(

finish = false
repeat
    throw = max - min -- = total lens throw
    del = throw/brackets
    qq=call_event_proc('MoveFocusLensWithPosition',del,0,0) -- move towards infinity
    qq = call_event_proc('GetFocusLensCurrentPosition')
    print("Now at position "..qq)
    -- take a snap here, but pause for now
    sleep(1000)
until call_event_proc('GetFocusLensCurrentPosition') >= max



 

Related Topics