找回密碼
 申請討論區帳戶
查看: 3145|回復: 7

Canon 相機日食拍攝控制第三方軟件 Magic Lantern Eclipse Sequencer

  [複製鏈接]
發表於 2014-11-30 14:36:40 | 顯示全部樓層 |閱讀模式
Canon 相機日食拍攝控制第三方軟件 Magic Lantern

http://www.magiclantern.fm/about.html

支援型號:
500D, 550D, 600D, 650D, 700D, 1100D
50D, 60D,
5D Mark II, 5D Mark III, 6D, 7D
EOS-M


 樓主| 發表於 2014-11-30 14:40:53 | 顯示全部樓層
主要用於包圍曝光 (最多12級) 及排程拍攝

 樓主| 發表於 2019-7-23 04:44:52 | 顯示全部樓層
Eclipse Sequencer

Eclipse Sequencer 是 Magic Lantern 的 LUA 腳本,可自動完成拍攝整個日食過程的照片

https://github.com/rkaczorek/eclipse-sequencer
 樓主| 發表於 2019-7-23 05:10:31 | 顯示全部樓層
Eclipse Sequencer 腳本 (script) 功能:

可設置初虧、食既、生光和復圓四個時間
可設置所有的日食階段:偏食,鑽石環,貝利珠,全食過程,拍攝地影
可設置日食前後的跟蹤拍攝時間(日食前後的影像)
開始時間綁定到真實時間
支持UTC和當地時間
從Magic Lantern菜單可以開啟模擬的測試模式
將拍攝過記錄到 log file
支援過程中暫停更換電池及重新啟動相機後停止並繼鑟執行餘下的程序
 樓主| 發表於 2019-7-23 05:14:24 | 顯示全部樓層
如何使用Eclipse Sequencer script
下載腳本 (script) 並將其放在SD卡上的ML / scripts目錄中重新配置eclipse的時序參數重新配置序列參數以滿足您的需要從Magic Lantern菜單運行腳本

如何重新編輯日食設定
編輯腳本並更改第27-30行中的時序參數。

以2019智利日全食為例 (時間是當地時間):

26 行 -- Chile 2019 (local time): 15:22:15 16:38:19 16:39:53 17:46:25
27 行 c1.hr = 15; c1.min = 22; c1.sec = 16;        --        Set C1 time here 初虧時間:時、分、秒
28 行 c2.hr = 16; c2.min = 38; c2.sec = 19;        --        Set C2 time here 食既時間:時、分、秒
29 行 c3.hr = 16; c3.min = 39; c3.sec = 55;        --        Set C3 time here 生光時間:時、分、秒
30 行 c4.hr = 17; c4.min = 46; c4.sec = 26;        --        Set C4 time here 復圓時間:時、分、秒

32 行 -- Local adjustment based on Solar Eclipse Calculator 按照預測地點與實際觀測地點修正
33 行 -- Set DeltaTime to LC parameter from the Solar Eclipse Calculator 實際觀測地點修正數值
34 行 DeltaTime = 2 要更改的修正時間 (秒)

編輯腳本並更改第39-47行中的其它參數

39 行 TestMode = 0                        -- can be changed from menu 測試模式  (0=否、1=是)
40 行 LogToFile = 1                        -- set to 0 to disable logging to eclipse.log file 寫入紀錄檔  (0=否、1=是)
41 行 MinShutter = (1/4096)           -- depends on camera model 採用相機最快的快門速度 (秒)
42 行 MaxShutter = 30                   -- depends on camera model 採用相機最慢的快門速度 (秒)
43 行 TimeZone = -4                      -- local time zone 觀測地點時區
44 行 UseUTC = 0                          -- set to 1 if you use UTC time on your camera 相機時間是否用世界時   (0=否、1=是)
45 行 LeadTime = 180                    -- number of seconds to start sequence before c1 初虧前開始拍照時間 (秒)
46 行 TrailTime = 180                     -- number of seconds to end sequence after c4 復圓後繼續拍照時間 (秒)
47 行 PartialDelay = 30                   -- number of seconds between partial images 偏食過程拍照間隔時間  (秒)
 樓主| 發表於 2019-7-23 05:23:55 | 顯示全部樓層
