领胜LDS 键盘AOI检测项目
10个文件已修改
699 ■■■■ 已修改文件
src/Bro.Common.Device/DeviceBase/HDevEngineTool.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/Bro.Common.Model/Model/MotionCardRelated.cs 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/Bro.Device.GTSCard/GTSCardDriver.cs 41 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/Bro.M071.DBManager/ExcelExportHelper.cs 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/Bro.M071.Model/Model/MeasurementUnitResult.cs 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/Bro.M071.Process/Bro.M071.Process.csproj 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/Bro.M071.Process/M071Process.cs 377 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/Bro.M071.Process/M071Process_MotionCard.cs 193 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/Bro.M071.Process/UI/M071_MainForm.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/Bro.M071.Process/packages.config 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/Bro.Common.Device/DeviceBase/HDevEngineTool.cs
@@ -250,7 +250,7 @@
            for (int i = 0; i < tuple.Length; i++)
            {
                list.Add(tuple[i]);
                list.Add(tuple[i].D);
            }
            return list;
src/Bro.Common.Model/Model/MotionCardRelated.cs
@@ -86,6 +86,13 @@
        //[Description("IsUseWarning:是否启用报警")]
        //public bool IsUseWarning { get; set; } = false;
        [Category("原点配置")]
        [DisplayName("回原点参数")]
        [Description("回原点参数")]
        [TypeConverter(typeof(ComplexObjectConvert))]
        [Editor(typeof(PropertyObjectEditor), typeof(UITypeEditor))]
        public GoHomePara GoHomePara { get; set; } = new GoHomePara();
        [Category("暂停配置")]
        [DisplayName("是否启用立即暂停")]
        [Description("IsImmediatePause:是否启用立即暂停")]
@@ -154,25 +161,19 @@
        [Category("回原点参数")]
        [DisplayName("回原点方式")]
        [Description("HomeMode:回原点方式 (HOME_MODE_LIMIT = 10; HOME_MODE_LIMIT_HOME = 11; HOME_MODE_LIMIT_INDEX = 12; HOME_MODE_LIMIT_HOME_INDEX = 13;HOME_MODE_HOME = 20;HOME_MODE_HOME_INDEX = 22;HOME_MODE_INDEX = 30;")]
        public short HomeMode { get; set; } = 11;
        [Category("回原点参数")]
        [DisplayName("回原点方向")]
        [Description("HomeDir:1 正向,-1 负向")]
        public short HomeDir { get; set; } = 1;
        public short HomeMode { get; set; } = 11;
        [Category("回原点参数")]
        [DisplayName("边缘")]
        [Description("edge:边缘")]
        public short Edge { get; set; } = 0;
        [Category("回原点参数")]
        [Category("回原点速度")]
        [DisplayName("回原点最低速度")]
        [Description("LowVelocity:速度,为0时表示不修改当前设置")]
        public double LowVelocity { get; set; } = 50;
        [Category("回原点参数")]
        [Category("回原点速度")]
        [DisplayName("回原点最高速度")]
        [Description("HighVelocity:速度,为0时表示不修改当前设置")]
        public double HighVelocity { get; set; } = 50;
@@ -182,16 +183,30 @@
        //[Description("SearchHomeDistance:搜索距离")]
        //public int SearchHomeDistance { get; set; } = 9999999;
        [Category("回原点参数")]
        [Category("回原点偏移")]
        [DisplayName("偏移距离")]
        [Description("HomeOffset:偏移距离")]
        public int HomeOffset { get; set; } = 0;
        [Category("回原点参数")]
        [Category("回原点偏移")]
        [DisplayName("跳过步长")]
        [Description("EscapeStep:跳过步长")]
        public int EscapeStep { get; set; } = 1000;
        [Category("回原点方向")]
        [DisplayName("起始运动方向")]
        [Description("回原点时,轴的初始运动方向:true 正向,false 负向")]
        public bool IsHomeDirPositive { get; set; } = true;
        [Category("回原点方向")]
        [DisplayName("原点捕捉方向")]
        [Description("捕捉原点时,轴的运动方向:true 正向,false 负向")]
        public bool IsCaptureDirPositive { get; set; } = true;
        [Category("回原点超时")]
        [DisplayName("回原点超时")]
        [Description("回原点超时,单位秒")]
        public int GoHomeTimeOut { get; set; } = 60;
    }
    /// <summary>
@@ -352,12 +367,12 @@
        //}
        //private GoHomePara goHomePara = new GoHomePara();
        [Category("运动配置")]
        [DisplayName("回原点参数")]
        [Description("GoHomePara:速度参数")]
        [TypeConverter(typeof(ComplexObjectConvert))]
        [Editor(typeof(PropertyObjectEditor), typeof(UITypeEditor))]
        public GoHomePara GoHomePara { get; set; } = new GoHomePara();
        //[Category("运动配置")]
        //[DisplayName("回原点参数")]
        //[Description("GoHomePara:速度参数")]
        //[TypeConverter(typeof(ComplexObjectConvert))]
        //[Editor(typeof(PropertyObjectEditor), typeof(UITypeEditor))]
        //public GoHomePara GoHomePara { get; set; } = new GoHomePara();
        //{
        //    get => goHomePara;
        //    set
