Improvements to press, click, release for shooting keys - General Discussion and Assistance - CHDK Forum

Improvements to press, click, release for shooting keys

  • 48 Replies
  • 8069 Views
*

Offline lapser

  • *****
  • 1093
Improvements to press, click, release for shooting keys
« on: 27 / December / 2012, 15:20:52 »
Advertisements
The attached diff file patches action_stack.c to improve the function of the shooting keys:
"shoot_full", "shoot_full_only", and "shoot_half".

press("shoot_full") and press("shoot_half") now wait for get_shooting() to be true after pressing the key.

press("shoot_full") and press("shoot_full_only") now wait for the shutter to open after pressing the key.

release("shoot_full") and release("shoot_half") now wait for get_shooting() to be false after releasing the key.

click(...) skips the now unnecessary delay between press and release for these 3 keys.

shoot() is now the same as click("shoot_full") but waits for get_flash_ready()
  However, on my camera, it appears that when the flash is active, get_shooting() already does this, so the
  shoot() command can be replaced by click("shoot_full").

I also think I found the cause of the infamous "shoot bug" that causes a script to stop when calling shoot() repeatedly. The current shoot() contains these statements:
-        action_push_release(KEY_SHOOT_FULL);
-        action_push_press(KEY_SHOOT_FULL);
This is equivalent to "click" but without the click delay. So on some cameras, the press may not be recognized, and the camera will enter an infinite loop waiting for get_shooting(). If this is the problem, it is fixed with the attached changes. You could also just replace the push/release statements above with:
action_push_click(KEY_SHOOT_FULL);

But the new changes are a major improvement to shooting with a script. They eliminate the need for all the loops that test for get_shooting(). They also work with review mode on. Here's some examples of how to write a script with the changes:

Code: (lua) [Select]
--[[
@title New Click Test
--]]

--this is equivalent to shoot(), but without the flash ready check
--please try it on your camera with the flash on and see if it waits for flash ready
repeat
  click("shoot_full")
until false

--This shoots pictures much faster, but without focusing and metering between shots.
--I think this is as fast as the camera can shoot pictures in single shot drive mode.
press("shoot_half")
repeat
  click("shoot_full_only")
until false;

--this still works, but without the suspected bug
repeat
  shoot()
until false
This shouldn't break any old scripts, although a script that does something in the get_shooting() wait loops, like checking for key presses, or turning the backlight off repeatedly, might not respond as fast.

The attached diff file was made with CHDK shell source tools on trunk 2406 version 1.2. If you patch this trunk and then re-diff it with TortoiseSVN, it will probably work better with other trunks/branches. Try it with any 1.2 trunk, though, and it will probably work.  Eventually, I'll get around to instaling TortoiseSVN :-[

Many thanks to philmoz and reyalp for helping me understand action_stack.c
===========
[EDIT2] attached diff file updated to add video mode test to new wait functions
[EDIT3] new diff file adds wait for shutter open after press("shoot_full_only") without modifying any other key functions. Test added so unsupported cameras do fixed wait like before.
« Last Edit: 28 / December / 2012, 22:27:47 by lapser »
EOS-M3_120f / SX50_100b / SX260_101a / G1X_100g / D20_100b
https://www.youtube.com/user/DrLapser/videos

Re: Improvements to press, click, release for shooting keys
« Reply #1 on: 27 / December / 2012, 23:43:31 »
Not sure how anyone else feels, but I'd be nervous about adding any "wait_for_something_to_happen()" code to the click & press scripting functions.  They should do what they say (simulated the press of a camera button) and no more.   

Having said that,  I'd be okay with updating shoot() to do a better job of waiting.

Thanks for all the work on this lapser.   I'm sure the group will come up with the best ways to integrate this after some discussion.

Ported :   A1200    SD940   G10    Powershot N    G16

*

Offline reyalp

  • ******
  • 12074
Re: Improvements to press, click, release for shooting keys
« Reply #2 on: 28 / December / 2012, 00:00:30 »
The attached diff file patches action_stack.c to improve the function of the shooting keys:
"shoot_full", "shoot_full_only", and "shoot_half".