以下是 Eclipse Sequencer 的 script file 文字檔,檔案名:eclipse_sequencer.lua
原本的連接網址:https://github.com/rkaczorek/ecl ... lipse_sequencer.lua

-- Eclipse Sequencer
-- Version 1.0.0
-- Auto Sequencer for Total Solar Eclipse
--
-- Copyright 2019 by Radek Kaczorek, [email protected]
-- Distributed under the GNU General Public License.
-- Inspired by Eclipse Magic by Brian Greenberg, [email protected]

require ("logger")

--
--        Script init parameters. DO NOT change these
--
TestStartTime = 0                -- do not change, global init
LoggingFile = nil                -- do not change, global init
c1 = {}                                        -- do not change, global init
c2 = {}                                        -- do not change, global init
c3 = {}                                        -- do not change, global init
c4 = {}                                        -- do not change, global init

--
--        Eclipse timing parameters. SET reliable times for each phase
--        You can use Solar Eclipse Calculator: http://xjubier.free.fr/en/site_p ... seCalc_Diagram.html
--

-- Chile 2019 (local time): 15:22:15 16:38:19 16:39:53 17:46:25
c1.hr = 15; c1.min = 22; c1.sec = 16;        --        Set C1 time here
c2.hr = 16; c2.min = 38; c2.sec = 19;        --        Set C2 time here
c3.hr = 16; c3.min = 39; c3.sec = 55;        --        Set C3 time here
c4.hr = 17; c4.min = 46; c4.sec = 26;        --        Set C4 time here

-- Local adjustment based on Solar Eclipse Calculator
-- Set DeltaTime to LC parameter from the Solar Eclipse Calculator
DeltaTime = 2

--
--        Configurable parameters. YOU CAN change these
--
TestMode = 0                        -- can be changed from menu
LogToFile = 1                        -- set to 0 to disable logging to eclipse.log file
MinShutter = (1/4096)        -- depends on camera model
MaxShutter = 30                        -- depends on camera model
TimeZone = -4                        -- local time zone
UseUTC = 0                                -- set to 1 if you use UTC time on your camera
LeadTime = 180                        -- number of seconds to start sequence before c1
TrailTime = 180                        -- number of seconds to end sequence after c4
PartialDelay = 30                -- number of seconds between partial images

--
--        ==============================================
--                DO NOT change anything below this line
--        ==============================================
--

if (TestMode == 1)
then
        c1.hr = 0; c1.min =  1; c1.sec = 00;
        c2.hr = 0; c2.min =  2; c2.sec = 00;
        c3.hr = 0; c3.min =  3; c3.sec = 00;
        c4.hr = 0; c4.min =  4; c4.sec = 00;
end

if (UseUTC == 1)        -- Change local time to UTC
then
        c1.hr = c1.hr + TimeZone
        c2.hr = c2.hr + TimeZone
        c3.hr = c3.hr + TimeZone
        c4.hr = c4.hr + TimeZone
end

--
-- Change time to seconds from midnight. We use this for timing all events
-- This approach ensures that the sequence resumes in proper time if you need
-- to change battery or you start the sequence in the middle of the event
--
c1_sec = c1.hr * 3600 + c1.min * 60 + c1.sec
c2_sec = c2.hr * 3600 + c2.min * 60 + c2.sec
c3_sec = c3.hr * 3600 + c3.min * 60 + c3.sec
c4_sec = c4.hr * 3600 + c4.min * 60 + c4.sec

totality_sec = math.floor(c2_sec + ((c3_sec - c2_sec) / 2))
c2_sec = c2_sec + DeltaTime
c3_sec = c3_sec - DeltaTime

