APEX96 conversion functions for script - General Discussion and Assistance - CHDK Forum supplierdeeply

APEX96 conversion functions for script

  • 7 Replies
  • 3741 Views
*

Offline reyalp

  • ******
  • 11924
APEX96 conversion functions for script
« on: 20 / January / 2013, 20:59:47 »
Advertisements
Continued from http://chdk.setepontos.com/index.php?topic=9312.msg96072#msg96072

First of all, I think this is long overdue. While pure Lua solutions are possible (and easier imath) the same functionality is desirable in ubasic, and this is really core functionality for shooting related scripts.
I don't have any issues adding this type of functionality to Lua, it's not a huge amount of new code; but I'm not keen on a single function that performs six different things based on a 'type' parameter. Having to go back to the documentation all the time to figure out which 'type' value is needed for a specific conversion is a pain.
Agreed on both counts.

For shutter speed, I'd be tempted to follow the firmware apex2us example and just use microseconds. tv96 to to msec is inappropriate, since sub-msec shutter speeds are available even in the standard firmware.

edit:
Some thought should also be given to "real" and "market" ISO.
« Last Edit: 20 / January / 2013, 21:05:22 by reyalp »
Don't forget what the H stands for.

*

Offline lapser

  • *****
  • 1093
Re: APEX96 conversion functions for script
« Reply #1 on: 21 / January / 2013, 00:31:22 »
For shutter speed, I'd be tempted to follow the firmware apex2us example and just use microseconds. tv96 to to msec is inappropriate, since sub-msec shutter speeds are available even in the standard firmware.
edit:
Some thought should also be given to "real" and "market" ISO.
OK, I'll write it up as 6 different functions. I agree that would be better as a permanent solution.

When I think about it, using microsecond shutter speed is the way to go. Good idea. The lua script can do anything it wants with the values, including formatting them as 1/T if desired. It makes the code simpler too. I always like that.

I noticed that the real ISO on the sx260 is 65 for a market of 100. Does that mean that the market ISO is always 35 plus the real ISO on this camera? The two ISO functions could have an optional extra parameter for market ISO values.

get_iso_to_sv96(int iso[, boolean market])

What do you think the function names should be?

iso_to_sv96
get_isotosv96
get_iso_sv96
get_sv96_iso

convert_iso_sv96
convert_sv96_iso
convert_iso_to_sv96

convert_tv96_microseconds
convert_usec_tv96

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

*

Offline reyalp

  • ******
  • 11924
