Timing problems with "shoot_full_only" - page 3 - General Discussion and Assistance - CHDK Forum

Timing problems with "shoot_full_only"

  • 34 Replies
  • 13144 Views
*

Offline philmoz

  • *****
  • 3450
    • Photos
Re: Timing problems with "shoot_full_only"
« Reply #20 on: 08 / December / 2012, 04:29:34 »
Advertisements
Code: (C) [Select]
// for press,release and click
static int luaCB_keyfunc( lua_State* L )
{
  raw_set_shot_wait(); //clears shot ready flag to 0 - polled by get_shot_ready()
  void* func = lua_touserdata( L, lua_upvalueindex(1) );
  ((void(*)(long))func)( lua_get_key_arg( L, 1 ) );
  return lua_yield( L, 0 );
}
//below is in raw.c
void raw_set_shot_wait() //called when shoot_full or shoot_full_only is clicked or pressed
{
  shot_ready=0;
}
Just adding one call  in luascript.c solved the timing problem without adding another lua function. I realized I don't even have to know anything about the key, or if it was pressed, released, or clicked. As long as pressing shoot_full_only clears the shot_ready flag, it will work.

I could put the shoot_full_only flag itself in raw.h and save the space and time overhead of defining and calling a function in raw.c. The function call would become:  shot_ready=0  Would this be acceptable, and preferable?

I have the new test time lapse video, and a discussion of the new metering method in the other topic here:
http://chdk.setepontos.com/index.php?topic=8997.new#new

A couple of suggestions.

I would change the variable name and value meaning so that 0 is the normal (non-shooting) mode, and 1 is the 'waiting for shot to complete' state.

Put the variable in raw.c as a static and use functions to set/clear/test it. There's already too may global variables so I prefer to use an interface (even a simple one) rather than create more.

Set the variable in both the action_push_click and action_push_press routines (action_stack.c) not in the lua function. Test the 'key' value is either KEY_SHOOT_FULL or KEY_SHOOT_FULL_ONLY and only set the variable if it is one of these.
This avoids the problem where if someone releases shoot_full_only before testing that the variable had been tested in the script; but after the shot had been taken (and the variable reset), then the test loop would never exit. It also allows other keys to be pressed while waiting for the variable to be cleared.
This means it will also work for ubasic as well as Lua.

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)
  g7x2 (1.01a, 1.01b, 1.10b)

*

Offline lapser

  • *****
  • 1093
Re: Timing problems with "shoot_full_only"
« Reply #21 on: 08 / December / 2012, 13:44:26 »
Set the variable in both the action_push_click and action_push_press routines (action_stack.c) not in the lua function. Test the 'key' value is either KEY_SHOOT_FULL or KEY_SHOOT_FULL_ONLY and only set the variable if it is one of these.
Thanks! That would be much better.
I think I have an easier solution though. I can reset the shot_ready flag to false whenever get_shot_ready() returns true. That is, it will only return true once per shot.
Code: (C) [Select]
volatile static int shot_ready=0;
int get_shot_ready()
{
  int iret=shot_ready;
  shot_ready=0;
  return iret;
}
I had tried this before, but it would never return true sometimes. I think the reason was that shot_ready was set to 1 in a different thread.  I think what was happening was this:

Code: (xml) [Select]
iret=shot_ready; //iret=0 in thread 1
shot_ready=1; //in thread 2
shot_ready=0;//thread 1
return iret; //return 0 thread 1 (Missed it!!)
Making shot_ready volatile may have helped, but I'm still not sure it's totally thread safe. Do you think it would be? Is there a way to block other threads from running to prevent this (synchronized blocks)?

I can try having thread 2 increment a shot counter and have thread 1 return the value of the counter to Lua. This sounds a lot like get_exp_count(), but my counter would increment in raw.c right after build_shot_histogram.  get_exp_count() increments in yet another thread, sometimes before build_shot_histogram, and sometimes after. There's a test in capt_seq.c to wait for get_exp_count() if raw file saving is enabled, to get the right raw file name. The comments note that doing this all the time would slow up burst mode.

So the new function would be:   get_shot_count().

Code: (lua) [Select]
nshot=get_shot_count()
press("shoot_full_only")
repeat sleep(50)until nshot~=get_shot_count()
This is the same code I was using with get_exp_count() that didn't work when get_exposure_cnt() changed before the histogram was ready. It requires storing get_shot_count() before pressing _shoot_full_only, which even has the advantage of telling you if more than 1 shot went by for some reason.