function sequence_partial (start_time, end_time, shutter_start, shutter_end, iso)
        local timenow = now()
        local counter = 1
        local shutter_speed = shutter_start
        local shutter_step = 0
        if (timenow >= end_time)
        then
                log ("%s: Skipping partial sequence due to time passed %d seconds ago", pretty_time(timenow), (timenow - end_time))
                return
        end
        log ("%s: Partial sequence starting in %d seconds", pretty_time(timenow), (start_time - timenow))
        sleep_until (start_time) -- wait for sequence start
        -- The sequence
        log ("%s: Partial sequence starting now", pretty_time(timenow))        

        if ((end_time - timenow) > PartialDelay)
        then
                counter = math.floor((end_time - timenow) / PartialDelay)        -- calculate number of images we can capture
        end

        if (shutter_end ~= shutter_start)        -- calculate shutter speed step throughout the sequence
        then
                shutter_step = (math.log((shutter_end / shutter_start),2) / counter)
        end

        for i = 1,counter,1        -- run the sequence
        do
                log ("%s: Partial sequence image %d/%d @ iso: %d, shutter speed: %s", pretty_time(timenow), i, counter, iso, pretty_shutter(shutter_speed))
                timenow = now()
                if (timenow >= end_time)
                then
                        log ("%s: No time for another image. Quiting sequence.", pretty_time(timenow))
                        return
                end
                capture_image (iso, shutter_speed)
                shutter_speed = shutter_speed * 2.0^shutter_step
               
                timenow = now()
                if ((timenow + PartialDelay) < end_time)
                then
                        sleep_until (timenow + PartialDelay)
                else
                        return
                end
        end
end

function sequence_diamond_ring (start_time, end_time, shutter_speed, iso)
        local timenow = now()
        if (timenow >= end_time)
        then
                log ("%s: Skipping diamond ring sequence due to time passed %d seconds ago", pretty_time(timenow), (timenow - end_time))
                return
        end
        log ("%s: Diamond ring sequence starting in %d seconds", pretty_time(timenow), (start_time - timenow))
        sleep_until (start_time) -- wait for sequence start
        -- The sequence
        log ("%s: Diamond ring sequence starting now", pretty_time(timenow))
        repeat
                timenow = now()
                capture_image (iso, shutter_speed)
        until (timenow >= end_time)
end

function sequence_baileys_beads (start_time, end_time, shutter_speed, iso)
        local timenow = now()
        if (timenow >= end_time)
        then
                log ("%s: Skipping baileys beads sequence due to time passed %d seconds ago", pretty_time(timenow), (timenow - end_time))
                return
        end
        log ("%s: Bailey's beads sequence starting in %d seconds", pretty_time(timenow), (start_time - timenow))
        sleep_until (start_time) -- wait for sequence start
        -- The sequence
        log ("%s: Bailey's beads sequence starting now", pretty_time(timenow))
        repeat
                timenow = now()
                capture_image (iso, shutter_speed)
        until (timenow >= end_time)        
end

function sequence_chromosphere (start_time, end_time, shutter_speed, iso)
        local timenow = now()
        if (timenow >= end_time)
        then
                log ("%s: Skipping chromosphere sequence due to time passed %d seconds ago", pretty_time(timenow), (timenow - end_time))
                return
        end
        log ("%s: Chromosphere sequence starting in %d seconds", pretty_time(timenow), (start_time - timenow))
        sleep_until (start_time) -- wait for sequence start
        -- The sequence
        log ("%s: Chromosphere sequence starting now", pretty_time(timenow))
        repeat
                timenow = now()
                capture_image (iso, shutter_speed)
        until (timenow >= end_time)        
end

function sequence_totality (start_time, end_time, shutter_start, shutter_end, iso)
        local timenow = now()
        local counter = 1
        local shutter_speed = shutter_start        -- preset shutter for the first loop
        if (timenow > totality_sec)                        -- reverse shutter changes after mid totality
        then
                shutter_speed = shutter_end
        end
        local shutter_step = 0.5
        if (timenow >= end_time)
        then
                log ("%s: Skipping totality sequence due to time passed %d seconds ago", pretty_time(timenow), (timenow - end_time))
                return
        end
        log ("%s: Totality sequence starting in %d seconds", pretty_time(timenow), (start_time - timenow))
        sleep_until (start_time) -- wait for sequence start
        -- The sequence
        log ("%s: Totality sequence starting now", pretty_time(timenow))        

        counter = math.floor(math.log((shutter_end / shutter_start),2) / shutter_step)        -- calculate number of images we can capture
        
        local loopcount = 1        
        repeat        -- run the sequence
                log ("%s: Totality sequence loop %d", pretty_time(timenow), loopcount)
                for i = 1,counter,1
                do               
                        log ("%s: Totality sequence image %d/%d @ iso: %d, shutter speed: %s", pretty_time(timenow), i, counter, iso, pretty_shutter(shutter_speed))
                        timenow = now()        -- security valve
                        if (timenow >= end_time)
                        then
                                log ("%s: No time for another image. Quiting sequence.", pretty_time(timenow))
                                return
                        end
                        capture_image (iso, shutter_speed)
                        if (timenow < totality_sec)
                        then
                                shutter_speed = shutter_speed * 2.0^shutter_step
                        else
                                 shutter_speed = shutter_speed / 2.0^shutter_step
                        end
                end
                loopcount = loopcount + 1
                timenow = now()
                shutter_speed = shutter_start        -- reset shutter for the next loop
                if (timenow > totality_sec)                -- reverse shutter changes after mid totality
                then
                        shutter_speed = shutter_end
                end
        until (timenow >= end_time)
