Lapser Script Development - LUA Scripting - CHDK Forum  

Lapser Script Development

  • 50 Replies
  • 22087 Views
*

Offline lapser

  • *****
  • 1093
Lapser Script Development
« on: 03 / July / 2017, 16:45:21 »
Advertisements
The port for the EOS M3, along with reyalp's most excellent LUA  hook functions, made we want to get back into CHDK programming again. This time, though, I'm only doing Lua scripting, no C code!!!

Over the last few years, I've done hundreds of time lapse videos using my Tlapser.lua script, and custom CHDK build. But I'm stuck back on version 1.3, so I hope to adapt Tlapser.lua for newer cameras, especially the M3.

I've attached a copy of my test script, Ctest.lua. The "C" stands for continuous mode, which my new time lapse script will require. I've also attached a combined log file from Ctest.lua that includes 2 runs on the G1X, and 2 on the M3.

One thing I discovered is that the ISO isn't saved into the EXIF data on the M3. The photos come out exposed correctly, however. So Ctest.lua includes an option to specify you're on an M3. If so, it saves sv into a new propcase I discovered that should be called:

PROPCASE_SV2 = 354 (on the M3)

If you have an M3, run Ctest with the eosm3 parameter unchecked, and another run with it checked. Set the ISO parameter different from the camera ISO, like ISO 800 or something. Then check the photos to see if they show the correct ISO or not.
====
You'll also notice that I wrote a logging function called:

function logger(s)

This delays the actual writing of the log file to the SD card until the end. That way, writing the log doesn't hang the script when the camera is busy writing photos (especially large RAW files). In my Tlapser.lua script, I found that writing every line to the SD card sometimes hangs for up to 7 seconds!
===
I also used reyalp's raw routines to log the black level, and the value of pixel (5,5). That pixel is in the masked area of the sensor where it doesn't get any light. Its value should be close to the black level.

Next I show the value of the pixel in the center of the active area, which varies. An overexposed image gives the white level.

Both the G1X and the M3 have 14 bit pixels, but the M3 black level is 2047, while the G1X is 511. That sounds like the M3 would have less range, but it's actually like having 13.8 bits instead of 14. Presumably, this helps to lower the noise level.
===
The logs also include timing data which I'm hoping to use to talk reyalp into adding a function like this:

set_next_shutter_open_time(tick_time)

That takes the precise timing of the shutter opening out of the script and puts into the shooting task, where it is more accurate. I discovered that I could sync 2 different cameras running Tlapser.lua by doing this, as well as a number of other advantages that speed up the maximum shot rate. I'll discuss this more in the future as I collect more data.

You can view the videos I've done with Tlapser.lua in the past few years here:
https://www.youtube.com/user/DrLapser/videos
EOS-M3_120f / SX50_100b / SX260_101a / G1X_100g / D20_100b
https://www.youtube.com/user/DrLapser/videos

*

Offline c_joerg

  • *****
  • 1250
Re: Lapser Script Development
« Reply #1 on: 04 / July / 2017, 05:53:23 »
I try to follow you…
That way, writing the log doesn't hang the script when the camera is busy writing photos (especially large RAW files). In my Tlapser.lua script, I found that writing every line to the SD card sometimes hangs for up to 7 seconds!
I can’t believe why it’s so much. Since I update my G1x to CHDK 1.5 I can rawopint with log on Intervals with 1.1s without problems…
while the G1X is 511
I couldn’t remember anymore. But I thought the blacklevel on G1x change under some conditions…
That sounds like the M3 would have less range, but it's actually like having 13.8 bits instead of 14. Presumably, this helps to lower the noise level.
And I haven’t really understood why M3 can have 1EV more dynamic range as G1x…
https://www.dxomark.com/Cameras/Compare/Side-by-side/Canon-EOS-M3-versus-Canon-PowerShot-G1X___1019_769

I discovered that I could sync 2 different cameras running Tlapser.lua by doing this,
What was the reason to do this?
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

*

Offline lapser

  • *****
  • 1093
Re: Lapser Script Development
« Reply #2 on: 05 / July / 2017, 14:42:01 »

That way, writing the log doesn't hang the script when the camera is busy writing photos (especially large RAW files). In my Tlapser.lua script, I found that writing every line to the SD card sometimes hangs for up to 7 seconds!
I can’t believe why it’s so much. Since I update my G1x to CHDK 1.5 I can rawopint with log on Intervals with 1.1s without problems…
Maybe, just for a second, we can forget what the "H" stands for and think like a designer instead of a hacker. A designer would ask, "What's the best way to do an interval timer in continuous mode?"

The answer is that you would put a delay in the shoot task right before it opens the shutter. In my Tlapser script, I used a set_shot_interval(msec) function. It worked, and was highly accurate. It could handle fairly long script delays without missing the interval. It didn't require (or allow) any script intervention.