Re: APEX96 conversion functions for script
« Reply #2 on: 21 / January / 2013, 01:44:02 »
I noticed that the real ISO on the sx260 is 65 for a market of 100. Does that mean that the market ISO is always 35 plus the real ISO on this camera?
No, not necessarily.  I posted some observations here http://chdk.setepontos.com/index.php?topic=8613.msg90280#msg90280
Quote
The two ISO functions could have an optional extra parameter for market ISO values.
I would just use separate function, if we supported both. In practice, I'm not sure we have the information to support the "market" values. We could convert  ISO to sv96_market and back, but without a way to set ISO by market value or convert to "real", it wouldn't help.  The ISO override code (which as I mentioned elsewhere, I don't fully understand...) does some conversions.

Quote
What do you think the function names should be?

iso_to_sv96
I think I prefer this style

edit:
Thinking about this more... the APEX96 <-> ISO conversion is the same for "market" and "real" so we can ignore it for the conversion functions.

If we can come up with a "market"<->"real" conversion (whether for the ISO values or APEX96 doesn't really matter) that would obviously be desirable, since people entering an "ISO" value will most likely expect it to be the same "market" values shown in the Canon UI.
« Last Edit: 21 / January / 2013, 12:27:12 by reyalp »
Don't forget what the H stands for.

*

Offline lapser

  • *****
  • 1093
Re: APEX96 conversion functions for script
« Reply #3 on: 21 / January / 2013, 15:26:25 »
I'll start with these names, then:

shutter_to_tv96
aperture_to_av96
iso_to_sv96

shooting.c uses this name:
shooting_get_tv96_from_shutter_speed(float t)

Of course, it's really shutter open TIME, not speed. I like just "shutter" so the user can call it speed or time. I also like using "..to.." instead of "get..from.." It's really a conversion, not a get, like convert_shutter_time_to_tv96. "shutter_to_tv96" is a good way to say that briefly. It reads "from-->to" like it should.

As for the microsecond thing, how do you like the idea of an optional scale parameter that defaults to 1000 for all the functions? Shutter times less than 1/2 or so are usually shown as 1/time, not decimal times. By defining a negative input time as 1/time in shutter_to_tv96, it makes it easy to enter reciprocal time values. The scale factor  also simplifies the lua scripting.

For example, to enter shutter time in seconds, you could define t as seconds and use:

tv96=shutter_to_tv96(t,1)

For 1/2 second, you could use:

tv96=shutter_to_tv96(-2,1)

Then if I define:

int convert96(x,scale,type)

all the lua functions take the form:

static int luaCB_shutter_to_tv96( lua_State* L )
{
  lua_pushnumber( L, convert96(luaL_checknumber(L,1),
    luaL_optnumber(L,2,1000), 1 )); //1 is type for shutter_to_tv96
  return 1;
}
====
I've been exploring the Market ISO complication. If I figure anything out that works, we can add another function or two. But for now, we can probably leave it to the script. CHDK just needs to supply the integer math functions that you can't do in Lua.
EOS-M3_120f / SX50_100b / SX260_101a / G1X_100g / D20_100b
https://www.youtube.com/user/DrLapser/videos


*

Offline reyalp

  • ******
  • 11924
Re: APEX96 conversion functions for script
« Reply #4 on: 21 / January / 2013, 16:12:18 »
As for the microsecond thing, how do you like the idea of an optional scale parameter that defaults to 1000 for all the functions? Shutter times less than 1/2 or so are usually shown as 1/time, not decimal times. By defining a negative input time as 1/time in shutter_to_tv96, it makes it easy to enter reciprocal time values. The scale factor  also simplifies the lua scripting.
I would prefer to keep the script interface simple as possible.

Optional parameters and special case values often seem more convenient on the surface, but if you have a function like usec_to_tv96(int usec), you know exactly what it takes every time (once you know what usec is :P). If you have shutter_to_tv96(int val_that_may_be_several_things,int scale_that_defaults_to_something), you end up having to look at the manual every time, and the underlying code is more likely to have unexpected corner cases.

If the script author wants to accept 1/x values as input, then they can make a trivial wrapper to do it

shutter_to_tv96(value)
 return usec_to_tv96(1000000/value)

This tells someone reading the script exactly what is happening, unlike shutter_to_tv96(-x,1)
 
I'm an opinionated SOB aren't I ? :(
Don't forget what the H stands for.

*

Offline philmoz

  • *****
  • 3107
    • Photos
Re: APEX96 conversion functions for script
« Reply #5 on: 21 / January / 2013, 16:59:30 »
As for the microsecond thing, how do you like the idea of an optional scale parameter that defaults to 1000 for all the functions? Shutter times less than 1/2 or so are usually shown as 1/time, not decimal times. By defining a negative input time as 1/time in shutter_to_tv96, it makes it easy to enter reciprocal time values. The scale factor  also simplifies the lua scripting.
I would prefer to keep the script interface simple as possible.

Optional parameters and special case values often seem more convenient on the surface, but if you have a function like usec_to_tv96(int usec), you know exactly what it takes every time (once you know what usec is :P). If you have shutter_to_tv96(int val_that_may_be_several_things,int scale_that_defaults_to_something), you end up having to look at the manual every time, and the underlying code is more likely to have unexpected corner cases.

If the script author wants to accept 1/x values as input, then they can make a trivial wrapper to do it

shutter_to_tv96(value)
 return usec_to_tv96(1000000/value)

This tells someone reading the script exactly what is happening, unlike shutter_to_tv96(-x,1)
 
I'm an opinionated SOB aren't I ? :(

Another alternative to consider would be:

    time_to_tv96(int numerator, int denonimator);

where the desired time value (in seconds) is expressed as a fraction.

Otherwise I would vote for usec_to_tv96(int usec) for simplicity.

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)

*

Offline lapser

  • *****
  • 1093
Re: APEX96 conversion functions for script
« Reply #6 on: 21 / January / 2013, 17:23:34 »
I would prefer to keep the script interface simple as possible.
If the script author wants to accept 1/x values as input, then they can make a trivial wrapper to do it
I'm an opinionated SOB aren't I ? :(
Me too. If we were the U.S. Congress, we would have fallen off the fiscal cliff.

I think our differences boil down to organization vs flexibility. I bet you have a neat desk and room. I have the opposite. Over-organization stifles creativity, and lack of organization blocks productivity.

I love optional parameters because they give you, well, more options. If you want to write (1000000/x) you can do it, and I can write (-1000000) to do the same thing. But you always have to write (1000000) for 1 second, and I can write (1,1). Your way still works without entering the optional scale parameter. Your scripts can be more clear if that's what you want. My scripts can be shorter and take some more effort to understand.

But all those zeros are hard for me to count, so I like 2 parameters better. Do it your way if you want, but please don't take away my options.

As for usec_to_tv96, that specifies the units but not what they refer to. Plus, I'd end up pronouncing it "usuck." I still like shutter_to_tv96.

I guess we are a lot like the U.S. Congress. Is there a CHDK Supreme Court that can decide this? Chief Justice Philmoz?
EOS-M3_120f / SX50_100b / SX260_101a / G1X_100g / D20_100b
https://www.youtube.com/user/DrLapser/videos

*

Offline lapser

  • *****
  • 1093
Re: APEX96 conversion functions for script
« Reply #7 on: 21 / January / 2013, 22:20:28 »
Here's everything all done, ready for testing. I used an optional scale, defaulting to 1000 (msec for shutter time) and aperture conversions. ISO conversions ignore the scale, although I left it in the lua function in case we want to use it for some reason.

I've also included my test lua script, which uses all the functions and options, including setting the scale to usuck, uh, usec (microseconds), or 1000000. I had ISO set to "auto" for the first part, and 100,200,400,800,1600,3200 at the end. Market values in auto seem to be off, but the convert function works properly.

I really think the optional scale factor adds a lot. Wasn't it reyalp who had the idea of adding an optional scale to get_histo_range(from, to, scale)? So I can blame him for giving me the idea in the first place. Try it. I think you'll like it.

Code: [Select]
static int luaCB_shutter_to_tv96( lua_State* L )
{
  lua_pushnumber( L, convert96(luaL_checknumber(L,1),
    luaL_optnumber(L,2,1000), 1 )); //1 is type for shutter_to_tv96
  return 1;
}

static int luaCB_tv96_to_shutter( lua_State* L )
{
  lua_pushnumber( L, convert96(luaL_checknumber(L,1),
    luaL_optnumber(L,2,1000), 2 )); //type 2
  return 1;
}

static int luaCB_iso_to_sv96( lua_State* L )
{
  lua_pushnumber( L, convert96(luaL_checknumber(L,1),
    luaL_optnumber(L,2,1), 3 )); //type 3 - scale ignored
  return 1;
}

static int luaCB_sv96_to_iso( lua_State* L )
{
  lua_pushnumber( L, convert96(luaL_checknumber(L,1),
    luaL_optnumber(L,2,1), 4 )); //type 4 - scale ignored
  return 1;
}

static int luaCB_aperture_to_av96( lua_State* L )
{
  lua_pushnumber( L, convert96(luaL_checknumber(L,1),
    luaL_optnumber(L,2,1000), 5 )); //type 5
  return 1;
}

static int luaCB_av96_to_aperture( lua_State* L )
{
  lua_pushnumber( L, convert96(luaL_checknumber(L,1),
    luaL_optnumber(L,2,1000), 6 )); //type 6
  return 1;
}

//************************************************************

static int convert96(int x, int scale, int type) //converts for lua integers
{
  switch(type)
  {
    case 1: //shutter speed (msec) to tv96
      if(x==0)break; //shutter speed 0 invalid
      double f=(double)x;
      if(x<0)f = -scale/f; //<0 means 1000/x.  example: -2000 means 1/2 sec shutter speed
      else f /=  scale; //500 means 1/2 sec also
      return (int)(-318.90509710918*log10(f)+0.5); //-96*log2(f)
    case 2: //tv96 to shutter speed(msec)
      return (int)(scale*pow(2,(((double)-x)*0.010416666666667))+0.5); //2^(-t/96)
      //if tv96<0 you can call with -tv96(positive) and print as ("1/",tv96_to_shutter(-tv))
    case 3: //iso to sv96 scale=1?
      return (int)(318.90509710918*log10(0.297301778750680*x)+0.5); // (96/log10(2))*log10(N*ISO)
    case 4: //sv96 to iso
      return (int)(pow(2,(((double)(x+168))*0.010416666666667))); //2^((x+96N)/96) N=2^(-7/4)   
    case 5: //aperture to av96
      if(x<1)break;
      return (int)(log10(((double)x)/scale)*637.810194218373+0.5); //log2(x/1000)*96
    case 6: //av96 to aperture
      return (int)(pow(2,((double)x)*0.005208333333333)*scale+0.5 ); //2^(x/192)*1000
  }
  return 0; //invalid type or input
}


Code: (lua) [Select]
--[[
@title Apex96
--]]
function seconds(tv) -- converts tv96 to time string   i.e. print(seconds(tv))
  pre=""
  if(tv>0)then
    tv=-tv
    pre="1/"
  end
  tv=tv96_to_shutter(tv) -- tv96 to msec
  ti=tv/1000 -- integer part
  ts=string.format("%s%u.%03u",pre,ti,tv%1000) -- xx.xxx or 1/xx.xxx
  if(ti>1)then -- truncate digits to reflect decimal precision
    if(ti>149)then ti=-5
    elseif(ti>14)then ti=-3
    else ti=-2 end
    ts=string.sub(ts,1,ti)
  end
  return ts
end


print_screen(-2)
print(os.date())
press("shoot_half")
repeat sleep(10) until get_shooting()

tv96=get_tv96();
shutter=tv96_to_shutter(tv96,1000000)
print(string.format("tv96=%d shutter=%d.%06d %s seconds",tv96,shutter/1000000,shutter%1000000,seconds(tv96)))
print("back to tv96=",shutter_to_tv96(shutter,1000000))

sv96=get_sv96()
iso=sv96_to_iso(sv96)
print("sv96=",sv96,iso,"ISO  real=",get_iso_real(),"market=",get_iso_market())
print("back to sv96=",iso_to_sv96(iso))

av96=get_av96()
ap=av96_to_aperture(av96)
print(string.format("av96= %d f/%d.%d",av96,ap/1000,ap%1000))
print("back to av96=",aperture_to_av96(ap))

print()
print_screen(false)
EOS-M3_120f / SX50_100b / SX260_101a / G1X_100g / D20_100b
https://www.youtube.com/user/DrLapser/videos


 

Related Topics