press("shoot_full") and press("shoot_half") now wait for get_shooting() to be true after pressing the key.
Agree with waterwingz, this strikes me as the wrong approach. They are key press functions that happen to control shooting related buttons, not shooting functions. Pressing shoot does not always shoot, it could start or stop video recording, or switch from play to rec mode. If those wait for get_shooting(), you will hang the kbd_task (you could make special case, but that's still adding complexity and making them no longer simple keyboard functions)

Furthermore, it is not always desirable that they wait, and waiting in script is quite trivial. In lua, you can easily make functions that wait, so it doesn't have to clutter up the code. Saving a few lines in script files is not a valid reason to add special behavior to the core code. It would also break existing scripts that already wait. I'm not averse to breaking compatibility when there is a compelling reason, but I don't see it in this case.

If shoot() is broken or needs additional functionality, fix it or add another function that does the "right" thing.

Quote
current shoot() contains these statements:
-        action_push_release(KEY_SHOOT_FULL);
-        action_push_press(KEY_SHOOT_FULL);
This is equivalent to "click" but without the click delay. So on some cameras, the press may not be recognized, and the camera will enter an infinite loop waiting for get_shooting().
There is an inherent delay, because only one action stack item is processed per kbd_task iteration. If that delay isn't enough and shoot is broken on some camera, that should be addressed on those specific cameras.
Don't forget what the H stands for.

*

Offline lapser

  • *****
  • 1093
Re: Improvements to press, click, release for shooting keys
« Reply #3 on: 28 / December / 2012, 02:18:42 »
Agree with waterwingz, this strikes me as the wrong approach. They are key press functions that happen to control shooting related buttons, not shooting functions. Pressing shoot does not always shoot, it could start or stop video recording, or switch from play to rec mode. If those wait for get_shooting(), you will hang the kbd_task (you could make special case, but that's still adding complexity and making them no longer simple keyboard functions)
That's a good point that "shoot_full" in video mode doesn't take a photo. There's already a test for that:
case AS_WAIT_SHOOTING_IN_PROGRESS:
        if (shooting_in_progress() || MODE_IS_VIDEO(mode_get()))
        {
            action_pop();
        }
        break; 
I can add a check for video mode to my changes that will fix this problem.

[EDIT] Also, with AS_WAIT_SHOOTING_IN_PROGRESS, you hang the script but not the keyboard task if it never becomes true. You can still exit the script by physically pressing the shutter.
Quote
Furthermore, it is not always desirable that they wait, and waiting in script is quite trivial. In lua, you can easily make functions that wait, so it doesn't have to clutter up the code. Saving a few lines in script files is not a valid reason to add special behavior to the core code. It would also break existing scripts that already wait. I'm not averse to breaking compatibility when there is a compelling reason, but I don't see it in this case.
Actually, it doesn't break scripts that have a wait loop. The wait just ends immediately. I used the new press, click, release functions tonight with my old time lapse script and it worked fine. I have a check during the wait loop to toggle the backlight, but even that still works, even though it only checks once.
Quote
If shoot() is broken or needs additional functionality, fix it or add another function that does the "right" thing.
...
There is an inherent delay, because only one action stack item is processed per kbd_task iteration. If that delay isn't enough and shoot is broken on some camera, that should be addressed on those specific cameras.
Actually, the amount of click delay isn't the problem. The camera has to be ready to accept "shoot_full" or "shoot_full_only" to trigger a shot with a click. After get_shooting() goes false, the camera is almost always ready for another click("shoot_full"). But under rare conditions, possibly a file save that requires a new directory, or memory full issues, the camera might not be ready and the click can be missed. I think this is the cause of the shoot bug.

The only reliable way to trigger a shot I've found is to press("shoot_full" or "shoot_full_only"), and wait for the shot to start. I discovered that right before the shutter opens, "shutter_open_tick_count" is updated. I added AS_WAIT_SHUTTER to wait for this. With this method, click("shoot_full_only") in half_shoot works every time(see my script example). This allows a much higher shot rate than was possible before.

You can switch to record mode with press("shoot_half"), as you suggest. But you want to wait for get_shooting(), (if not in video mode), to know when you actually are in record mode, don't you?

Simplifying scripts isn't the major reason for these changes, but I don't think it's a trivial accomplishment. Reducing script code and moving it to C code saves memory and speeds execution. It also makes script writing easier to learn. click("shoot_full" and "shoot_full_only") should take a shot as quickly as possible every time, not require a lot of extra code and delays to get it to work most of the time.

Moving the wait loop to C can give a significant improvement in how fast the shot is taken. I've been doing some timing experiments as part of my shot histogram research. When the histogram is ready, the C code sets a flag. The lua script is in a sleep(10) loop waiting for that flag. When the flag changes, the Lua script does its thing and resets the flag, signalling the C code to take another shot. The script usually can keep up with the C code, but sometimes the script gets hung up for over 1 second, for no apparent reason. So there can be significant performance improvements from reducing Lua code.
=====
How about if I update the diff file to handle video mode correctly, and then you see if you can get it to mess up or behave differently than the old code? My cameras have a separate video button, so shoot always shoots a picture for me. I'll post the new diff with an EDIT note in the first message.

Thanks for all your help.
« Last Edit: 28 / December / 2012, 02:25:41 by lapser »
EOS-M3_120f / SX50_100b / SX260_101a / G1X_100g / D20_100b
https://www.youtube.com/user/DrLapser/videos


*

Offline philmoz

  • *****
  • 3123
    • Photos
Re: Improvements to press, click, release for shooting keys
« Reply #4 on: 28 / December / 2012, 03:10:06 »
The main problem with a change like this is it's impossible to test across every camera.

For example there are 4 capt_seq.c files that don't call capt_seq_hook_set_nr and 6 where the call is commented out. So for at least 10 cameras your AS_WAIT_SHUTTER code will never exit and the action_stack will hang.

I'm also not sure what 'shoot' bug you are referring to; but it's not possible for a script to hang waiting 'get_shooting' to go to 0 after calling 'shoot'. Once the SHOOT_FULL is released the camera will always set the PROPCASE_SHOOTING value back to 0 (if it wasn't already).

Phil.
CHDK ports:
  sx30is (1.00c, 1.00h, 1.00l, 1.00n & 1.00p)
  g12 (1.00c, 1.00e, 1.00f & 1.00g)
  sx130is (1.01d & 1.01f)
  ixus310hs (1.00a & 1.01a)
  sx40hs (1.00d, 1.00g & 1.00i)
  g1x (1.00e, 1.00f & 1.00g)
  g5x (1.00c, 1.01a, 1.01b)

*

Offline lapser

  • *****
  • 1093
Re: Improvements to press, click, release for shooting keys
« Reply #5 on: 28 / December / 2012, 03:33:53 »
The main problem with a change like this is it's impossible to test across every camera.
For example there are 4 capt_seq.c files that don't call capt_seq_hook_set_nr and 6 where the call is commented out. So for at least 10 cameras your AS_WAIT_SHUTTER code will never exit and the action_stack will hang.
Thanks Phil. That's a real problem. Is there a way to test for those 10 cameras? Maybe you could add a compile time flag? Presumably, they wouldn't be able to create standard DNG raw files without the shutter open time, would they?

One reliable way to make sure it didn't mess up anything would be to add a script call that activates the changes. Without the call, it would work the old way. Does that sound acceptable?

[EDIT]Another way around this problem would be to also increment a file counter in raw_save_file(), and finish AS_WAIT if this flag changes, as a back-up. I've already tested this flag with my time lapse routines. It takes about 1/4 second from shutter open to raw_save_file() on my sx260 (plus shutter time for long exposures).

Or isn't there another camera hook that is activated after a "shoot_full" or "shoot_full_only", but before the shutter opens? I just need to wait until the key press starts the camera before releasing the key.

I agree a change this basic has to work with every old camera and old script. I still think it's possible, with everyone's help.
Quote
I'm also not sure what 'shoot' bug you are referring to; but it's not possible for a script to hang waiting 'get_shooting' to go to 0 after calling 'shoot'. Once the SHOOT_FULL is released the camera will always set the PROPCASE_SHOOTING value back to 0 (if it wasn't already).
Actually, I think the problem may be that the press/release("shoot_full") part of shoot() may not be recognized if the camera is really busy for some rare reason. The camera would hang waiting for get_shooting() to go to 1.

I have the new diff file with the video mode tests ready here:
http://chdk.setepontos.com/index.php?topic=9172.msg94847#msg94847
« Last Edit: 28 / December / 2012, 03:58:32 by lapser »
EOS-M3_120f / SX50_100b / SX260_101a / G1X_100g / D20_100b
https://www.youtube.com/user/DrLapser/videos

*

Offline lapser

  • *****
  • 1093
Re: Improvements to press, click, release for shooting keys
« Reply #6 on: 28 / December / 2012, 12:03:02 »
OK, the bottom line here is that you have  shoot functions that don't shoot a picture. click("shoot_full") is pretty worthless, as is, because it doesn't work without press("half_shoot") first. Pressing any of the 3 buttons all require inefficient wait loops in the script. Even releasing a button requires a script wait loop to make sure you're ready for the next press.

Also, "shoot_full_only", which holds "half_shoot", has no way of knowing when the camera is ready for it, and doesn't take a picture if you go too fast. And shooting rapid shots is its main purpose.

As for the shoot() bug, I'm not really sure missing the click("shoot_fulll")  is the problem. I'm discovering that Lua is too slow to keep up with rapid shots (in continuous mode). I've had Lua crashes on the sx260 (not on the G1X yet), after 2,000 rapid shots that I haven't figured out. That could be related to the shoot() bug.

So the solution for taking shots as rapidly as possible is to use continuous mode and keep the script out of the shoot loop. The only thing I need to do that is press("shoot_full") once.

So if your "shoot_full" and "shoot_full only" buttons won't go out with me, I don't care. They're ugly anyway. :P
All seriousness aside, though, they'd look great with a new hairdo and some makeup.
EOS-M3_120f / SX50_100b / SX260_101a / G1X_100g / D20_100b
https://www.youtube.com/user/DrLapser/videos

Re: Improvements to press, click, release for shooting keys
« Reply #7 on: 28 / December / 2012, 12:12:26 »
OK, the bottom line here is that you have  shoot functions that don't shoot a picture.
Correct.  All they do is simulate a button press.  Which is all that they are supposed to do.  That allows the script writer to determine what else is supposed to happen or be checked.

Quote
click("shoot_full") is pretty worthless, as is, because it doesn't work without press("half_shoot") first. Pressing any of the 3 buttons all require inefficient wait loops in the script. Even releasing a button requires a script wait loop to make sure you're ready for the next press. Also, "shoot_full_only", which holds "half_shoot", has no way of knowing when the camera is ready for it, and doesn't take a picture if you go too fast. And shooting rapid shots is its main purpose.
All true.  And that's the kind of function that a script writer would normally want.  You can't anticipate what someone is going to do. The more you build into a function like this - the less flexible it becomes.

Probably a better approach is some new shooting functions that do all the great things you have discovered rather than change the older simple building block functions ?
Ported :   A1200    SD940   G10    Powershot N    G16


*

Offline dvip

  • ****
  • 451
Re: Improvements to press, click, release for shooting keys
« Reply #8 on: 28 / December / 2012, 15:04:26 »
@lapser,
How about a new set of functions (different names) like
waterwingz says, and they can be conditionally compiled
for the sx260 where they can be tested for a while (that's
if some has the time to do this). If they work fine, then
they can be moved to other cams. The old hard coded
functions should be left as they are for legacy scripts.

I find your C functions and scripts very interesting. Thanks
for putting time on them. I hope you continue experimenting with these functions.


*

Offline lapser

  • *****
  • 1093
Re: Improvements to press, click, release for shooting keys
« Reply #9 on: 28 / December / 2012, 15:53:01 »
Probably a better approach is some new shooting functions that do all the great things you have discovered rather than change the older simple building block functions ?
Right again! That is the best solution. For some reason, I don't like to add new script functions.

However, I have to agree with reyalp that it's not worth a C function just to avoid doing a wait loop in Lua. I already use Lua functions called press_half() and release_half() that include waits. The performance boost would be minimal, and my tests show it would be negated by the over 1 second delays in Lua processing that seem to happen when shooting rapidly.

When I think of it, though, the only problem that really needs fixing is with press("shoot_full_only"), or more specifically:

action_push_press(key) //when key==KEY_SHOOT_FULL_ONLY

I think everything would work right if I save shutter_open_tick_count when you press shoot_full_only, and then wait until it changes before continuing. I can back this up with a check for raw_save_file being called, possibly with a state_shooting check if I can find one... and also a check for video mode.

shoot_full_only isn't really a button, it's the way you press a button. You can't use it by itself to stop/start video, so that shouldn't be a problem. But the change would allow this:

press_half() -- waits for get_shooting
repeat
  click("shoot_full_only")
until false

With a normal shoot, if you want to make sure the shot has started, you could do this:

press_half()
  click("shoot_full_only")
release_half()

If you don't want any waiting, just do this:

press_half()
click("shoot_full") -- does release half without wait loop afterwards

So the new proposal is to only modify press("shoot_full_only"). I'll also change shoot() so it clicks shoot_full_only instead of shoot_full. That will fix the shoot() bug, if that's what's causing it.

I love you guys. If we get this thing working together, we should apply to be judges on American Idol. I'll tell everyone it was the greatest song I've ever heard in my life.  Reyalp will tell everyone they suck. Waterwingz will say, "Yo dawg. Check it out.", and philmoz will give a true and accurate critique of how they really sang... usually agreeing with reyalp.
EOS-M3_120f / SX50_100b / SX260_101a / G1X_100g / D20_100b
https://www.youtube.com/user/DrLapser/videos

 

Related Topics