Lua access/control of certain ML functionality

Started by garry23, February 09, 2018, 12:55:48 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

garry23

@a1ex or anyone

I'm about to start a new scripting project and wish to do a few things.

First I wish to trigger advanced bracketing from the script. At the moment advanced bracketing can't be explicitly triggered from a script, as far as I know.

Second, I wish to wait until the bracketing has finished and detect this, so I can change the bracketing parameters and, in the script, start another sequence.

Thirdly, when each sequence finishes, and is detected by Lua, eg a wait state looking for bracketing to stop, I ideally would like to know the camera setting at the end condition, eg shutter speed, aperture and ISO.

Am I too far off piste?

Cheers

Garry

a1ex

That's best done with scripting around the menu API.

There is a function to wait until a photo capture is done (camera.wait()), but for some reason it's not in the API docs; will check later to find out why. Triggering should work by taking the first picture (not tested).

garry23

@a1ex

Thanks, I'll do some scripting tests.

Cheers

Garry

garry23

@a1ex

Started playing around with some basic functionality testing around a script running the advanced bracketing twice, but with different settings.

In this test script, all I'm doing is explicitly running the advanced bracketing, via two camera.shoot() calls.

I have set advanced bracketing to 3x3Ev with ISO shifting.

My base exposure is at ISO 100.

hdr_pressed = false

function sim(arg)
if hdr_pressed == true then
hdr_pressed = false
        camera.shoot()
        camera.wait()
        camera.shoot()
return false
else
return true
end
end

function test4key(key)
    if key == KEY.MENU then
hdr_pressed = true
return false
else
return true
end
end

event.keypress = test4key
event.shoot_task = sim


What seems to happen is the first image is captured in the first bracket call, then the next camera.shoot() trigger seems to take the correct 3x3Ev bracket set.

Any ideas why the camera.wait doesn'r appear to pause between the two camera.shoot() calls.

a1ex

Reproduced - it comes from PROP_LAST_JOB_STATE, whose values are model-specific; I only know for sure that 0 means idle and anything non-zero means the photo capture side is busy in some way (even if it's just saving the last picture to card, which may take several seconds after the camera is ready to take a second picture). I don't really know a good way to tell when the camera is ready to change settings and accept a second picture - current bracketing code uses some heuristics that were just tweaked over the years until they seemed to work. Solving this in a cross-platform way requires some investigation (and the hardest part - detailed feedback from owners of many other camera models, to avoid breaking the still photo features on models I could not test).

My test script (minimal example, not working):

-- Bracketing test
menu.set("Shoot", "Advanced Bracket", 1)
menu.set("Advanced Bracket", "Frames", 2)
menu.set("Advanced Bracket", "Sequence", "0 + ++")
camera.shoot()
camera.wait()
menu.set("Advanced Bracket", "Sequence", "0 - --")
camera.shoot()
camera.wait()
menu.set("Shoot", "Advanced Bracket", 0)


At least, camera.wait() does wait until the card LED turns off.

garry23

I've tried various attempts at pausing the script between the two bracketing sequences, but no luck so far.

For example task.yield for a few seconds.

But no luck, at least 'just' using Lua.

I'll keep thinking about Lua scripting work around  ;)

a1ex

Found out PROP_LAST_JOB_STATE also gets triggered quite late in the capture process (actually somewhere in the middle - in our case, that may happen after shoot() returns). That means, even if its values were the same on all models, this property is not enough to tell whether an image capture is in progress or not, and I also have some ideas how to fix it (at least for Lua).

A bit of a mystery: the image capture process starts here:


8150F> ShootCaptu:ff086fc8:93:03: scsReleaseOn
815DC>   MainCtrl:00ca908c:00:00: *** _prop_request_change(0x80050025, 0x330c, 0x4), from ff0824f8


but I'm unable to get any events with PROP_HANDLER(0x80050025)...

Anyway, the issue was a race condition between Lua and ML bracketing code. Pushed a fix; not fully happy with it, but at least it's a start - the above script works unmodified.

Without the call to wait(), shoot() returns too early (after taking the first picture in the set); this results in the Sequence parameter being changed in the middle of the first bracket; otherwise, the backend seems to be able to handle it. Need to do some serious refactoring to ensure thread safety.

garry23

@a1ex

Thanks for looking into this.

I spent the evening working out a hack in Lua, but it's very messy :-(

I'll carry on with my line, and hope your more proper fix pans out.

Cheers

Garry

garry23

@a1ex

I see there is a Lua Fix on the experimental, and have looked at it with my 5D3.

I think (?) you have pushed a possible fix for the camera.wait, but the following still only takes the first image in the first bracket request triggered by camera.shoot

camera.shoot()
camera.wait()
camera.shoot()


Should I be calling camera.wait differently?

Cheers

Garry

a1ex

This one takes 2 brackets here; however, I can imagine some race condition with very fast cards (I've only tested on a SD card).

You could also try:

camera.shoot()
msleep(1000) -- to make sure the bracketing sequence actually started
camera.wait() -- to wait for the bracketing sequence to finish


Will try to reproduce on the fast card; if I won't be able to, I'll ask you for your initial bracketing settings (exposure and ML settings).

garry23

@a1ex

I did try that myself and no matter what delay, the first bracket set only seems to take the first image. The second bracket set goes OK.

BTW here is my full test script:

hdr_pressed = false

function sim(arg)
if hdr_pressed == true then
hdr_pressed = false
camera.shoot()
msleep(1000)  -- have tried different delays here, but it only seems to take one image
camera.wait()
camera.shoot()
return false
else
return true
end
end

function test4key(key)
    if key == KEY.MENU then
hdr_pressed = true
return false
else
return true
end
end

event.keypress = test4key
event.shoot_task = sim


As for setting, 1/30,ISO 100 and ML pretty much neutral.

garry23

@a1ex

Just thought I'd keep you in the loop regarding my Lua experiments.

The script will, when finished, intelligently take an 'optimised' hand held bracket set from any initial state.

The algorithm will be based on a two pass advanced bracketing schema.

The first pass, from the highlight exposure, eg ETTRed exposure, will undertake a 3x3Ev ISO shifted bracket, ie from the base ISO position to, say, ISO 6400.

The second pass will then work out additional brackets, for example from the slowest shutter set.

This test script simply sets the first pass shutter at 1/125 and the second at 1/30, ie as a proof of principle.

Using this approach, I don't need to use camera.wait, which I'm struggling with at the moment.

Here's the code

[code]hdr_pressed = false
second_pass = false

function HH_bracket(arg)
if hdr_pressed == true or second_pass then
if hdr_pressed == true then -- first pass with fast shutter
camera.shutter.value = 1/125
camera.iso.value = 100
msleep(1000)
menu.set("Advanced Bracket", "Frames", 3) -- take three ISO frames
        camera.shoot()
second_pass = true
hdr_pressed = false
return false
end

if second_pass then -- second pass with slowest shutter
camera.shutter.value = 1/30
camera.iso.value = 100
menu.set("Advanced Bracket", "Frames", 2) -- take two ISO frames
camera.shoot()
beep()
second_pass = false
return false
end

else
return true
end
end

function test4key(key)
    if key == KEY.MENU then
hdr_pressed = true
return false
else
return true
end
end

event.keypress = test4key
event.shoot_task = HH_bracket



[/code]