示例#1
0
        private static void PerformAlignment(SystemServiceClient Service, Func <string, object>[] AlignmentHandlers,
                                             Options opts, string[] Profiles, SSC_PMRangeEnum PMRange, double BreakPowerDiff_dBm,
                                             double BreakPowerMax_dBm = double.MaxValue, int MaxCycle = 5)
        {
            if (AlignmentHandlers.Length != Profiles.Length)
            {
                throw new Exception("Handler和Profile的数量不一致。");
            }

            var cycle     = 0;
            var currPower = Service.__SSC_Powermeter_Read(opts.PowerMeterCaption);
            var lastPower = currPower;

            while (true)
            {
                Service.__SSC_Powermeter_SetRange(opts.PowerMeterCaption, PMRange);

                Thread.Sleep(200);

                for (var i = 0; i < AlignmentHandlers.Length; i++)
                {
                    AlignmentHandlers[i](Profiles[i]);
                }

                Thread.Sleep(200);

                // 计算耦合后和耦合前的功率差值
                currPower = Service.__SSC_Powermeter_Read(opts.PowerMeterCaption);
                var diffPower = currPower - lastPower;
                lastPower = currPower;

                if (double.IsNaN(BreakPowerDiff_dBm) == false)
                {
                    if (diffPower <= BreakPowerDiff_dBm || currPower >= BreakPowerMax_dBm)
                    {
                        // if the delta power is less than 2dB, jump out of the loop.
                        break;
                    }

                    cycle++;
                    if (cycle > MaxCycle)
                    {
                        throw new Exception("初始光太小。");
                    }
                }
                else
                {
                    break;
                }
            }

            // wait until the powermeter is stable.
            Thread.Sleep(500);
        }
示例#2
0
        /// <summary>
        /// Lens慢速线性扫描
        /// </summary>
        /// <param name="Service"></param>
        /// <param name="opts"></param>
        private static void Step3(SystemServiceClient Service, Options opts)
        {
            var cycle = 0;

            Service.__SSC_Powermeter_SetRange(opts.PowerMeterCaption, SSC_PMRangeEnum.AUTO);

            Thread.Sleep(500);

            Service.__SSC_LogInfo("开始执行线性扫描....");

            while (true)
            {
                // PowerMeterAutoRange(Service, PM_CAPTION);

                var pBeforeAlign = Service.__SSC_Powermeter_Read(opts.PowerMeterCaption);

                if (opts.UseHillClimbInLensAlign)
                {
                    Service.__SSC_DoHillClimb(opts.ProfileNameLineScanLens);
                }
                else
                {
                    Service.__SSC_DoProfileND(opts.ProfileNameLineScanLens);
                }

                Thread.Sleep(500);

                var pAfterAlign = Service.__SSC_Powermeter_Read(opts.PowerMeterCaption);
                Service.__SSC_LogInfo($"光功率:{pAfterAlign:F2}dBm");

                var powerDiff = pAfterAlign - pBeforeAlign;
                Service.__SSC_LogInfo($"Power Diff: {powerDiff:F2}dB, {pAfterAlign:F2}dBm/{pBeforeAlign:F2}dBm");

                //if (power > 0 && (powerDiff > -0.2 && powerDiff < 0.2))
                if (powerDiff > opts.PowerThreLineScanN && powerDiff < opts.PowerThreLineScanP)
                {
                    break;
                }
                if (pAfterAlign >= opts.PowerThreTerminate)
                {
                    break;
                }

                cycle++;

                if (cycle > 10)
                {
                    throw new Exception("慢速扫描执行失败,无法找到稳定光功率。");
                }
            }
        }
示例#3
0
        /// <summary>
        /// 执行爬山算法微调
        /// </summary>
        /// <param name="Apas"></param>
        /// <param name="opts"></param>
        private static void Step5(SystemServiceClient Apas, Options opts)
        {
            Apas.__SSC_LogInfo("开始执行最终位置优化...");

            try
            {
                Apas.__SSC_Powermeter_SetRange(opts.PowerMeterCaption, SSC_PMRangeEnum.AUTO);
                if (opts.UseHillClimbInFinalFineTune)
                {
                    Apas.__SSC_DoHillClimb(opts.ProfileNameFinalFineTune);
                }
                else
                {
                    Apas.__SSC_DoProfileND(opts.ProfileNameFinalFineTune);
                }
            }
            catch (Exception)
            {
            }
        }