src/Bro.Device.GTSCard/GTSCardDriver.cs
@@ -888,7 +888,11 @@
        {
            try
            {
                StartCapture:
                var goHomePara = IConfig.AxisSettings.FirstOrDefault(u => u.AxisIndex == movingOption.AxisIndex).GoHomePara;
                bool homeDirection = goHomePara.IsHomeDirPositive;
                bool isRightLimitReached = false;
            StartCapture:
                PositionReset(movingOption.AxisIndex, 1);
                ClearStatus(movingOption.AxisIndex, 1);
@@ -907,24 +911,24 @@
                // 设置点位模式运动参数
                sRtn = GTSCardAPI.GT_SetTrapPrm((short)IConfig.CardNum, (short)movingOption.AxisIndex, ref trapPrm);
                // 设置点位模式目标速度,即回原点速度
                sRtn = GTSCardAPI.GT_SetVel((short)IConfig.CardNum, (short)movingOption.AxisIndex, movingOption.GoHomePara.HighVelocity);
                sRtn = GTSCardAPI.GT_SetVel((short)IConfig.CardNum, (short)movingOption.AxisIndex, goHomePara.HighVelocity);
                // 设置点位模式目标位置,即原点搜索距离
                sRtn = GTSCardAPI.GT_SetPos((short)IConfig.CardNum, (short)movingOption.AxisIndex, movingOption.GoHomePara.HomeDir == 1 ? 99999999 : -99999999);
                sRtn = GTSCardAPI.GT_SetPos((short)IConfig.CardNum, (short)movingOption.AxisIndex, homeDirection ? 99999999 : -99999999);
                // 启动运动
                sRtn = GTSCardAPI.GT_Update((short)IConfig.CardNum, 1 << (movingOption.AxisIndex - 1));
                int repeatTime = 1000;
                int repeatTime = goHomePara.GoHomeTimeOut * 1000;
                short capture;
                int pos;
                uint clk;//时钟参数
                do
                {
                    Thread.Sleep(20);
                    Thread.Sleep(IConfig.MonitorInterval);
                    // 读取捕获状态
                    GTSCardAPI.GT_GetCaptureStatus((short)IConfig.CardNum, (short)movingOption.AxisIndex, out capture, out pos, 1, out clk);
                    isStop = IsStop((short)movingOption.AxisIndex);
                    repeatTime--;
                    repeatTime -= IConfig.MonitorInterval;
                } while (!(isStop || capture == 1 || repeatTime <= 0));
                if (repeatTime <= 0)
@@ -941,7 +945,22 @@
                    if (((axisStatus.AxisStatus & 0x20) != 0) || ((axisStatus.AxisStatus & 0x40) != 0))
                    {
                        movingOption.GoHomePara.HomeDir = (short)(movingOption.GoHomePara.HomeDir == 1 ? -1 : 1);
                        //movingOption.GoHomePara.HomeDir = (short)(movingOption.GoHomePara.HomeDir == 1 ? -1 : 1);
                        //正限位
                        if ((axisStatus.AxisStatus & 0x20) != 0 && !goHomePara.IsCaptureDirPositive)
                        {
                            isRightLimitReached = true;
                        }
                        //负限位
                        if ((axisStatus.AxisStatus & 0x40) != 0 && goHomePara.IsCaptureDirPositive)
                        {
                            isRightLimitReached = true;
                        }
                        homeDirection = !homeDirection;
                        goto StartCapture;
                    }
@@ -950,12 +969,18 @@
                if (capture == 1)
                {
                    if (!isRightLimitReached)
                    {
                        capture = 0;
                        goto StartCapture;
                    }
                    //先stop
                    MoveStop((short)movingOption.AxisIndex, 0);
                    ClearStatus((short)movingOption.AxisIndex, 1);
                    //已经捕获到Home才可以回零 阶段2
                    // 运动到"捕获位置+偏移量"
                    sRtn = GTSCardAPI.GT_SetPos((short)IConfig.CardNum, (short)movingOption.AxisIndex, pos + movingOption.GoHomePara.HomeOffset);
                    sRtn = GTSCardAPI.GT_SetPos((short)IConfig.CardNum, (short)movingOption.AxisIndex, pos + goHomePara.HomeOffset);
                    // 在运动状态下更新目标位置
                    sRtn = GTSCardAPI.GT_Update((short)IConfig.CardNum, 1 << (movingOption.AxisIndex - 1));
                    isStop = false;
src/Bro.M071.DBManager/ExcelExportHelper.cs
@@ -12,20 +12,23 @@
    public class ExcelExportSet
    {
        public List<string> Worksheets { get; set; }
        public List<string> Worksheets { get; set; } = new List<string>();
        /// <summary>
        /// Key: Worksheet的名称 Value:Worksheet对应的列名集合(key 为要导出的列名 value 为导出后显示的列名)
        /// </summary>
        public Dictionary<string, Dictionary<string, string>> WorksheetColumns { get; set; }
        public Dictionary<string, DataTable> WorksheetDataTable { get; set; }
        public Dictionary<string, Dictionary<string, string>> WorksheetColumns { get; set; } = new Dictionary<string, Dictionary<string, string>>();
        public ExcelExportSet()
        {
            Worksheets = new List<string>();
            WorksheetColumns = new Dictionary<string, Dictionary<string, string>>();
            WorksheetDataTable = new Dictionary<string, DataTable>();
        }
        public Dictionary<string, Dictionary<string, string>> WorksheetRows { get; set; } = new Dictionary<string, Dictionary<string, string>>();
        public Dictionary<string, DataTable> WorksheetDataTable { get; set; } = new Dictionary<string, DataTable>();
        //public ExcelExportSet()
        //{
        //    Worksheets = new List<string>();
        //    WorksheetColumns = new Dictionary<string, Dictionary<string, string>>();
        //    WorksheetDataTable = new Dictionary<string, DataTable>();
        //}
    }
@@ -265,6 +268,7 @@
                return "";
            }
        }
    }
}
src/Bro.M071.Model/Model/MeasurementUnitResult.cs
@@ -48,6 +48,10 @@
        public string ProductionCode { get; set; }
        [NotMapped]
        public string ProductionBarcode { get; set; }
        [NotMapped]
        public string Keys { get; set; }
        [NotMapped]
        public string Positions { get; set; }
    }
    public class MeasurementUnitResultRequest : BaseRequest
