using AutoMapper; using FLY.Thick.Base.Common; using FLY.Thick.Base.Server; using Newtonsoft.Json; using OfficeOpenXml; using System; using System.Collections.Generic; using System.Data; using System.IO; using System.Linq; namespace FLY.Simulation.Calender.GuRuiShiYe { public class GageAd : ISimulationGageAD { #region 涂料轮廓 /// /// 涂料的横向视图, 精度1mm, /// um /// public List HorizontalView = new List(); /// /// 涂料的纵向视图,精度1mm,纵向是周长发生的 /// um /// public List VerticalView = new List(); #endregion #region 机架信息 /// /// 机架视图 AD值,精度1mm, /// public List GageView = new List(); /// /// 机架视图 均值 /// public double GageViewAvg { get; set; } public double Mmpp { get; set; } = 0.0945; /// 编码器2 mm/p 胶轮周长200mm,编码器 转1圈800脉冲 正确应该0.25 /// public double Mmpp2 = 0.24925; public int TotalLength { get; private set; } = 1600; /// /// 测速辊周长 314mm /// public double MmOfRoll { get; set; } = 314; /// /// 测速辊上接近开关信号长度 /// public double MmOfRoundSign { get; set; } = 10; /// /// 纵向位置偏移 单位m /// public double FilmPositionOffset { get; set; } #endregion /// /// 相对于机架 左起始位置 mm /// public int FilmBegin { get; set; } = 170; /// /// 纵向速度 m/min /// public double FilmVelocity { get; set; } = 20; /// /// 当前极片位置 m /// public double FilmPosition { get; set; } = 0; private double filmPosition_real; public bool IsSyncLight { get; set; } /// /// AD曲线 /// public CurveCollection curve; string gageName; /// /// 获取膜上厚度值 /// /// 膜上横向位置 /// 膜上纵向位置 /// public delegate double GetFilmValueHandler(int mm_h, int mm_v); GetFilmValueHandler GetBaseMaterialValue; public GetFilmValueHandler GetFilmValue; public GageAd() { GetFilmValue = new GetFilmValueHandler(_GetFilmValue); } private double _GetFilmValue(int mm_h, int mm_v) { if (mm_h >= 0 && mm_h < HorizontalView.Count) { double bValue = 0; if (GetBaseMaterialValue != null) bValue = GetBaseMaterialValue(mm_h, mm_v); var hValue = HorizontalView[mm_h]; int vIndex = (int)GetRemainder(mm_v, VerticalView.Count()); var vValue = VerticalView[vIndex]; return bValue+(vValue + hValue) / 2; } else { return 0; } } public void Init(string gageName, GetFilmValueHandler getBaseMaterialValue) { this.gageName = gageName; this.GetBaseMaterialValue = getBaseMaterialValue; curve = new CurveCollection($@"{gageName}\curve.json"); LoadXlsx_film($@"{gageName}\FilmView.xlsx"); LoadXlsx_scancorr($@"{gageName}\GageView.xlsx"); if (!GageAdJsonDb.Load(this, $@"{gageName}\gageAd.json")) GageAdJsonDb.Save(this, $@"{gageName}\gageAd.json"); GageViewAvg = GageView.Average(); TotalLength = GageView.Count(); } void Load_double(List datas, string csvFilePath) { datas.Clear(); using (StreamReader sr = new StreamReader(csvFilePath)) { string header = sr.ReadLine();//标题 , Thick, HSign while (!sr.EndOfStream) { string s = sr.ReadLine(); string[] ss = s.Split(','); double thk = double.Parse(ss[0]); datas.Add(thk); } sr.Close(); } } private void LoadXlsx_film(string filepath) { //检测标题 DataTable dataTable_h = new DataTable("table_horizontal"); dataTable_h.Columns.Add(new DataColumn() { ColumnName = "位置mm", DataType = typeof(double), Caption = "0" }); dataTable_h.Columns.Add(new DataColumn() { ColumnName = "涂料", DataType = typeof(double), Caption = "0" }); DataTable dataTable_v = new DataTable("table_vertical"); dataTable_v.Columns.Add(new DataColumn() { ColumnName = "位置mm", DataType = typeof(double), Caption = "0" }); dataTable_v.Columns.Add(new DataColumn() { ColumnName = "涂料", DataType = typeof(double), Caption = "0" }); using (ExcelPackage p = new ExcelPackage(new FileInfo(filepath))) { ExcelWorksheet sheet = p.Workbook.Worksheets["横向数据"]; FromSheet(sheet, dataTable_h); ExcelWorksheet sheet2 = p.Workbook.Worksheets["纵向数据"]; FromSheet(sheet2, dataTable_v); } HorizontalView.Clear(); for (int i = 0; i < dataTable_h.Rows.Count; i++) { double mm = (double)dataTable_h.Rows[i]["位置mm"]; double value = (double)dataTable_h.Rows[i]["涂料"]; for (int j = HorizontalView.Count(); j <= mm; j++) { HorizontalView.Add(value); } } VerticalView.Clear(); for (int i = 0; i < dataTable_v.Rows.Count; i++) { double mm = (double)dataTable_v.Rows[i]["位置mm"]; double value = (double)dataTable_v.Rows[i]["涂料"]; for (int j = VerticalView.Count(); j <= mm; j++) { VerticalView.Add(value); } } } private void LoadXlsx_scancorr(string filepath) { //检测标题 DataTable dataTable = new DataTable("table_scancorr"); dataTable.Columns.Add(new DataColumn() { ColumnName = "序号", DataType = typeof(double), Caption = "0" }); dataTable.Columns.Add(new DataColumn() { ColumnName = "脉冲", DataType = typeof(double), Caption = "0" }); dataTable.Columns.Add(new DataColumn() { ColumnName = "位置mm", DataType = typeof(double), Caption = "0" }); dataTable.Columns.Add(new DataColumn() { ColumnName = "正向原始", DataType = typeof(double), Caption = "0" }); dataTable.Columns.Add(new DataColumn() { ColumnName = "反向原始", DataType = typeof(double), Caption = "0" }); dataTable.Columns.Add(new DataColumn() { ColumnName = "正向滤波", DataType = typeof(double), Caption = "0" }); dataTable.Columns.Add(new DataColumn() { ColumnName = "反向滤波", DataType = typeof(double), Caption = "0" }); using (ExcelPackage p = new ExcelPackage(new FileInfo(filepath))) { ExcelWorksheet sheet = p.Workbook.Worksheets["机架修正"]; FromSheet(sheet, dataTable); } //获取正向滤波数据 GageView.Clear(); for (int i = 0; i < dataTable.Rows.Count; i++) { double mm = (double)dataTable.Rows[i]["位置mm"]; double ad = (double)dataTable.Rows[i]["正向滤波"]; for (int j = GageView.Count(); j <= mm; j++) { GageView.Add(ad); } } } void FromSheet(ExcelWorksheet sheet, DataTable dataTable) { int from_row = 1; int row = from_row; for (int i = 0; i < dataTable.Columns.Count; i++) { int col = i + 1; if ((string)(sheet.Cells[row, col].Value) != dataTable.Columns[i].ColumnName) { throw new Exception($"格式出错, 第{i}列 不是{dataTable.Columns[i].ColumnName}"); } } row++; while (true) { var newRow = dataTable.NewRow(); //当一行都是空的,认为没有数据 int nullCnt = 0; for (int j = 0; j < dataTable.Columns.Count; j++) { int col = j + 1; object value = sheet.Cells[row, col].Value; if (value is string || value == null) { if (string.IsNullOrEmpty((string)(value))) { //空的 nullCnt++; //continue; return; } } try { newRow[j] = sheet.Cells[row, col].Value; } catch (Exception e) { throw e; } } if (nullCnt == dataTable.Columns.Count) { //没有数据了 break; } dataTable.Rows.Add(newRow); row++; } } DateTime lastTime = DateTime.MinValue; public void OnPoll(DateTime now) { if (lastTime == DateTime.MinValue) { lastTime = now; return; } var ts = now - lastTime; double ms = 1.0 * ts.Ticks / TimeSpan.TicksPerMillisecond; double minute = ms / 1000 / 60; if (FilmVelocity != 0) { filmPosition_real += minute * FilmVelocity; } FilmPosition = filmPosition_real - FilmPositionOffset; //int index = (int)(filmPosition_real * 1000 % VerticalView.Count()); lastTime = now; } public int GetAD(int mm) { if (mm < 0) return (int)GageView[0]; else if (mm >= GageView.Count()) return (int)GageView.Last(); if (mm < FilmBegin || mm >= FilmBegin+HorizontalView.Count()) { //膜的外面 return (int)GageView[mm]; } int posLength = (int)(FilmPosition * 1000); double value = GetFilmValue(mm - FilmBegin, posLength); double ad = curve.Value2Ad(value, AD2ValueFlag.NoRevised); double ad_zero = curve.Value2Ad(0, AD2ValueFlag.NoRevised); //ad *= GageViewAvg / ad_zero; //ad *= GageView[mm] / GageViewAvg; ad *= GageView[mm] / ad_zero; if (ad > 65535) ad = 65535; else if (ad < 0) ad = 0; return (int)ad; } public ushort GetInput() { UInt16 istatus = 0x0fff; double mmInRoll = GetRemainder(FilmPosition * 1000, MmOfRoll); if (mmInRoll < MmOfRoundSign) { //亮灯 Misc.MyBase.CLEARBIT(ref istatus, IODefinition.IN_RSENSOR); } if (IsSyncLight) Misc.MyBase.CLEARBIT(ref istatus, IODefinition.IN_SYNC); return istatus; } static double GetRemainder(double a, double b) { if (a >= 0) { return a % b; } else { double ret = a % b; if (ret != 0) ret += Math.Abs(b); return ret; } } public int GetPosition2() { return (int)(FilmPosition * 1000 / Mmpp2); } public int GetSpeed2() { return (int)(FilmVelocity * 1000 / 60 / Mmpp2); } public void SetOutput(ushort output) { if (!Misc.MyBase.CHECKBIT(output, IODefinition.OUT_SYNC)) IsSyncLight = true; else IsSyncLight = false; } } public class GageAdJsonDb { static Mapper Mapper { get; } = new AutoMapper.Mapper(new MapperConfiguration(c => { c.CreateMap().ReverseMap(); })); public static bool Save(GageAd src, string filePath) { if (string.IsNullOrEmpty(filePath)) return false; var p = Mapper.Map(src); try { File.WriteAllText(filePath, JsonConvert.SerializeObject(p, Formatting.Indented)); return true; } catch { //异常,没有json 编码失败 } return false; } public static bool Load(GageAd src, string filePath) { if (string.IsNullOrEmpty(filePath)) return false; try { if (File.Exists(filePath)) { string json = File.ReadAllText(filePath); var p = JsonConvert.DeserializeObject(json); Mapper.Map(p, src); return true; } } catch { //异常,没有json 解码失败 } return false; } public double FilmPositionOffset; } }