Quote
Put the variable in raw.c as a static and use functions to set/clear/test it. There's already too may global variables so I prefer to use an interface (even a simple one) rather than create more.
I think I'm a little confused about the meaning of "static" in C. All of the variables in shot_histogram.c that are outside of a function are declared without the qualifier, "static". Variables and functions that need to be referenced in other source files are contained in shot_histogram.h.

Some people seem to put "extern" in front of everything in the ".h" files, and some don't. Isn't "extern" the default if a variable is defined outside a function? And variables names that aren't included in a ".h" file won't be visible to other source files, will they?

I guess I don't see the difference between a static variable and a variable that's not included in an h file. Can you help? Thanks. 
« Last Edit: 08 / December / 2012, 14:30:13 by lapser »
EOS-M3_120f / SX50_100b / SX260_101a / G1X_100g / D20_100b
https://www.youtube.com/user/DrLapser/videos

*

Offline lapser

  • *****
  • 1093
Re: Timing problems with "shoot_full_only"
« Reply #22 on: 08 / December / 2012, 13:55:52 »
Actually, I just want to set a flag when Lua calls for a press or click of shoot_full_only. I've tracked it down to luascript.c here:
Why on earth would you want to do that???
Translation: "Your'e an idiot."
Response: If nobody calls me an idiot, I haven't discovered something significant. However, 99% of the time, I'm an idiot.
Quote
edit:
If you can give a general description of what you are trying to accomplish and how you would use this flag to do it, we may be able to suggest better approaches.
Translation: "Well, there's always that 1% . . ."
Response: Actually, there IS a better way to do it.
Tanslation: I'm an idiot.

Anyway, thanks for the help. Feel free to call me an idiot in the future. You'll probably be right, and it will help.
EOS-M3_120f / SX50_100b / SX260_101a / G1X_100g / D20_100b
https://www.youtube.com/user/DrLapser/videos

*

Offline lapser

  • *****
  • 1093
Re: Timing problems with "shoot_full_only"
« Reply #23 on: 08 / December / 2012, 16:21:20 »
I know I've said this before, but I think I've got it now.
Code: [Select]
//in raw.c
static int shot_count=0; //doesn't need to be volatile

int raw_get_shot_count() // called from Lua
{
  return shot_count;
}
    //in raw_save_file()
    if (state_kbd_script_run && shot_histogram_isenabled()) build_shot_histogram(); //unchanged
    shot_count++; //updated only in this thread, so should be safe.
========================
--in Lua script
  nshot=get_shot_count()
  press("shoot_full_only")
  repeat
    sleeper(10)
  until get_shot_count()~=nshot -- waits for build_histogram
  release("shoot_full_only")
This method never requires a reset, and is thread safe because the common variable is only changed in one thread. The script (keyboard?) thread (or task) only reads the variable.

I timed it at 0.9 seconds per picture (1/25th second exposure time) with this method and no extra delay between shots (1/25 sec shutter).

EOS-M3_120f / SX50_100b / SX260_101a / G1X_100g / D20_100b
https://www.youtube.com/user/DrLapser/videos


*

Offline reyalp

  • ******
  • 14080
Re: Timing problems with "shoot_full_only"
« Reply #24 on: 08 / December / 2012, 16:37:05 »
I know I've said this before, but I think I've got it now.
Code: [Select]
//in raw.c
static int shot_count=0; //doesn't need to be volatile

int raw_get_shot_count() // called from Lua
{
  return shot_count;
}
    //in raw_save_file()
    if (state_kbd_script_run && shot_histogram_isenabled()) build_shot_histogram(); //unchanged
    shot_count++; //updated only in this thread, so should be safe.
========================
--in Lua script
  nshot=get_shot_count()
  press("shoot_full_only")
  repeat
    sleeper(10)
  until get_shot_count()~=nshot -- waits for build_histogram
  release("shoot_full_only")
This method never requires a reset, and is thread safe because the common variable is only changed in one thread. The script (keyboard?) thread (or task) only reads the variable.

I timed it at 0.9 seconds per picture (1/25th second exposure time) with this method and no extra delay between shots (1/25 sec shutter).
Yes. This looks like a much safer, simpler and more general solution.

Quote
Translation: "Your'e an idiot."
No just working on complicated, unfamiliar stuff.
Don't forget what the H stands for.

*

Offline reyalp

  • ******
  • 14080
Re: Timing problems with "shoot_full_only"
« Reply #25 on: 08 / December / 2012, 17:44:05 »
I think I'm a little confused about the meaning of "static" in C.
http://en.wikipedia.org/wiki/External_variable and articles in the "see also" section may help. Please don't take this as an "OMG RTFM!" kind of way, it's just a more complete explanation than I can give in a quick forum post.