end

function sequence_eartshine (start_time, end_time, shutter_speed, iso)
        local timenow = now()
        if (timenow >= end_time)
        then
                log ("%s: Skipping eartshine sequence due to time passed %d seconds ago", pretty_time(timenow), (timenow - end_time))
                return
        end
        log ("%s: Earthshine sequence starting in %d seconds", pretty_time(timenow), (start_time - timenow))
        sleep_until (start_time) -- wait for sequence start
        -- The sequence
        log ("%s: Earthshine sequence starting now", pretty_time(timenow))
        repeat
                timenow = now()
                capture_image (iso, shutter_speed)
        until (timenow >= end_time)
end

function filter_warning (warning_time)
        local timenow = now()
        if (timenow >= warning_time)
        then
                log ("%s: Skipping filter warning due to time passed %d seconds ago", pretty_time(timenow), (timenow - warning_time))
                return
        end
        log ("==================================")
        log ("==================================")
        log ("%s: Filter warning in %d seconds", pretty_time(timenow), (warning_time - timenow))
        log ("==================================")
        log ("==================================")
        sleep_until (warning_time) -- wait for sequence start
        if (timenow < totality_sec)
        then
                log ("==================================")
                log ("==================================")
                log ("%s: Remove filter !!!", pretty_time(timenow))
                log ("==================================")
                log ("==================================")
        else
                log ("==================================")
                log ("==================================")
                log ("%s: Replace filter !!!", pretty_time(timenow))
                log ("==================================")
                log ("==================================")
        end
end

--
-- Open log file
--
function log_start ()
        if (LogToFile ~= 0)
        then
                local now = dryos.date
                local filename = string.format("eclipse.log")
                print (string.format ("Open log file %s", filename))
                LoggingFile = logger (filename)
        else
                print (string.format ("Logging disabled"))
        end
end

--
-- Close log file
--
function log_stop ()
        if (LogToFile ~= 0)
        then
                print (string.format ("Close log file"))
                LoggingFile:close ()
        end
end

--
-- Log to file
--
function log (s, ...)
        local str = string.format (s, ...)
        str = str .. "\n"
        if (LogToFile == 1)
        then
                LoggingFile:write (str)
        end
        return
end

--
--        Get current time in seconds (from midnight)
--
function now()
        local now = dryos.date
        local seconds = (now.hour * 3600 + now.min * 60 + now.sec)

        if (TestMode == 1)
        then
                seconds = (seconds - TestStartTime)
        end
        return seconds
end

--
--        Sleep predefined number of seconds
--
function sleep_until (targettime)
        local timenow = now()
        log ("%s: Sleeping %d seconds until %s.", pretty_time(now()), targettime - timenow, pretty_time(targettime))
        repeat
                msleep(500)
                timenow = now()
        until((timenow > (targettime - 1)))
end

--
-- Take current time in seconds (from midnight) and convert it to HH:MM:SS
--
function pretty_time (time_secs)
        local text_time = ""
        local hrs = 0
        local mins = 0
        local secs = 0
        
        hrs =  math.floor(time_secs / 3600)
    mins = math.floor((time_secs - (hrs * 3600)) / 60)
        secs = (time_secs - (hrs*3600) - (mins * 60))
        text_time = string.format("%02d:%02d:%02d", hrs, mins, secs)
        return text_time
end

--
-- Take shutter speed expressed in fractional seconds and convert it to 1/x
--
function pretty_shutter (shutter_speed)
        local text_time = ""

        if (shutter_speed >= 1.0)
        then
                text_time = tostring (shutter_speed)
        else
                text_time = string.format ("1/%s", tostring (1/shutter_speed))
        end
        return text_time