示例#4
0
        /// <summary>
        /// Receptacle和准直Lens同时调整。
        /// </summary>
        /// <param name="Apas"></param>
        private static void Step4(SystemServiceClient Apas, Options opts)
        {
            var cycle = 0;

            Apas.__SSC_LogInfo("开始Rept和准直Lens双边调整...");

            Apas.__SSC_Powermeter_SetRange(opts.PowerMeterCaption, SSC_PMRangeEnum.AUTO);

            while (true)
            {
                var pBeforeAlign = Apas.__SSC_Powermeter_Read(opts.PowerMeterCaption);

                #region 调整Receptacle

                if (opts.UseProfileNdInReceptLensDualScan == false)
                {
                    Apas.__SSC_Powermeter_SetRange(opts.PowerMeterCaption, SSC_PMRangeEnum.RANGE4);
                    Apas.__SSC_DoFastND(opts.ProfileNameDualLineScanRecept);
                }
                else
                {
                    Apas.__SSC_Powermeter_SetRange(opts.PowerMeterCaption, SSC_PMRangeEnum.AUTO);
                    Apas.__SSC_DoProfileND(opts.ProfileNameDualLineScanRecept);
                }

                #endregion

                Thread.Sleep(200);

                #region 调整Lens

                Apas.__SSC_Powermeter_SetRange(opts.PowerMeterCaption, SSC_PMRangeEnum.AUTO);
                if (opts.UseHillClimbInLensAlign)
                {
                    Apas.__SSC_DoHillClimb(opts.ProfileNameDualLineScanLens);
                }
                else
                {
                    Apas.__SSC_DoProfileND(opts.ProfileNameDualLineScanLens);
                }
                #endregion

                Thread.Sleep(500);

                var pAfterAlign = Apas.__SSC_Powermeter_Read(opts.PowerMeterCaption);
                var pDiff       = pAfterAlign - pBeforeAlign;

                Apas.__SSC_LogInfo($"Power Diff: {pDiff:F2}dB, {pAfterAlign:F2}dBm, {pBeforeAlign:F2}dBm");

                //if (power > 3.5 && (powerDiff > -0.2 && powerDiff < 0.2))
                if (pDiff > opts.PowerThreDualLineScanN && pDiff < opts.PowerThreDualLineScanP)
                {
                    break;
                }
                if (pAfterAlign >= opts.PowerThreTerminate)
                {
                    break;
                }
                if (pDiff < -0.3)
                {
                    break;               // 如果耦合功率开始变小超过-0.3dBm,则停止扫描
                }
                cycle++;

                if (cycle > 10)
                {
                    var msg = "无法调整稳定功率位置。";
                    Apas.__SSC_LogError(msg);
                    throw new Exception(msg);
                }
            }
        }