Reyalp's rawopint moved the interval delay into the script task. He moved as much as he could into the script task, which gives the script more control. I really like that for everything else!

But scripts run in the keyboard task, which is a low priority task. Sometimes low priority tasks don't execute for long periods of time when a higher priority task is busy. If the keyboard task is controlling the shot interval, then you'll miss the interval when another task is busy.

Another problem with having the script do the shot timing is that the script can't do any processing after calling hook_raw.continue(). It has to enter a delay loop so it can call hook_shoot.continue() at the proper time.

But if you had this function:

set_next_shutter_open_time(tick_time)

then the script could do a lot more processing (or garbage collecting) during the entire shot. It could handle a single long delay without missing the next shot. That would give it time to close and reopen the log file without missing the interval, for example.

Reyalp added a feature that turns the histogram into a lua object. What a great idea! Since that copies the histogram data into lua memory, you could process and display it after calling hook_raw_continue(), that is, if the script didn't have to control the interval. Wouldn't it be great to show a live histogram on the screen in continuous mode, without affecting the shot rate?

You asked why I would want to run two cameras in exact sync. Well, you could show two simultaneous time lapses in split screen. One could show the full Moon rising, with the other showing the Sun setting at the same time. And if you could sync a lot of camera clocks accurately, you could do "bullet time" videos without any cabling:
All these things, and more, become possible when the the script is freed from doing the exact interval timing. Now let me ask you a question. What is the advantage of making the script do all the interval timing? I can't think of one.
EOS-M3_120f / SX50_100b / SX260_101a / G1X_100g / D20_100b
https://www.youtube.com/user/DrLapser/videos

Re: Lapser Script Development
« Reply #3 on: 05 / July / 2017, 14:59:39 »
That way, writing the log doesn't hang the script when the camera is busy writing photos (especially large RAW files). In my Tlapser.lua script, I found that writing every line to the SD card sometimes hangs for up to 7 seconds!
As I demonstrated quite conclusively here,  that delay will occur after a set number of writes to your SD card (images or log file updates). It's not a scripting speed or priority issue - it's just a function of how your SD card internal wear leveling works.   In my scripts,  I started buffering log entries and write them periodically rather than after every shot to minimize the number of times this happens.

But if you had this function: set_next_shutter_open_time(tick_time)  then the script could do a lot more processing (or garbage collecting) during the entire shot. It could handle a single long delay without missing the next shot. That would give it time to close and reopen the log file without missing the interval, for example.
What you are really looking for is an interrupt driven system where certain event can be guaranteed to occur at specified times.  While it seems unlikely that CHDK Lua will ever truly get to that state,  it does seem possible that a "high priority" call back mechanism could be implemented in the script engine with some work.  It's just a question of how valuable that would really be I guess.
Ported :   A1200    SD940   G10    Powershot N    G16


*

Offline lapser

  • *****
  • 1093
Re: Lapser Script Development
« Reply #4 on: 05 / July / 2017, 15:10:25 »
What you are really looking for is an interrupt driven system where certain event can be guaranteed to occur at specified times.  While it seems unlikely that CHDK Lua will ever truly get to that state,  it does seem possible that a "high priority" call back mechanism could be implemented in the script engine with some work.  It's just a question of how valuable that would really be I guess.
All I'm looking for is for you to add this function:

set_next_shutter_open_time(tick_time)

That moves the precise control of the shot timing to the shoot task, instead of being dependent on the keyboard (script) task AND the shoot task. It's a simple coding change!
EOS-M3_120f / SX50_100b / SX260_101a / G1X_100g / D20_100b
https://www.youtube.com/user/DrLapser/videos

Re: Lapser Script Development
« Reply #5 on: 05 / July / 2017, 15:39:56 »
All I'm looking for is for you to add this function: set_next_shutter_open_time(tick_time)
Well, that's certainly easier than adding a pseudo interrupt call back structure!

If I understand this correctly, would it be more clear to just use something like :
Code: [Select]
shoot_when(tick_time)
Quote
That moves the precise control of the shot timing to the shoot task, instead of being dependent on the keyboard (script) task AND the shoot task. It's a simple coding change!
AFAIK, the hooked "shoot tasks" (capt_seq_task or exp_drv_task) respond to messages from other parts of the firmware - they don't run on a regular basis. So having them open the shutter at a specified tick time doesn't really work.  But it seems likely that there is another way to make this work satisfactorily. 


Ported :   A1200    SD940   G10    Powershot N    G16

*

Offline lapser

  • *****
  • 1093
