日食撮像自動化プロジェクト for 2016

7. 最終的に落ち着いたフローチャートとプログラムの基礎的部分


 Nikon SDKのC#Wrapper自体は、D600を動かすには充分な能力があります。しかし問題はVisual StudioのC#を使ったフォームでプログラミングする際には”_waitForDevice.WaitOne();”が引っ掛かって、どうやっても動かない。という事で、フォームからのD600の稼働を諦め、フォームでは各種データを入力するだけにして、これを撮像スケジュールファイルとしてファイルに書きだしておき、スタートボタンを押したら、別にC#で書いて実行ファイル形式にした撮像シーケンスソフトウェアで撮像スケジュールを読み込んで、これに従って撮像シーケンスを進めていく形にしました。ここでD7100は、D600がC2前の連写開始時間が始まったときにビープ音を出して、これを感知したら撮像を開始する・・・と言う形にしたいと考えています。
 ここには、コマンドラインで動かす連写~多段階露光~連写を行うルーチンを提示しました。各種データはフォームから入力しセーブした撮像スケジュールを読み込んでこれを変数に代入して従って動くようにしたり、タイムラプスのループからダイヤモンドリングのための連写、多段階撮像を時刻で切ってダイヤモンドリグのための連写に移行することなど、色々関門はあります。
 フォームもきちんと考えないとですね。
 弱点は単写速度が遅いので皆既中の多段階撮像は今回の日食では6セット程度しか撮れない事です。まあこの辺はD7100に依存することになります。

 下部にあるプログラムはコマンドプロンプトで動く「連写~多段階の露光~連写」を設定した数値で実行するプログラムです。Wrapperにもありますが、ソースコードのプロパティには、nikonwrapperを導入し、コンパイルして実行ファイルが入るところにはnikoncswrapper.dll、nikoncswrapper.pdb、NkdPTP.dll、Type0008.md3がある必要があります。
 設定した数値はフォームから入力し、データはtextファイルで取って起き、コマンドプロンプトで動くこのプログラムに読み込む様に作って行く予定です。

Index Next

//

// This work is licensed under a Creative Commons Attribution 3.0 Unported License.

//Thomas Dideriksen (thomas@dideriksen.com)

//

// Modification is done by M_shi_Lab for imaging automatic Total Solar Eclips

//

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.Threading;

using System.IO;

using Nikon;

 

namespace demo_capture

{

    class DemoCapture

    {

        NikonDevice _device;

        AutoResetEvent _waitForDevice = new AutoResetEvent(false);

        AutoResetEvent _waitForCaptureComplete = new AutoResetEvent(false);

 

        public int Speed { get; private set; }

        public int MaxSpeed { get; private set; }

        public int EVStep { get; private set; }

        public int DownStep { get; private set; }

 

        // Create manager object - make sure you have the correct MD3 file for your Nikon DSLR

        //(see https://sdk.nikonimaging.com/apply/)

 

        NikonManager manager = new NikonManager("Type0008.md3");

 

        public void Run()

        {

            try

            {

                // Listen for the 'DeviceAdded' event

                manager.DeviceAdded += manager_DeviceAdded;

 

                // Wait for a device to arrive

                _waitForDevice.WaitOne();

 

                // Hook up capture events

                _device.ImageReady += _device_ImageReady;

                _device.CaptureComplete += _device_CaptureComplete;

 

                //C2ダイヤモンドリング撮像のための連写ルーチン

                Speed = 34;                         //SSはフォームから読み取ります

                uint Count = 5;                     //ここでは5コマですが、コマ数はC2前後撮像する秒数の合計の2倍です

                ContinuousCapture(Speed, Count);    //サブルーチンに飛びます

 

                //多段階撮像ルーチン

                //↓では動作確認上規定値としていますが、本当は表に出るフォームの入力値を

                //セーブしたファイルから読み込みます。     

                MaxSpeed = 36;  //最高速度を規定します。デモ上は1/4000secになります

                EVStep = 2*2;   //EVステップ×2が減速となります

                DownStep = 5;   //何段階撮像するかを規定します

 

                //最低速度を計算します。デモ上では1/4secになります

                int MinSpeed = MaxSpeed - EVStep * DownStep;

               

                //多段階にSSを減速させつつ撮像するルーチン

                //1ループごとにC3前連写時刻と現時刻を比較しつつ回す必要がありますが、それは後に。

                for (Speed = MaxSpeed; Speed >= MinSpeed; Speed = Speed - EVStep)

                {

                    Captor(Speed);

                }

 

                //C3ダイヤモンドリング撮像のための連写ルーチン

                Speed = 34;                         //SSはフォームから読み取ります

                Count = 5;                        //ここでは5コマですが、コマ数はC2前後撮像する秒数の合計の2倍です

                ContinuousCapture(Speed, Count);    //サブルーチンに飛びます

 

                // Shutdown

                manager.Shutdown();

            }

            catch (NikonException ex)

            {

                Console.WriteLine(ex.Message);

            }

        }

        private void ContinuousCapture(int Speed, uint Count) //C2,3のダイヤモンドリングを連写するサブルーチン

        {

            NikonEnum shutterSpeed = _device.GetEnum(eNkMAIDCapability.kNkMAIDCapability_ShutterSpeed);

            shutterSpeed.Index = Speed;

            _device.SetEnum(eNkMAIDCapability.kNkMAIDCapability_ShutterSpeed, shutterSpeed);

 

            // Set number of continuous captures - in this case we want 5

            _device.SetUnsigned(eNkMAIDCapability.kNkMAIDCapability_ContinuousShootingNum, Count);

 

            // Capture

            _device.Capture();

 

            // Wait for the capture to complete

            _waitForCaptureComplete.WaitOne();

        }

 

        private void Captor(int Speed) //任意のシャッター速度で単写するサブルーチン

        {

            _device.SetUnsigned(eNkMAIDCapability.kNkMAIDCapability_ContinuousShootingNum, 1);

            //ShutterSpeed シャッター速度を変えるコード

            NikonEnum shutterSpeed = _device.GetEnum(eNkMAIDCapability.kNkMAIDCapability_ShutterSpeed);

            shutterSpeed.Index = Speed;

            _device.SetEnum(eNkMAIDCapability.kNkMAIDCapability_ShutterSpeed, shutterSpeed);

 

            // Capture

            _device.Capture();

 

            // Wait for the capture to complete

            _waitForCaptureComplete.WaitOne();

        }

 

        void _device_ImageReady(NikonDevice sender, NikonImage image)

        {

           // Save captured image to disk

            string filename = "image" + ((image.Type == NikonImageType.Raw) ? ".jpg" : ".nef");

 

            using (FileStream s = new FileStream(filename, FileMode.Create, FileAccess.Write))

            {

                 s.Write(image.Buffer, 0, image.Buffer.Length);

            }

        }

 

        void _device_CaptureComplete(NikonDevice sender, int data)

        {

            // Signal the the capture completed

            _waitForCaptureComplete.Set();

        }

 

        void manager_DeviceAdded(NikonManager sender, NikonDevice device)

        {

            if (_device == null)

            {

                // Save device

                this._device = device;

                device.SetUnsigned(eNkMAIDCapability.kNkMAIDCapability_SaveMedia, (uint)eNkMAIDSaveMedia.kNkMAIDSaveMedia_Card);

 

                // Signal that we got a device

                _waitForDevice.Set();

            }

        }

    }

 

 

    class Program

    {

        static void Main(string[] args)

        {

            DemoCapture demo = new DemoCapture();

            demo.Run();

        }

    }

}

inserted by FC2 system