示例#5
0
        /// <summary>
        ///     The section of the user process.
        ///     用户自定义流程函数。
        ///     Please write your process in the following method.
        ///     请在以下函数中定义您的工艺流程。
        /// </summary>
        /// <param name="Apas"></param>
        /// <returns></returns>
        private static void UserProc(SystemServiceClient Apas, CamRemoteAccessContractClient Camera = null,
                                     Options opts = null)
        {
            try
            {
                Apas.__SSC_LogInfo($"目标功率:{opts.PowerThreTerminate:F2}dBm");

                var sw      = new Stopwatch();
                var swTotal = new Stopwatch();
                swTotal.Start();

                // 初始化功率计状态
                Apas.__SSC_LogInfo("初始化光功率计...");
                Apas.__SSC_Powermeter_SetRange(opts.PowerMeterCaption, SSC_PMRangeEnum.AUTO);
                Apas.__SSC_Powermeter_SetUnit(opts.PowerMeterCaption, SSC_PMUnitEnum.dBm);

                // 等待功率计稳定
                Thread.Sleep(500);


                // 读取初始功率
                var power = Apas.__SSC_Powermeter_Read(opts.PowerMeterCaption);
                Apas.__SSC_LogInfo($"初始光 {power:F2}dBm");


                // STEP 1: RECT Area Scan
                if (power < -25)
                {
                    if (opts.IgnoreBlindSearch == false)
                    {
                        sw.Restart();

                        Step1(Apas, opts);

                        sw.Stop();
                        Apas.__SSC_LogInfo($"耗时: {sw.Elapsed.TotalSeconds:F1}s");
                    }
                    else
                    {
                        Apas.__SSC_LogWarn($"忽略BlindSearch,当前功率:{power:F2}dBm");
                    }
                }


                // Step 2: Fast Focus Scan
                if (power < 0)
                {
                    if (opts.IgnoreFastFocusScan == false)
                    {
                        sw.Restart();

                        Step2(Apas, opts);

                        sw.Stop();
                        Apas.__SSC_LogInfo($"耗时: {sw.Elapsed.TotalSeconds:F1}s");
                    }
                    else
                    {
                        Apas.__SSC_LogWarn($"忽略快速焦距扫描,,当前功率:{power:F2}dBm");
                    }
                }

                // STEP 3: Profile ND to fine-tune.

                // 等待功率计稳定
                Thread.Sleep(500);
                power = Apas.__SSC_Powermeter_Read(opts.PowerMeterCaption);
                if (opts.IgnoreLensProfileScan == false && power < opts.PowerThreTerminate)
                {
                    sw.Restart();

                    Step3(Apas, opts);

                    sw.Stop();
                    Apas.__SSC_LogInfo($"耗时: {sw.Elapsed.TotalSeconds:F1}s");
                }
                else
                {
                    Apas.__SSC_LogWarn($"忽略Lens线性Profile扫描,,当前功率:{power:F2}dBm");
                }

                // STEP 4: 双边耦合
                // 等待功率计稳定
                Thread.Sleep(500);
                power = Apas.__SSC_Powermeter_Read(opts.PowerMeterCaption);
                if (opts.IgnoreReceptLensDualScan == false && power < opts.PowerThreTerminate)
                {
                    sw.Restart();

                    Step4(Apas, opts);

                    sw.Stop();
                    Apas.__SSC_LogInfo($"耗时: {sw.Elapsed.TotalSeconds:F1}s");
                }
                else
                {
                    Apas.__SSC_LogWarn($"忽略Receptacle-Lens双边扫描,,当前功率:{power:F2}dBm");
                }


                // STEP 5: 最终位置优化
                // 等待功率计稳定
                Thread.Sleep(500);
                power = Apas.__SSC_Powermeter_Read(opts.PowerMeterCaption);
                if (opts.IgnoreFinalFineTune == false && power < opts.PowerThreTerminate)
                {
                    sw.Restart();

                    Step5(Apas, opts);

                    sw.Stop();
                    Apas.__SSC_LogInfo($"耗时: {sw.Elapsed.TotalSeconds:F1}s");
                }
                else
                {
                    Apas.__SSC_LogWarn($"忽略最终微调,,当前功率:{power:F2}dBm");
                }

                swTotal.Stop();
                Apas.__SSC_LogInfo($"总耗时: {swTotal.Elapsed.TotalSeconds:F1}s");


                // 检查光功率是否达标
                Apas.__SSC_Powermeter_SetRange(opts.PowerMeterCaption, SSC_PMRangeEnum.AUTO);
                Thread.Sleep(500);

                power = Apas.__SSC_Powermeter_Read(opts.PowerMeterCaption);
                Apas.__SSC_LogInfo($"最终光功率为 {power:F2}dBm");

                if (TARGET_POWER_MIN_DBM <= power)
                {
                    Apas.__SSC_LogInfo("脚本运行完成");
                }
                else
                {
                    var msg = $"无法耦合到目标功率 {TARGET_POWER_MIN_DBM}dBm";
                    Apas.__SSC_LogError(msg);
                    throw new Exception(msg);
                }
            }
            catch (Exception ex)
            {
                //Apas.__SSC_LogError(ex.Message);
                throw new Exception(ex.Message);
            }

            // Thread.Sleep(100);
        }