src/Bro.M071.Process/Bro.M071.Process.csproj
@@ -81,6 +81,9 @@
    <Reference Include="Autofac, Version=4.9.4.0, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL">
      <HintPath>..\..\packages\Autofac.4.9.4\lib\net45\Autofac.dll</HintPath>
    </Reference>
    <Reference Include="EPPlus, Version=4.5.3.3, Culture=neutral, PublicKeyToken=ea159fdaa78159a1, processorArchitecture=MSIL">
      <HintPath>..\..\packages\EPPlus.4.5.3.3\lib\net40\EPPlus.dll</HintPath>
    </Reference>
    <Reference Include="halcondotnet, Version=12.0.0.0, Culture=neutral, PublicKeyToken=4973bed59ddbf2b8, processorArchitecture=MSIL">
      <SpecificVersion>False</SpecificVersion>
      <HintPath>..\..\libs\halcon12\halcondotnet.dll</HintPath>
@@ -95,8 +98,11 @@
    <Reference Include="PostSharp, Version=6.2.7.0, Culture=neutral, PublicKeyToken=b13fd38b8f9c99d7, processorArchitecture=MSIL">
      <HintPath>..\..\packages\PostSharp.Redist.6.2.7\lib\net45\PostSharp.dll</HintPath>
    </Reference>
    <Reference Include="PresentationCore" />
    <Reference Include="System" />
    <Reference Include="System.configuration" />
    <Reference Include="System.Core" />
    <Reference Include="System.Security" />
    <Reference Include="System.Xml.Linq" />
    <Reference Include="System.Data.DataSetExtensions" />
    <Reference Include="Microsoft.CSharp" />
src/Bro.M071.Process/M071Process.cs
@@ -9,6 +9,8 @@
using Bro.Process;
using HalconDotNet;
using Newtonsoft.Json;
using OfficeOpenXml;
using OfficeOpenXml.Style;
using System;
using System.Collections.Generic;
using System.ComponentModel;
@@ -270,7 +272,7 @@
                          return;
                      }
                      RunImageHandle(camera, s.CameraOp.OpConfig, set, s.Id, s.Name, pMeasure.Measurements);
                      RunImageHandle(s.CameraOp.OpConfig, set, s.Id, s.Name, pMeasure.Measurements);
                  });
            BarCode = "";
@@ -374,7 +376,7 @@
                                        }
                                        else
                                        {
                                            m.Spec.ActualValue = _halconToolDict[toolKey].GetResultTuple("OUTPUT_Result").D;
                                            m.Spec.ActualValue = double.Parse(_halconToolDict[toolKey].GetResultTuple("OUTPUT_Result").D.ToString("f2"));
                                            LogAsync(DateTime.Now, $"{m.GetDisplayText()}数据{m.Spec.ActualValue},结果{(m.Spec.MeasureResult == null ? "TBD" : (m.Spec.MeasureResult == true ? "OK" : "NG"))}", "");
                                        }
                                    }
@@ -421,7 +423,9 @@
                }
                //Excel报表输出 (单个产品的excel导出)
                ExportProductionExcel(measurementUnitResultAndKeyUnitDataSet);
                //ExportProductionExcel(measurementUnitResultAndKeyUnitDataSet);
                ExportProductionInColumns(measurementUnitResultAndKeyUnitDataSet);
                ////数据库保存 
                //SaveProductionData(measurementUnitResultAndKeyUnitDataSet);
@@ -501,8 +505,19 @@
                    measurementUnitResult.ProductionMeasurementRecordsId = productionMeasurementRecords.ID;
                    measurementUnitResult.ProductionBarcode = productionMeasurementRecords.ProductionBarcode;
                    measurementUnitResult.MeasurementName = measurementUnit.GetDisplayText();
                    if (measurementUnit.MeasureType == "Alignment" || measurementUnit.MeasureType == "Slant")
                    {
                        measurementUnitResult.Keys = string.Join("-", measurementUnit.KeyUnitCollection.Select(u => u.Key));
                        measurementUnitResult.Positions = string.Join("-", measurementUnit.KeyUnitCollection.Select(u => u.KeyResultId));
                    }
                    else if (measurementUnit.MeasureType == "RowAlignment")
                    {
                        measurementUnitResult.Keys = measurementUnit.KeyUnitCollection[0].Key + "~" + measurementUnit.KeyUnitCollection[measurementUnit.KeyUnitCollection.Count() - 1].Key;
                        measurementUnitResult.Keys = measurementUnit.KeyUnitCollection[0].KeyResultId + "~" + measurementUnit.KeyUnitCollection[measurementUnit.KeyUnitCollection.Count() - 1].KeyResultId;
                    }
                    measurementUnitResult.MeasurementType = measurementUnit.MeasureType;
                    measurementUnitResult.MeasurementValue = measurementUnit.Spec.ActualValue.ToString();
                    measurementUnitResult.MeasurementValue = measurementUnit.Spec.ActualValue == null ? "NA" : measurementUnit.Spec.ActualValue.Value.ToString("f2");
                    measurementUnitResult.MeasurementResult = measurementUnit.Spec.MeasureResult.Value ? "OK" : "NG";
                    measurementUnitResults.Add(measurementUnitResult);