Re: Lapser Script Development
« Reply #6 on: 05 / July / 2017, 17:27:08 »
AFAIK, the hooked "shoot tasks" (capt_seq_task or exp_drv_task) respond to messages from other parts of the firmware - they don't run on a regular basis. So having them open the shutter at a specified tick time doesn't really work.  But it seems likely that there is another way to make this work satisfactorily.
Can you give me a link to the source code file that contains reyalp's code that delays the shutter opening until the script calls hook_shoot_continue()? Things have changed around a bit since version 1.3!

You don't need to open the shutter at any specific time. You just need to delay the next shutter open until after a specific time, i.e. next_shutter_open_time, that's set by the script.

This is how I did it in my build:
Code: [Select]
void __attribute__((naked,noinline)) capt_seq_hook_set_nr()
{
 asm volatile("STMFD   SP!, {R0-R12,LR}\n");
******* my code
     shot_histogram_shot_delay(); //wait delay interval, if any, right before taking shot
    //note: must delay BEFORE setting NR values
********
    switch (conf.raw_nr){
    case NOISE_REDUCTION_AUTO_CANON:
        // leave it alone
#if defined(NR_AUTO)         // If value defined store it (e.g. for G12 & SX30 need to reset back to 0 to enable auto)
        set_nrflag(NR_AUTO);
#endif
        break;
    case NOISE_REDUCTION_OFF:
        set_nrflag(NR_OFF);
        break;
    case NOISE_REDUCTION_ON:
        set_nrflag(NR_ON);
        break;
    };
 camera_info.state.shutter_open_time = _time((void*)0);
 camera_info.state.shutter_open_tick_count = get_tick_count();


 asm volatile("LDMFD   SP!, {R0-R12,PC}\n");
}
EOS-M3_120f / SX50_100b / SX260_101a / G1X_100g / D20_100b
https://www.youtube.com/user/DrLapser/videos

Re: Lapser Script Development
« Reply #7 on: 05 / July / 2017, 18:02:17 »
Can you give me a link to the source code file that contains reyalp's code that delays the shutter opening until the script calls hook_shoot_continue()?
https://app.assembla.com/spaces/chdk/subversion/source/HEAD/trunk/core/usb_sync.c#ln84
Ported :   A1200    SD940   G10    Powershot N    G16


*

Offline reyalp

  • ******
  • 14111
Re: Lapser Script Development
« Reply #8 on: 06 / July / 2017, 01:28:01 »
But scripts run in the keyboard task, which is a low priority task.
PhySw is actually equal priority to CaptSeq in the cameras I looked at. (lower numbers  = more priority)
Quote
Sometimes low priority tasks don't execute for long periods of time when a higher priority task is busy. If the keyboard task is controlling the shot interval, then you'll miss the interval when another task is busy.
In all the time I spent developing and testing this feature, I have not seen any evidence that this is a problem. This is born out by the fact that on the cameras I've tested, scripts using this system can maintain intervals very close the the cameras native continuous shooting rate.

I would need to be convinced of the diagnosis before adding features to "fix" it.

Quote
Another problem with having the script do the shot timing is that the script can't do any processing after calling hook_raw.continue(). It has to enter a delay loop so it can call hook_shoot.continue() at the proper time.
Again, I'm not seeing the real problem. Outside of metering (which has to happen in the raw hook), even a very complicated script like rawopint spends very little time processing.  There is certain to be a substantial delay between hook_raw.continue() and the shoot hook being ready, since all image processing and saving happens after the raw hook.

The hand off between script and the other tasks does have some overhead but it should only be ~20ms. That should be negligible for most purposes, and considering the tick count has 10 ms precision, there isn't a huge amount of room for improvement.

Waterwingz pointed you to where the shoot hook is called, the actual implementation of the hooks is in
https://app.assembla.com/spaces/chdk/subversion/source/HEAD/trunk/modules/script_shoot_hook.c


Don't forget what the H stands for.

*

Offline c_joerg

  • *****
  • 1250
Re: Lapser Script Development
« Reply #9 on: 07 / July / 2017, 15:28:00 »
If have just seen your last video. It’s great to see the comparing videos.
How do you made the split window (or zooming)?
Quote
ETTR (Exposure To The Right) means the photo is exposed as brightly as possible without overexposing any part of the image.
Why do you think you need to have no overexposing? I think the core of the sun can be overexposed. When I run rawopint I set the maximum overexposure to about 1% (when I use lowest focal length of G1x). Yes of course for time-lapse with the moon I set it close to 0 to see the structure of the moon.
Not sure how much EV steps between 0% or 1% overexposure…

Can it be that the shutter starts to flicker? I notice some in the previous video.
How much shoots have your G1x right now?
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

 

Related Topics


SimplePortal 2.3.6 © 2008-2014, SimplePortal