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;
}
}