@@ -518,7 +533,7 @@
                                keyUnitData.ProductionBarcode = productionMeasurementRecords.ProductionBarcode;
                                keyUnitData.Key = keyUnit.Key;
                                keyUnitData.MeasurementItem = keyValue.Key;
                                keyUnitData.ItemValue = keyValue.Value.ToString();
                                keyUnitData.ItemValue = keyValue.Value == null ? "NA" : keyValue.Value.Value.ToString("f2");
                                keyUnitDatas.Add(keyUnitData);
                                MeasurementAndKeyDataRelation measurementAndKeyDataRelation = new MeasurementAndKeyDataRelation();
@@ -583,6 +598,342 @@
                fs.Flush();
                fs.Close();
            });
        }
        static object excelExportLock = new object();
        private async void ExportProductionInColumns(ProductionMeasurementUnitResultAndKeyUnitDataSet exportData)
        {
            if (!Config.IsCSVOutputEnabled)
                return;
            await Task.Run(() =>
            {
                lock (excelExportLock)
                {
                    if (!Directory.Exists(Config.LogPath))
                    {
                        Directory.CreateDirectory(Config.LogPath);
                    }
                    var fileName = Path.Combine(Config.LogPath, $"LDSData_{DateTime.Now.ToString("yyyyMMdd")}.xlsx");
                    //bool isExisted = File.Exists(fileName);
                    using (ExcelPackage package = new ExcelPackage(new FileInfo(fileName)))
                    {
                        ExcelWorksheet rawDataSheet = null;
                        ExcelWorksheet slantSheet = null;
                        ExcelWorksheet alignmentSheet = null;
                        ExcelWorksheet rowAlignmentSheet = null;
                        if (!package.Workbook.Worksheets.Any(s => s.Name == "RawData"))
                        {
                            package.Workbook.Worksheets.Add("RawData");
                            rawDataSheet = package.Workbook.Worksheets["RawData"];
                            for (int i = 0; i < Config.KeyNameCollection.Count; i++)
                            {
                                var cell = rawDataSheet.Cells[i + 3, 1];
                                cell.Value = Config.KeyNameCollection[i];
                                SetTitleCell(cell, false);
                            }
                        }
                        rawDataSheet = package.Workbook.Worksheets["RawData"];
                        if (!package.Workbook.Worksheets.Any(s => s.Name == "Slant"))
                        {
                            package.Workbook.Worksheets.Add("Slant");
                            slantSheet = package.Workbook.Worksheets["Slant"];
                            var keyCell = slantSheet.Cells[2, 1];
                            keyCell.Value = "Key";
                            SetTitleCell(keyCell);
                            for (int i = 0; i < Config.KeyNameCollection.Count; i++)
                            {
                                var cell = slantSheet.Cells[i + 3, 1];
                                cell.Value = Config.KeyNameCollection[i];
                                SetTitleCell(cell, false);
                            }
                        }
                        slantSheet = package.Workbook.Worksheets["Slant"];
                        if (!package.Workbook.Worksheets.Any(s => s.Name == "Alignment"))
                        {
                            package.Workbook.Worksheets.Add("Alignment");
                            alignmentSheet = package.Workbook.Worksheets["Alignment"];
                            var keysCell = alignmentSheet.Cells[2, 1];
                            keysCell.Value = "Keys";
                            SetTitleCell(keysCell);
                            var positionCell = alignmentSheet.Cells[2, 2];
                            positionCell.Value = "Positions";
                            SetTitleCell(positionCell);
                            var alignmentMeasures = exportData.MeasurementUnitResultList.Where(u => u.MeasurementType == "Alignment").ToList();
                            for (int i = 0; i < alignmentMeasures.Count(); i++)
                            {
                                var cellKeys = alignmentSheet.Cells[i + 3, 1];
                                cellKeys.Value = alignmentMeasures[i].Keys;
                                SetTitleCell(cellKeys, false);
                                var cellPosition = alignmentSheet.Cells[i + 3, 2];
                                cellPosition.Value = alignmentMeasures[i].Positions;
                                SetTitleCell(cellPosition, false);
                            }
                        }
                        alignmentSheet = package.Workbook.Worksheets["Alignment"];
                        if (!package.Workbook.Worksheets.Any(s => s.Name == "RowAlignment"))
                        {
                            package.Workbook.Worksheets.Add("RowAlignment");
                            rowAlignmentSheet = package.Workbook.Worksheets["RowAlignment"];
                            var keysCell = rowAlignmentSheet.Cells[2, 1];
                            keysCell.Value = "Keys";
                            SetTitleCell(keysCell);
                            var positionCell = rowAlignmentSheet.Cells[2, 2];
                            positionCell.Value = "Positions";
                            SetTitleCell(positionCell);
                            var rowAlignmentMeasures = exportData.MeasurementUnitResultList.Where(u => u.MeasurementType == "RowAlignment").ToList();
                            for (int i = 0; i < rowAlignmentMeasures.Count(); i++)
                            {
                                var cellKeys = rowAlignmentSheet.Cells[i + 3, 1];
                                cellKeys.Value = rowAlignmentMeasures[i].Keys;
                                SetTitleCell(cellKeys, false);
                                var cellPosition = rowAlignmentSheet.Cells[i + 3, 2];
                                cellPosition.Value = rowAlignmentMeasures[i].Positions;
                                SetTitleCell(cellPosition, false);
                            }
                        }
                        rowAlignmentSheet = package.Workbook.Worksheets["RowAlignment"];
                        #region RawData
                        {
                            //rawDataSheet = package.Workbook.Worksheets["RawData"];
                            int rowDataStartCol = rawDataSheet.Dimension.Columns;
                            var barcodeCell = rawDataSheet.Cells[1, rowDataStartCol + 1, 1, rowDataStartCol + 4];
                            barcodeCell.Merge = true;
                            barcodeCell.Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;
                            barcodeCell.Value = exportData.ProductionMeasurementRecord.ProductionBarcode;
                            SetTitleCell(barcodeCell);
                            var z1Cell = rawDataSheet.Cells[2, rowDataStartCol + 1];
                            z1Cell.Value = "Z1";
                            SetTitleCell(z1Cell);
                            var z2Cell = rawDataSheet.Cells[2, rowDataStartCol + 2];
                            z2Cell.Value = "Z2";
                            SetTitleCell(z2Cell);
                            var z3Cell = rawDataSheet.Cells[2, rowDataStartCol + 3];
                            z3Cell.Value = "Z3";
                            SetTitleCell(z3Cell);
                            var z4Cell = rawDataSheet.Cells[2, rowDataStartCol + 4];
                            z4Cell.Value = "Z4";
                            SetTitleCell(z4Cell);
                            exportData.KeyUnitDataList.ForEach(k =>
                            {
                                int keyIndex = Config.KeyNameCollection.IndexOf(k.Key);
                                if (keyIndex < 0)
                                {
                                    LogAsync(DateTime.Now, "Excel导出错误", $"{k.Key}的RawData未能获取行信息,未导出");
                                    return;
                                }
                                int zIndex = int.Parse(k.MeasurementItem.Substring(1));
                                var cell = rawDataSheet.Cells[keyIndex + 1 + 2, rowDataStartCol + zIndex];
                                cell.Value = string.IsNullOrWhiteSpace(k.ItemValue) ? "NA" : k.ItemValue;
                            });
                        }
                        #endregion
                        #region Slant
                        var slantMeasures = exportData.MeasurementUnitResultList.Where(u => u.MeasurementType == "Slant").ToList();
                        if (slantMeasures.Count > 0)
                        {
                            int slantStartCol = slantSheet.Dimension.Columns;
                            var barcodeCell = slantSheet.Cells[1, slantStartCol + 1, 1, slantStartCol + 2];
                            barcodeCell.Merge = true;
                            barcodeCell.Value = exportData.ProductionMeasurementRecord.ProductionBarcode;
                            SetTitleCell(barcodeCell);
                            var valueCell = slantSheet.Cells[2, slantStartCol + 1];
                            valueCell.Value = "Value";
                            SetTitleCell(valueCell);
                            var resultCell = slantSheet.Cells[2, slantStartCol + 2];
                            resultCell.Value = "Result";
                            SetTitleCell(resultCell);
                            slantMeasures.ForEach(m =>
                            {
                                int rowIndex = Config.KeyNameCollection.IndexOf(m.Keys);
                                if (rowIndex < 0)
                                {
                                    LogAsync(DateTime.Now, "Excel导出错误", $"{m.Keys}的Slant未能获取行信息,未导出");
                                    return;
                                }
                                var cellValue = slantSheet.Cells[rowIndex + 1 + 2, slantStartCol + 1];
                                var cellResult = slantSheet.Cells[rowIndex + 1 + 2, slantStartCol + 2];
                                cellValue.Value = m.MeasurementValue;
                                cellResult.Value = m.MeasurementResult;
                                if (m.MeasurementResult != "OK")
                                {
                                    SetNGCell(cellValue);
                                    SetNGCell(cellResult);
                                }
                            });
                        }
                        #endregion
                        #region Alignment
                        {
                            var alignmentMeasures = exportData.MeasurementUnitResultList.Where(u => u.MeasurementType == "Alignment").ToList();
                            if (alignmentMeasures.Count > 0)
                            {
                                List<string> keysList = new List<string>();
                                int allRowNums = alignmentSheet.Dimension.Rows;
                                int aligneStartCol = alignmentSheet.Dimension.Columns;
                                for (int i = 3; i <= allRowNums; i++)
                                {
                                    string keys = alignmentSheet.Cells[i, 1].Value.ToString();
                                    string position = alignmentSheet.Cells[i, 2].Value.ToString();
                                    keysList.Add($"{keys}_{position}");
                                }
                                var barcodeCell = alignmentSheet.Cells[1, aligneStartCol + 1, 1, aligneStartCol + 2];
                                barcodeCell.Merge = true;
                                barcodeCell.Value = exportData.ProductionMeasurementRecord.ProductionBarcode;
                                SetTitleCell(barcodeCell);
                                var valueCell = alignmentSheet.Cells[2, aligneStartCol + 1];
                                valueCell.Value = "Value";
                                SetTitleCell(valueCell);
                                var resultCell = alignmentSheet.Cells[2, aligneStartCol + 2];
                                resultCell.Value = "Result";
                                SetTitleCell(resultCell);
                                alignmentMeasures.ForEach(a =>
                                {
                                    int rowIndex = keysList.IndexOf($"{a.Keys}_{a.Positions}");
                                    if (rowIndex < 0)
                                    {
                                        LogAsync(DateTime.Now, "Excel导出错误", $"{a.Keys}_{a.Positions}的Alignment未能获取行信息,未导出");
                                        return;
                                    }
                                    var cellValue = alignmentSheet.Cells[rowIndex + 1 + 2, aligneStartCol + 1];
                                    var cellResult = alignmentSheet.Cells[rowIndex + 1 + 2, aligneStartCol + 2];
                                    cellValue.Value = a.MeasurementValue;
                                    cellResult.Value = a.MeasurementResult;
                                    if (a.MeasurementResult != "OK")
                                    {
                                        SetNGCell(cellValue);
                                        SetNGCell(cellResult);
                                    }
                                });
                            }
                        }
                        #endregion
                        #region RowAlignment
                        {
                            var rowAlignmentMeasures = exportData.MeasurementUnitResultList.Where(u => u.MeasurementType == "RowAlignment").ToList();
                            if (rowAlignmentMeasures.Count > 0)
                            {
                                List<string> keysList = new List<string>();
                                int allRowNums = rowAlignmentSheet.Dimension.Rows;
                                int aligneStartCol = rowAlignmentSheet.Dimension.Columns;
                                for (int i = 3; i <= allRowNums; i++)
                                {
                                    string keys = alignmentSheet.Cells[i, 1].Value.ToString();
                                    string position = alignmentSheet.Cells[i, 2].Value.ToString();
                                    keysList.Add($"{keys}_{position}");
                                }
                                var barcodeCell = rowAlignmentSheet.Cells[1, aligneStartCol + 1, 1, aligneStartCol + 2];
                                barcodeCell.Merge = true;
                                barcodeCell.Value = exportData.ProductionMeasurementRecord.ProductionBarcode;
                                SetTitleCell(barcodeCell);
                                var valueCell = rowAlignmentSheet.Cells[2, aligneStartCol + 1];
                                valueCell.Value = "Value";
                                SetTitleCell(valueCell);
                                var resultCell = rowAlignmentSheet.Cells[2, aligneStartCol + 2];
                                resultCell.Value = "Result";
                                SetTitleCell(resultCell);
                                rowAlignmentMeasures.ForEach(a =>
                                {
                                    int rowIndex = keysList.IndexOf($"{a.Keys}_{a.Positions}");
                                    if (rowIndex < 0)
                                    {
                                        LogAsync(DateTime.Now, "Excel导出错误", $"{a.Keys}_{a.Positions}的RowAlignment未能获取行信息,未导出");
                                        return;
                                    }
                                    var cellValue = rowAlignmentSheet.Cells[rowIndex + 1 + 2, aligneStartCol + 1];
                                    var cellResult = rowAlignmentSheet.Cells[rowIndex + 1 + 2, aligneStartCol + 2];
                                    cellValue.Value = a.MeasurementValue;
                                    cellResult.Value = a.MeasurementResult;
                                    if (a.MeasurementResult != "OK")
                                    {
                                        SetNGCell(cellValue);
                                        SetNGCell(cellResult);
                                    }
                                });
                            }
                        }
                        #endregion
                        package.Save();
                    };
                }
            });
        }
        private void SetNGCell(ExcelRange cell)
        {
            cell.Style.Font.Color.SetColor(Color.White);
            cell.Style.Font.Bold = true;
            cell.Style.Fill.PatternType = ExcelFillStyle.Solid;
            cell.Style.Fill.BackgroundColor.SetColor(Color.Red);
        }
        private void SetTitleCell(ExcelRange cell, bool isCenterAlign = true)
        {
            cell.Style.Font.Color.SetColor(Color.White);
            cell.Style.Font.Bold = true;
            cell.Style.Fill.PatternType = ExcelFillStyle.Solid;
            cell.Style.Fill.BackgroundColor.SetColor(Color.FromArgb(31, 73, 125));
            cell.AutoFitColumns();
            if (isCenterAlign)
            {
                cell.Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;
            }
            else
            {
                cell.Style.HorizontalAlignment = ExcelHorizontalAlignment.Left;
            }
        }
        #region 图像保存