end

--
-- Capture an image with or without bracketing. Sequence: -,0,+
--
function capture_image(iso, shutter_speed, bktcount, bktstep)
        bktcount = bktcount or 0
        bktstep = bktstep or 0
        
        local bktspeed = 0.0        
        camera.iso.value = iso

        if (shutter_speed < MinShutter or shutter_speed > MaxShutter ) -- warn user of invalid shutter speed and skip image capture
        then
        
                log ("%s: Skipping image! Invalid shutter speed!!! (Min: %s s, Max: %s s)",
                        pretty_time(now()), pretty_shutter(MinShutter), pretty_shutter(MaxShutter))
                return
        end
        
        -- If braketing run - brackets
        if (bktcount > 0)
        then
                log ("%s: Capturing image with bracketing @ Brackets: %d Step: %s",
                        pretty_time(now()), bktcount, tostring(bktstep))

                for i = bktcount,1,-1
                do
                        bktspeed = shutter_speed / (2.0^(i * bktstep))

                        if (bktspeed < MinShutter) -- prevent shutter speed going below minimum
                        then
                                bktspeed = MinShutter
                        end

                        camera.shutter.value = bktspeed
                        
                        log ("%s: Capturing - bracket image %d/%d @ ISO: %s Shutter: %s",
                                pretty_time(now()), (bktcount - i + 1), bktcount, tostring(camera.iso.value), pretty_shutter(camera.shutter.value))

                        if (TestMode == 0)
                        then
                                camera.shoot(false)
                                msleep(100)
                        else               
                                msleep(camera.shutter.ms + 100)               
                        end
                end
        end

        -- Just capture an image without brackets
        camera.shutter.value = shutter_speed

        log ("%s: Capturing image @ ISO: %s Shutter: %s",
                pretty_time(now()), tostring(camera.iso.value), pretty_shutter(camera.shutter.value))

        if (TestMode == 0)
        then
                camera.shoot(false)
                msleep(100)
        else
                msleep(camera.shutter.ms + 100)
        end

        -- If braketing run + brackets
        if (bktcount > 0)
        then
                for i = 1,bktcount,1
                do
                        bktspeed = shutter_speed * (2.0^(i * bktstep))

                        if (bktspeed > MaxShutter) -- prevent shutter speed going over maximum
                        then
                                bktspeed = MaxShutter
                        end
                        
                        camera.shutter.value = bktspeed
                        
                        log ("%s: Capturing + bracket image %d/%d @ ISO: %s Shutter: %s",
                                pretty_time(now()), i, bktcount, tostring(camera.iso.value), pretty_shutter(camera.shutter.value))

                        if (TestMode == 0)
                        then
                                camera.shoot(false)
                                msleep(100)
                        else               
                                msleep(camera.shutter.ms + 100)               
                        end
                end
        end
end

--
-- Capture images in burst mode
--
function capture_burst(iso, shutter_speed, counter)
        camera.shutter.value = shutter_speed
        camera.iso.value = iso
               
        log ("%s: Capturing %d images in burst",
                pretty_time(now()), counter)
        for i = 1,counter,1
        do
                log ("%s: Capturing image %d/%d @ ISO: %s shutter: %s",
                        pretty_time(now()), i, counter, tostring(camera.iso.value), pretty_shutter(camera.shutter.value))

                if (TestMode == 0)
                then
                        capture_image(iso, shutter_speed)
                        msleep(100)
                else
                        msleep(counter * (camera.shutter.ms + 100))               
                end
        end
end

