Newer
Older
TIASShot / TIASshot / Cameras / Lucam.HwTest.cs
#if HWTEST
using System;
using Lumenera.USB;

namespace TIASshot {

    /// <summary>
    /// Lucam の実機テスト用の口(HWTEST 限定).SDK を呼ぶだけの薄い処理に留める.
    /// 露光(ms)・ゲイン(倍率)は LucamGetProperty / LucamSetProperty の float の実数値そのもの(整数への丸めは無い)で読み書きするため,
    /// 最初に読んだ値をそのまま書き戻せば元の値に戻る(HwTestRunner.RestoreSettings が IScam と同じく相対誤差 1% で読み戻しを確かめる).
    /// </summary>
    internal partial class Lucam : IHwTestAdjustable {

        /// <summary>接続されている Lumenera カメラの台数(SDK が無い・列挙に失敗した場合は例外)</summary>
        internal static int HwTestCountCameras() {
            return dll.LucamNumCameras();
        }

        public string HwTestExposureUnit => "ms(LucamProperty.EXPOSURE)";

        /// <summary>Lucam の露光(LucamProperty.EXPOSURE)は ms 単位の線形の量(検査では ×0.5 / ×2 で 1 段動かす)</summary>
        public HwTestValueScale HwTestExposureScale => HwTestValueScale.Linear;

        public string HwTestGainUnit => "倍率(LucamProperty.GAIN)";

        public HwTestSetting HwTestGetExposure() {
            return GetSetting(dll.LucamProperty.EXPOSURE);
        }

        public void HwTestSetExposure(double value) {
            var range = GetSetting(dll.LucamProperty.EXPOSURE);
            var v = (float)HwTestJudge.Clamp(value, range.Min, range.Max);
            // 以降の SetCameraParam(校正中のホワイトバランス反映)で元に戻されないよう,保持値も更新する
            _snap.Exposure = v;
            SetProperty(dll.LucamProperty.EXPOSURE, v);
        }

        public HwTestSetting HwTestGetGain() {
            return GetSetting(dll.LucamProperty.GAIN);
        }

        public void HwTestSetGain(double value) {
            var range = GetSetting(dll.LucamProperty.GAIN);
            var v = (float)HwTestJudge.Clamp(value, range.Min, range.Max);
            _snap.Gain = v;
            SetProperty(dll.LucamProperty.GAIN, v);
        }

        private HwTestSetting GetSetting(dll.LucamProperty property) {
            if (_hCam == IntPtr.Zero) throw new InvalidOperationException("Lucam が接続されていません");
            if (!dll.LucamGetProperty(_hCam, property, out float value, out dll.LucamPropertyFlag _)) {
                throw new InvalidOperationException($"LucamGetProperty({property}) に失敗しました({dll.LucamGetLastErrorForCamera(_hCam)})");
            }
            if (!dll.LucamPropertyRange(_hCam, property, out float min, out float max, out float _, out dll.LucamPropertyFlag _)) {
                throw new InvalidOperationException($"LucamPropertyRange({property}) に失敗しました({dll.LucamGetLastErrorForCamera(_hCam)})");
            }
            return new HwTestSetting(value, min, max);
        }

        private void SetProperty(dll.LucamProperty property, float value) {
            if (_hCam == IntPtr.Zero) throw new InvalidOperationException("Lucam が接続されていません");
            if (!dll.LucamSetProperty(_hCam, property, value, dll.LucamPropertyFlag.NONE)) {
                throw new InvalidOperationException($"LucamSetProperty({property}, {value}) に失敗しました({dll.LucamGetLastErrorForCamera(_hCam)})");
            }
        }
    }
}
#endif