@@ -676,7 +1027,7 @@
        }
        #endregion
        private async void RunImageHandle(CameraBase camera, IOperationConfig opConfig, IImageSet imgSet, string snapshotId, string snapshotName, List<MeasurementUnit> measureList)
        private async void RunImageHandle(IOperationConfig opConfig, IImageSet imgSet, string snapshotId, string snapshotName, List<MeasurementUnit> measureList)
        {
            await Task.Run(() =>
             {
@@ -697,6 +1048,9 @@
                         keyBindCollection.ForEach(k => k.FillKeyValues(null));
                         return;
                     }
                     string fileName = Path.Combine(Config.ImageSaveFolder, "BeforeRun", $"{DateTime.Now.ToString("yyyyMMddHHmmssfff")}.tif");
                     imgSet.HImage.WriteImage("tiff", 0, fileName);
                     _halconToolDict[toolKey].InputImageDic["INPUT_Image"] = imgSet.HImage;
                     if (!_halconToolDict[toolKey].RunProcedure(out string error))
@@ -741,7 +1095,10 @@
                     HOperatorSet.SelectObj(images, out HObject image, i);
                     string fileName = Path.Combine(dir, $"{i}.tif");
                     image.ConvertHObjectToHImage().WriteImage("tiff", 0, fileName);
                     using (HImage temp = image.ConvertHObjectToHImage())
                     {
                         temp.WriteImage("tiff", 0, fileName);
                     }
                     keys.Where(u => u.ImageSeq == i).ToList().ForEach(k =>
                         {
@@ -759,19 +1116,21 @@
                                 _halconToolDict[keyToolKey].InputImageDic["INPUT_Image"] = image;
                                 _halconToolDict[keyToolKey].InputTupleDic["INPUT_Resolution_X"] = scanParam.Resolution_X / 1000000.0;
                                 _halconToolDict[keyToolKey].InputTupleDic["INPUT_Resolution_Z"] = scanParam.Resolution_Z / 1000000.0;
                                 _halconToolDict[keyToolKey].InputTupleDic["INPUT_ImageId"] = $"{k.AliasName}_{DateTime.Now.ToString("HHmmssfff")}.tif";
                                 if (!_halconToolDict[keyToolKey].RunProcedure(out string error))
                                 {
                                     LogAsync(DateTime.Now, $"{k.AliasName}检测算法异常,{error}", "");
                                 }
                                 else
                                 {
                                     var results = _halconToolDict[keyToolKey].GetResultTuple("OUTPUT_Results").HTupleToDouble();
                                     var results = _halconToolDict[keyToolKey].GetResultTuple("OUTPUT_Results").DArr.ToList();
                                     if (results.Count == 0 || results.Any(u => u < 0))
                                     {
                                         LogAsync(DateTime.Now, $"{k.AliasName}原始数据异常", "");
                                     }
                                     else
                                     {
                                         //results = results.Select(u => double.Parse(u.ToString("f2"))).ToList();
                                         LogAsync(DateTime.Now, $"{k.AliasName}原始数据", $"{string.Join(" ", results)}");
                                         resultDict = k.KeyResultList.ToDictionary(u => u, u =>
                                              {
@@ -789,7 +1148,7 @@
                             });
                         });
                     //image.Dispose();
                     image.Dispose();
                 }
                 //);
src/Bro.M071.Process/M071Process_MotionCard.cs
@@ -30,112 +30,102 @@
                if (machineState == value)
                    return;
                //_machineStatePre = machineState;
                machineState = value;
                switch (machineState)
                Task.Run(() =>
                {
                    case MachineState.Ready:
                        lock (machineStateLock)
                        {
                            SwitchBeep(false);
                            SwitchLightRed(false);
                            SwitchLightYellow(false);
                        }
                        Task.Run(() =>
                        {
                            while (MachineState == MachineState.Ready)
                    switch (machineState)
                    {
                        case MachineState.Ready:
                            lock (machineStateLock)
                            {
                                lock (machineStateLock)
                                {
                                    SwitchLightGreen(true);
                                    Thread.Sleep(1000);
                                    SwitchLightGreen(false);
                                    Thread.Sleep(1000);
                                }
                                SwitchBeep(false);
                                SwitchLightRed(false);
                                SwitchLightYellow(false);
                            }
                        });
                        break;
                    case MachineState.Running:
                        lock (machineStateLock)
                        {
                            SwitchBeep(false);
                            SwitchLightRed(false);
                            SwitchLightYellow(false);
                            SwitchLightGreen(true);
                        }
                        break;
                    case MachineState.Alarm:
                        lock (machineStateLock)
                        {
                            SwitchBeep(true);
                            SwitchLightRed(true);
                            SwitchLightYellow(false);
                            SwitchLightGreen(false);
                        }
                        break;
                    case MachineState.Pause:
                        lock (machineStateLock)
                        {
                            SwitchBeep(false);
                            SwitchLightRed(false);
                        }
                        Task.Run(() =>
                        {
                            while (MachineState == MachineState.Pause)
                            Task.Run(() =>
                            {
                                lock (machineStateLock)
                                while (MachineState == MachineState.Ready)
                                {
                                    SwitchLightYellow(true);
                                    SwitchLightGreen(true);
                                    Thread.Sleep(1000);
                                    SwitchLightYellow(false);
                                    SwitchLightGreen(false);
                                    Thread.Sleep(1000);
                                    lock (machineStateLock)
                                    {
                                        SwitchLightGreen(true);
                                        Thread.Sleep(1000);
                                        SwitchLightGreen(false);
                                        Thread.Sleep(1000);
                                    }
                                }
                            }
                        });
                        break;
                    case MachineState.Resetting:
                        lock (machineStateLock)
                        {
                            SwitchBeep(false);
                            SwitchLightRed(false);
                            SwitchLightGreen(false);
                        }
                        Task.Run(() =>
                        {
                            while (MachineState == MachineState.Resetting)
                            {
                                lock (machineStateLock)
                                {
                            });
                                    SwitchLightYellow(true);
                                    Thread.Sleep(1000);
                                    SwitchLightYellow(false);
                                    Thread.Sleep(1000);
                                }
                            break;
                        case MachineState.Running:
                            lock (machineStateLock)
                            {
                                SwitchBeep(false);
                                SwitchLightRed(false);
                                SwitchLightYellow(false);
                                SwitchLightGreen(true);
                            }
                        });
                        break;
                    default:
                        break;
                }
                            break;
                        case MachineState.Alarm:
                            lock (machineStateLock)
                            {
                                SwitchBeep(true);
                                SwitchLightRed(true);
                                SwitchLightYellow(false);
                                SwitchLightGreen(false);
                            }
                            break;
                        case MachineState.Pause:
                            lock (machineStateLock)
                            {
                                SwitchBeep(false);
                                SwitchLightRed(false);
                            }
                            Task.Run(() =>
                            {
                                while (MachineState == MachineState.Pause)
                                {
                                    lock (machineStateLock)
                                    {
                                        SwitchLightYellow(true);
                                        SwitchLightGreen(true);
                                        Thread.Sleep(1000);
                                        SwitchLightYellow(false);
                                        SwitchLightGreen(false);
                                        Thread.Sleep(1000);
                                    }
                                }
                            });
                            break;
                        case MachineState.Resetting:
                            lock (machineStateLock)
                            {
                                SwitchBeep(false);
                                SwitchLightRed(false);
                                SwitchLightGreen(false);
                            }
                            Task.Run(() =>
                            {
                                while (MachineState == MachineState.Resetting)
                                {
                                    lock (machineStateLock)
                                    {
                                        SwitchLightYellow(true);
                                        Thread.Sleep(1000);
                                        SwitchLightYellow(false);
                                        Thread.Sleep(1000);
                                    }
                                }
                            });
                            break;
                        default:
                            break;
                    }
                });
                OnMachineStateChanged?.Invoke(machineState);
                //if (_machineStatePre == MachineState.Running && machineState == MachineState.Pause)
                //{
                //    Pause();
                //}
                //else if (_machineStatePre == MachineState.Pause && (machineState == MachineState.Running || machineState == MachineState.Ready))
                //{
                //    Resume();
                //}
            }
        }