--
--        Main routine
--
function main()
        TestStartTime = now()
        
        menu.close()
        console.show()
        log_start ()


        if (eclipse_menu.submenu["Test Mode"].value == "ON")
        then
                TestMode = 1
        else
                TestMode = 0
        end

        print ()
        print ("-------------------------------------")
        print ("  Eclipse Sequencer")
        print ("  Copyright 2019, [email protected]")
        print ("  Released under the GNU GPL")
        print ("-------------------------------------")
        print ()

        if (TestMode == 1)
        then
                log ("==================")
                log ("== Test Mode ON ==")
                log ("==================")
        end

        if (camera.mode ~= MODE.M)
        then
                log  ("Camera must be in manual (M) mode")
                display.print("Press any button to exit the script. Change the mode and re-run.")               
                key.wait()
                console.hide()
                display.clear()
                display.off()
                menu.block(false)
                return
        end

        local timenow = now()
        log("System Time: %d", timenow)
        log("C1: %d", c1_sec)
        log("C2: %d", c2_sec)
        log("C3: %d", c3_sec)
        log("C4: %d", c4_sec)

        --
        --        Sequence of events at Total Solar Eclipse
        --
        --                Example exposures for focal ratio: F/9                ISO                Exposure
        --                                                                                                        ---                -------------
        -- c1 to c2:                        partial eclipse                                100                1/500 - 1/250
        -- c2-20s:                                remove camera filter!
        -- c2-15s to c2-11s:        diamond ring                                100                1/80
        -- c2-10s to c2-3s:                bailey's beads                                100                1/2000
        -- c2-2s to c2+5s:                chromosphere                                100                1/1000 - 1/500
        -- totality start                lower to outer corona                100                1/250 - 1
        -- totality mid                        eartshine                                        1600        1
        -- totality end                        lower to outer corona                100                1/250 - 1
        -- c3-5s to c3+2s:                chromosphere                                100                1/1000 - 1/500
        -- c3+3s to c3+10s:                bailey's beads                                100                1/2000
        -- c3+11s to c3+15s:        diamond ring                                100                1/80
        -- c3+20s:                                replace camera filter!
        -- c3 to c4:                        partial eclipse                                100                1/250 - 1/2

        -- Main solar eclipse sequence
        sequence_partial ((c1_sec - LeadTime), (c2_sec - 21), (1/500), (1/250), 100)
        filter_warning ((c2_sec - 20))
        sequence_diamond_ring ((c2_sec - 15), (c2_sec - 11), (1/40), 100)
        sequence_baileys_beads ((c2_sec - 10), (c2_sec - 3), (1/2000), 100)
        sequence_chromosphere ((c2_sec - 2), (c2_sec + 5), (1/1000), 100)
        sequence_totality ((c2_sec + 6), (totality_sec - 11), (1/250), 1.0, 200)
        sequence_eartshine ((totality_sec - 10), (totality_sec + 10), 1.0, 1600)
        sequence_totality ((totality_sec + 11), (c3_sec - 6), (1/250), 1.0, 200)
        sequence_chromosphere ((c3_sec - 5), (c3_sec + 2), (1/1000), 100)
        sequence_baileys_beads ((c3_sec + 3), (c3_sec + 10), (1/2000), 100)
        sequence_diamond_ring ((c3_sec + 11), (c3_sec + 15), (1/40), 100)
        filter_warning ((c3_sec + 20))
        sequence_partial ((c3_sec + 21), (c4_sec + TrailTime), (1/250), (1/2), 100)

        log ("%s: All done", pretty_time(now()))
        log_stop ()
        print("Press any button to exit")
        key.wait()
        console.hide()
end

--
-- Menu item
--
eclipse_menu = menu.new
{
    name   = "Eclipse Sequencer",
    help   = "Auto Sequencer for Solar Eclipse",
    submenu =
    {
        {
            name = "Run",
            help = "Run this script",
            select = function(this) task.create(main) end
        },
        {
            name = "Test Mode",
            help = "Run test or real world",
            choices = {"ON", "OFF"}
        }
    }
}




 樓主| 發表於 2019-7-23 13:03:46 | 顯示全部樓層
Eclipse Sequencer 是 Eclipse Magic 的改良版本

Eclipse Magic 的 camera.burst() 功能需要先做 lua_fix

lua_fix
https://builds.magiclantern.fm/experiments.html
 樓主| 發表於 2019-7-23 13:06:29 | 顯示全部樓層
Eclipse Magic 1.7 版本的腳本 (script) 原文

http://www.grnbrg.org/eclipse_magic.lua

您需要登錄後才可以回帖 登錄 | 申請討論區帳戶

本版積分規則

Archiver|手機版|小黑屋|香港天文學會

GMT+8, 2024-3-29 07:27 , Processed in 0.012887 second(s), 16 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回復 返回頂部 返回列表