C has some implicit behavior that makes this stuff a bit confusing.

A quick overview, for variables at the file level (not in a function):
* static creates a variable that is visible only in the file where it appears. Unless you specifically need to share the global with other files, you should use this. If you have multiple statics with the same name in different files, they will be different variables.
* everything else is global by default.
* extern just declares that a global is defined elsewhere, however, it is possible to use a global without declaring it (you'll get warning but it will still work). extern on function prototypes is meaningless, even though you see it all over the chdk code.
* if the same global appears in multiple files without extern, the compiler and linker will try to sort it out (effectively making it one variable), and complain if the definitions contradict. Not recommended.
* header files have no semantic effect. The contents of the header is simply inserted where the #include directive appears. If a declaration appears in a header, it is exactly equivalent to copy/pasting it into every file where it appears.

volatile is almost never the correct answer. It just tells the compiler to load it from memory every time it is accessed rather than letting it sit around in a register. This doesn't make it thread safe, although it may narrow the window where bad things can happen. A function call has the same effect, since the compiler doesn't know if a function modified a global. The main legitimate use of volatile is for twiddling MMIO addressable hardware like LEDs.
Don't forget what the H stands for.

*

Offline lapser

  • *****
  • 1093
Re: Timing problems with "shoot_full_only"
« Reply #26 on: 08 / December / 2012, 18:26:43 »
@reyalp,

Thanks for all the good info. I love reading manuals, especially if there's a link to it! I had looked through Wikipedia a bit on static variables and such.  I also found this reference, which makes things more clear:

http://publications.gbdirect.co.uk/c_book/chapter4/linkage.html

Thanks for taking the time to write out that explanation. It's very helpful.
EOS-M3_120f / SX50_100b / SX260_101a / G1X_100g / D20_100b
https://www.youtube.com/user/DrLapser/videos

*

Offline philmoz

  • *****
  • 3450
    • Photos
Re: Timing problems with "shoot_full_only"
« Reply #27 on: 08 / December / 2012, 18:52:05 »
I know I've said this before, but I think I've got it now.
Code: [Select]
//in raw.c
static int shot_count=0; //doesn't need to be volatile

int raw_get_shot_count() // called from Lua
{
  return shot_count;
}
    //in raw_save_file()
    if (state_kbd_script_run && shot_histogram_isenabled()) build_shot_histogram(); //unchanged
    shot_count++; //updated only in this thread, so should be safe.
========================
--in Lua script
  nshot=get_shot_count()
  press("shoot_full_only")
  repeat
    sleeper(10)
  until get_shot_count()~=nshot -- waits for build_histogram
  release("shoot_full_only")
This method never requires a reset, and is thread safe because the common variable is only changed in one thread. The script (keyboard?) thread (or task) only reads the variable.

I timed it at 0.9 seconds per picture (1/25th second exposure time) with this method and no extra delay between shots (1/25 sec shutter).



Looks ok. My only concern is that the 'get_shot_count' name might confuse people in future, that it is somehow related to the total number of images taken by the camera, not just the number since last startup.

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)
  g7x2 (1.01a, 1.01b, 1.10b)


*

Offline reyalp

  • ******
  • 14080
Re: Timing problems with "shoot_full_only"
« Reply #28 on: 08 / December / 2012, 20:48:29 »
Looks ok. My only concern is that the 'get_shot_count' name might confuse people in future, that it is somehow related to the total number of images taken by the camera, not just the number since last startup.
Agreed, not sure what it should be called, something like shot_hook_count (was going to say raw_hook_count but that sort of implies it is related to raw)?

Alternately, I suppose it could be initialized from an actual shot count at startup. That would invite inconsistency though because the file counter is also used for movies and resets in some situations.
Don't forget what the H stands for.

*

Offline lapser

  • *****
  • 1093
Re: Timing problems with "shoot_full_only"
« Reply #29 on: 08 / December / 2012, 20:51:14 »
Looks ok. My only concern is that the 'get_shot_count' name might confuse people in future, that it is somehow related to the total number of images taken by the camera, not just the number since last startup.
How about:
get_shot_counter()
get_raw_ready()
get_raw_count()
or my wife's name for it:
get_up_already()
« Last Edit: 08 / December / 2012, 20:57:02 by lapser »
EOS-M3_120f / SX50_100b / SX260_101a / G1X_100g / D20_100b
https://www.youtube.com/user/DrLapser/videos

 

Related Topics