@@ -653,13 +643,16 @@
        ManualResetEventSlim _pausedHandle = new ManualResetEventSlim(true);
        MachineState _machineStateBeforePause = MachineState.Unknown;
        private async void CheckMachinePauseState()
        private void CheckMachinePauseState()
        {
            await Task.Run(() =>
            //await Task.Run(() =>
            {
                if (IsMachinePaused)
                {
                    _machineStateBeforePause = MachineState;
                    if (MachineState == MachineState.Ready || MachineState == MachineState.Running)
                    {
                        _machineStateBeforePause = MachineState;
                    }
                    MachineState = MachineState.Pause;
                    _pausedHandle.Reset();
@@ -681,7 +674,8 @@
                        MachineState = _machineStateBeforePause;
                    }
                }
            });
            }
            //);
        }
        public bool IsMachinePaused
@@ -711,9 +705,6 @@
        [ProcessMethod("", "SafetyBeamSignal", "安全光幕信号监控,正常ON,OFF时报警", InvokeType.TestInvoke)]
        public ProcessResponse SafetyBeamSignal(IOperationConfig opConfig, IDevice invokeDevice, IDevice sourceDevice)
        {
            //if (MachineState != MachineState.Running && MachineState != MachineState.Pause)
            //    return new ProcessResponse(true);
            if (opConfig.InputPara == null || opConfig.InputPara.Count == 0)
                throw new ProcessException("安全光幕监控未配置输入信号");
@@ -756,7 +747,7 @@
            IsEmergencyStopped = opConfig.InputPara[0] == 0;
            if (IsEmergencyStopped)
            if (isEmergencyStopped)
            {
                RaisedAlarm("急停按钮被拍下");
                MachineState = MachineState.Alarm;
src/Bro.M071.Process/UI/M071_MainForm.cs
@@ -313,7 +313,7 @@
        {
            if (lblMachineState.IsHandleCreated)
            {
                lblMachineState.BeginInvoke(new Action(() =>
                lblMachineState.Invoke(new Action(() =>
                {
                    switch (state)
                    {
src/Bro.M071.Process/packages.config
@@ -2,6 +2,7 @@
<packages>
  <package id="Autofac" version="4.9.4" targetFramework="net452" />
  <package id="DockPanelSuite" version="3.0.6" targetFramework="net452" />
  <package id="EPPlus" version="4.5.3.3" targetFramework="net452" />
  <package id="Newtonsoft.Json" version="11.0.2" targetFramework="net452" />
  <package id="PostSharp.Redist" version="6.2.7" targetFramework="net452" />
  <package id="WeifenLuo.WinFormsUI.Docking" version="2.1.0" targetFramework="net452" />