using FLY.Thick.Blowing.IService;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FLY.Thick.Blowing.UI.Fix.Client
{
public class CalFilmLen : INotifyPropertyChanged
{
#region 状态
///
/// 信息
///
public string Msg { get; private set; }
///
/// 下载中
///
public bool IsDownloading { get; private set; }
///
/// 数据准备好了
///
public bool IsDataReady { get; private set; }
///
/// 计算中
///
public bool IsCaling { get; private set; }
///
/// 有足够的数据,可以下载
///
public bool IsCanDownload { get; private set; }
///
/// 当前数据总分钟数 min
///
public int DataMaxMinute { get; private set; }
///
/// 必须获取的最少数据量 min
///
public int DataMinMinute { get; private set; }
///
/// 最佳获取数据量 min
///
public int DataBestMinute { get; private set; }
#endregion
#region 参数
///
/// 第1牵引速度
///
public double Velocity1 { get; private set; }
///
/// 速度滤波 单位s
///
public int VelocityFilter { get; private set; } = 1;
///
/// 膜距离
///
public double FilmLength { get; private set; }
#endregion
IBlowingFixService mCurrBlowing;
IBlowingDetectService mCurrRDetect;
BlowingDetectCore mRDetectCore;
List mADList = new List();
List mLimitList = new List();
List mRollList = new List();
#region 画图
public List LimitValues { get; } = new List();
public List VelocityValues { get; } = new List();
public List ThicknessValues { get; } = new List();
public List FilmLength3DValues { get; } = new List();
[PropertyChanged.DoNotCheckEquality]
public List CurrFilmLength3D { get; set; } = new List();
[PropertyChanged.DoNotCheckEquality]
public List NewFilmLength3D { get; set; } = new List();
public class Frame
{
///
/// 厚度
///
public double[] Thicks;
///
/// 旋转方向
///
public Misc.DIRECTION Direction;
///
/// 旋转次数
///
public int RotationCnt;
///
/// 与上一幅图的相关性
///
public double R;
///
/// 大于30%数据 非 NaN
///
public bool IsVaild;
}
[PropertyChanged.DoNotCheckEquality]
public List Frames { get; set; } = new List();
#endregion
int NBolts;
int OrgBoltNo;
DateTime dataBegin;
///
/// 最小旋转次数
///
const int minRotationCnt = 2;
public CalFilmLen()
{
mRDetectCore = new BlowingDetectCore();
}
public void Init(IBlowingFixService mRenZiJiaFix, IBlowingDetectService mRDetect)
{
this.mCurrBlowing = mRenZiJiaFix;
this.mCurrRDetect = mRDetect;
this.FilmLength = mRDetect.FilmLength;
Misc.BindingOperations.SetBinding(mCurrRDetect, "BufTotalTime", () =>
{
DataMaxMinute = (int)(mCurrRDetect.BufTotalTime.TotalMinutes);
});
Misc.BindingOperations.SetBinding(mCurrRDetect, "RotationCnt", () =>
{
if (mRDetect.RotationCnt < minRotationCnt)
{
IsCanDownload = false;
}
else
{
IsCanDownload = true;
}
});
Misc.BindingOperations.SetBinding(mCurrRDetect, "RenZiJiaPeriod", () =>
{
DataMinMinute = (int)(mRDetect.RenZiJiaPeriod.TotalMinutes * (minRotationCnt - 1));
DataBestMinute = (int)Math.Round((mRDetect.RenZiJiaPeriod.TotalMinutes * 3));
});
}
public bool DownloadData(int getDataMinute)
{
//应该在界面 检测错误原因
if (IsDownloading)
return false;
if (IsCaling)
return false;
TimeSpan getBufTime = TimeSpan.FromMinutes(getDataMinute);
if ( getBufTime > mCurrRDetect.BufTotalTime)
return false;
dataBegin = DateTime.Now - getBufTime;
IsDownloading = true;
IsDataReady = false;
DownloadData_limit();
return true;
}
void DownloadData_limit()
{
Msg = $"下载 转向信号数据 [{dataBegin} - Now]....";
mCurrRDetect.GetLimitList(dataBegin, (object AsyncState, object retData) =>
{
Action act = AsyncState as Action;
var p = retData as GetLimitListReponse;
if ((p.datas == null) || p.datas.Count() < 2)
{
Msg = $"数据下载异常, 转向信号数量<2";
IsDownloading = false;
return;
}
mLimitList = p.datas;
DownloadData_roll();
},null);
}
void DownloadData_roll()
{
Msg = $"下载 辊信号数据 [{dataBegin} - Now]....";
mCurrRDetect.GetRollList(dataBegin,
(object AsyncState, object retData) => {
var p = retData as GetRollListReponse;
if ((p.datas == null) || p.datas.Count() < 10)
{
Msg = "数据下载异常, 辊信号数量 < 10";
IsDownloading = false;
return;
}
mRollList = p.datas;
DownloadData_ad();
}, null );
}
void DownloadData_ad()
{
Msg = $"下载 厚度数据 [{dataBegin} - Now]....";
mCurrBlowing.GetADList(dataBegin,
(object AsyncState, object retData) => {
var p = retData as GetADListReponse;
if ((p.datas == null) || p.datas.Count() < 10)
{
Msg = "数据下载异常, 厚度数据数量 < 10";
IsDownloading = false;
return;
}
mADList = p.datas.Select(
a => new ADCell() {
Ad = a.thick,
Time = a.dt }
).ToList();
if (mCurrRDetect.Is3D)
DownloadData_CurrFilmLength3D();
else
DownloadData_OK();
}, null);
}
void DownloadData_CurrFilmLength3D()
{
Msg = $"下载 膜距离增量数据 [{dataBegin} - Now]....";
mCurrRDetect.GetFilmLength3D(
(object AsyncState, object retData) => {
var p = retData as GetFilmLength3DReponse;
CurrFilmLength3D = p.datas;
DownloadData_OK();
}, null);
}
void DownloadData_OK()
{
NBolts = mCurrBlowing.NBolts;
OrgBoltNo = mCurrBlowing.OrgBoltNo;
if (OrgBoltNo < 1)
OrgBoltNo = 1;
mRDetectCore.Init(
mCurrRDetect.RAngle,
mCurrRDetect.RollPerimeter,
mCurrRDetect.RenZiJiaPeriod,
mCurrRDetect.FilmLength,
mCurrRDetect.Is3D,
mRollList,
mLimitList,
CurrFilmLength3D);
UpdateLimitValues();
UpdateThicknessValues();
UpdateVelocityValues(VelocityFilter);
UpdateADList();
UpdateFrames();
Msg = "数据下载完成";
IsDownloading = false;
IsDataReady = true;
}
public void UpdateVelocityValues(int velocity_filter)
{
VelocityFilter = velocity_filter;
var filter_half = TimeSpan.FromSeconds(VelocityFilter / 2);
VelocityValues.Clear();
for (int i = 0; i < mRollList.Count(); i++)
{
var dt_min = mRollList[i].dt - filter_half;
var dt_max = mRollList[i].dt + filter_half;
int i_begin = 0;
int i_end = mRollList.Count()-1;
for (int j = i; j >= 0; j--)
{
if (mRollList[j].dt <= dt_min)
{
//找到了
i_begin = j;
break;
}
}
for (int j = i; j < mRollList.Count(); j++)
{
if (mRollList[j].dt >= dt_max)
{
//找到了
i_end = j;
break;
}
}
if (i_begin == i_end)
{
i_begin = i;
i_end = i + 1;
if (i_end >= mRollList.Count())
{
i_begin = i - 1;
i_end = i;
}
}
TimeSpan ts = mRollList[i_end].dt - mRollList[i_begin].dt;
double minute = 1.0 * ts.Ticks / TimeSpan.TicksPerMinute;
double v = (i_end - i_begin)*mCurrRDetect.RollPerimeter / 1000 / minute;
VelocityValues.Add(
new TimeValue()
{
Time = mRollList[i].dt,
Value = v
});
}
OnPropertyChanged("VelocityValues");
Velocity1 = VelocityValues.Average(tv => tv.Value);
if (mCurrRDetect.Is3D)
UpdateFilmLength3D(Velocity1);
}
public void UpdateFilmLength3D(double velocity1)
{
Velocity1 = velocity1;
FilmLength3DValues.Clear();
double sum = 0;
FilmLength3DValues.Add(
new TimeValue()
{
Time = VelocityValues[0].Time,
Value = sum
});
for (int i = 1; i < VelocityValues.Count(); i++)
{
var ts = VelocityValues[i].Time - VelocityValues[i - 1].Time;
double minute = 1.0* ts.Ticks / TimeSpan.TicksPerMinute;
sum += ((VelocityValues[i].Value + VelocityValues[i - 1].Value) / 2 - Velocity1) * minute;
FilmLength3DValues.Add(
new TimeValue()
{
Time = VelocityValues[i].Time,
Value = sum
});
}
double min_f = FilmLength3DValues.Min(tv => tv.Value);
foreach (var tv in FilmLength3DValues)
tv.Value -= min_f;
OnPropertyChanged("FilmLength3DValues");
UpdateNewFilmLength3D();
}
void UpdateThicknessValues()
{
ThicknessValues.Clear();
foreach (var adcell in mADList)
{
ThicknessValues.Add(
new TimeValue() {
Time = adcell.Time,
Value = Misc.MyBase.ISVALIDATA(adcell.Ad)?
adcell.Ad / 100.0:double.NaN });
}
OnPropertyChanged("ThicknessValues");
}
void UpdateLimitValues()
{
LimitValues.Clear();
foreach (var limit in mLimitList)
{
DateTime dt = limit.dt_begin;
if (dt == DateTime.MinValue)
dt = limit.dt_end;
LimitValues.Add(new TimeValue() { Time = dt, Value = limit.no });
}
OnPropertyChanged("LimitValues");
}
void UpdateADList()
{
for (int i = 0; i < mADList.Count(); i++)
{
ADCell c = mADList[i];
if(i==143)
{
}
int ret = mRDetectCore.GetFilmInfo(
out BlowingDetectCore.FilmInfo filminfo,
mADList[i].Time);
if (ret > 0 )//发生在辊信号的未来,把数据删除!!!!
{
//异常
mADList.RemoveRange(i, mADList.Count() - i);
return;
}
if (filminfo.rotationCnt == 1)
{
}
else if (filminfo.rotationCnt != 1)
{
}
if (filminfo.inCV)
{
}
//计算相关性,只使用 膜边=0mm 模式
c.Direction = filminfo.direction;
c.Angles.Clear();
c.Angles.Add(filminfo.angle);
c.RotationCnt = filminfo.rotationCnt;
c.Velocity = filminfo.filmVelocity;
c.InCV = filminfo.inCV;
}
}
void UpdateNewFilmLength3D()
{
int n = 100;
List< IEnumerable> fs = new List>();
for (int i = 0; i < mLimitList.Count()-1; i++)
{
int no = mLimitList[i].no;
DateTime begin_dt = mLimitList[i].dt_end;
DateTime end_dt = mLimitList[i+1].dt_begin;
if ((begin_dt == DateTime.MinValue) || (end_dt == DateTime.MinValue))
{
//异常
continue;
}
var filmlength3d = FilmLength3DValues.Where(tv => tv.Time >= begin_dt && tv.Time <= end_dt);
double[] f = new double[n];
int k = 0;
for (int j = 0; j < f.Count(); j++)
{
DateTime dt = begin_dt + TimeSpan.FromTicks(j * (end_dt - begin_dt).Ticks / f.Count());
bool hadFind = false;
for (; k < filmlength3d.Count(); k++)
{
if (filmlength3d.ElementAt(k).Time >= dt)
{
//找到了
f[j] = filmlength3d.ElementAt(k).Value;
hadFind = true;
break;
}
}
if (!hadFind)//找不到
{
if (j > 0)
f[j] = f[j - 1];
}
}
if (no == 0)
fs.Add(f);
else
fs.Add(f.Reverse());
}
//求均值
List newfilmlength3d = new List();
for (int i = 0; i < fs.First().Count(); i++)
{
double sum = 0;
for (int j = 0; j < fs.Count(); j++)
{
sum += fs[j].ElementAt(i);
}
newfilmlength3d.Add(sum / fs.Count());
}
NewFilmLength3D = newfilmlength3d;
}
public void SetFilmLength3D()
{
CurrFilmLength3D = NewFilmLength3D;
mRDetectCore.mFilmLength3D = CurrFilmLength3D;
if (mRDetectCore.Is3D)
{
UpdateFrames();
}
mCurrRDetect.SetFilmLength3D(NewFilmLength3D);
FLY.ControlLibrary.Window_Tip.Show(
"应用成功",
$"立体式旋转 膜距离增量设置成功",
TimeSpan.FromSeconds(2));
}
public void SetFilmLength(double filmLength)
{
FilmLength = filmLength;
mRDetectCore.FilmLength = filmLength;
UpdateADList();
UpdateFrames();
}
void UpdateFrames()
{
Frames = GetFrames();
}
List GetFrames()
{
List frames = new List();
int boltIndex = -1;
List datas = new List();
int roationCnt = -1;
Frame frame = null;
foreach (ADCell c in mADList)
{
int bi = (int)(NBolts * c.Angles[0] / 360);
if (bi < 0) bi = 0;
else if (bi >= NBolts) bi = NBolts - 1;
int boltno = bi + OrgBoltNo;
if (boltno > NBolts)
boltno -= NBolts;
//添加到
if ((c.InCV == true) &&
((roationCnt == -1) || (roationCnt != c.RotationCnt))
)
{
roationCnt = c.RotationCnt;
frame = new Frame();
frame.RotationCnt = roationCnt;
frame.Direction = c.Direction;
frame.Thicks = new double[NBolts];
for (int j = 0; j < frame.Thicks.Count(); j++)
frame.Thicks[j] = double.NaN;
frames.Add(frame);
boltIndex = -1;
}
if ((boltIndex == -1) || (boltIndex != boltno - 1))
{
datas.Clear();
}
datas.Add(c.Ad);
boltIndex = boltno - 1;
int avg = Misc.MyMath.Avg(datas);
if (Misc.MyBase.ISVALIDATA(avg))
frame.Thicks[boltIndex] = avg / 100.0;
}
for (int i = 1; i < frames.Count; i++)
{
frames[i].IsVaild = 1.0 * frames[i].Thicks.Count(t => !double.IsNaN(t)) / frames[i].Thicks.Count() > 0.3;
if (frames[i].IsVaild)
{
//计算相关性
frames[i].R = Misc.MyMath.Correl(frames[i].Thicks, frames[i - 1].Thicks);
}
}
return frames;
}
bool TestFilmLength(double filmlength, ref double max_r, ref double best_filmlength, out double r)
{
bool ret = false;
mRDetectCore.FilmLength = filmlength;
UpdateADList();
var frames = GetFrames();
r = frames.Max(f => f.R);
if (r > max_r)
{
max_r = r;
best_filmlength = mRDetectCore.FilmLength;
ret = true;
}
return ret;
}
public async void Cal(double begin_filmlength, double end_filmlength)
{
if (mRDetectCore.RotationCnt < 3)
{
Msg = "---警告--- 没法自动计算,旋转次数少于3次";
return;
}
if (begin_filmlength < 3)
begin_filmlength = 3;
if (end_filmlength > 50)
end_filmlength = 50;
IsCaling = true;
double max_r=0;
double best_filmlength=FilmLength;
await Task.Factory.StartNew(() =>
{
for (double i = begin_filmlength; i < end_filmlength; i+=0.1)
{
TestFilmLength(i, ref max_r, ref best_filmlength, out double r);
int progress = (int)((i - begin_filmlength) / (end_filmlength - begin_filmlength) * 100);
Msg = $"{progress:000}/100 {i:F1}m R={r:F3} 最合理[{best_filmlength:F1}m MaxR={max_r:F3}]";
}
});
SetFilmLength(best_filmlength);
Msg = $"最合理[{best_filmlength:F1}m MaxR={max_r:F3}]";
IsCaling = false;
}
//public void Start()
//{
// if (step == 0)
// {
// step = 1;
// dt_onpoll = DateTime.MinValue;
// RotationCnt = 3;
// TimeOfMin = DateTime.MinValue;
// TimeOfMax = DateTime.MinValue;
// mADList.Clear();
// OnPoll();
// }
//}
//bool Poll()
//{
// switch (step)
// {
// case 1:
// {
// if (Step01())
// {
// step = 2;
// return true;
// }
// }
// break;
// case 2:
// {
// if (Step02())
// {
// step = 3;
// return true;
// }
// }
// break;
// case 3:
// {
// if (Step03())//已经成功获取了时间
// {
// step = 4;
// return true;
// }
// else
// {
// if (TimeOfMin == DateTime.MinValue)
// {
// step = 2;
// }
// }
// }
// break;
// case 4:
// {
// Step04();
// step = 5;
// }
// break;
// }
// return false;
//}
//DateTime dt_onpoll = DateTime.MinValue;
public event PropertyChangedEventHandler PropertyChanged;
/////
///// 每次获取完所有angle,执行,每20秒触发一次
/////
//public void OnPoll()
//{
// DateTime now = DateTime.Now;
// if ((dt_onpoll != DateTime.MinValue) && ((now - dt_onpoll) < TimeSpan.FromSeconds(30)))
// return;
// dt_onpoll = now;
// while (Poll()) ;
//}
//bool Step01()
//{
// //下载数据
// if (mCurrRDetect.RotationCnt < 3)
// {
// RotationCnt = 3;
// State = "RotationCnt=3 Wait";
// return true;
// }
// RotationCnt = mCurrBlowing.mPDetect.RotationCnt;
// return true;
//}
/////
///// 确保三个rotationcnt 都存在
/////
/////
//bool Step02()
//{
// if (RotationCnt > mCurrBlowing.mPDetect.RotationCnt)
// {
// State = "RotationCnt=" +
// RotationCnt.ToString() + ">" + mCurrBlowing.mPDetect.RotationCnt.ToString() + " Wait";
// return false;
// }
// DateTime min_time;
// DateTime max_time;
// double min_fl = MinFilmLength;
// double max_fl = MaxFilmLength;
// BlowingDetect.GetLimitTimeResult r1 =
// mCurrBlowing.mPDetect.GetLimitTime(
// RotationCnt - 2,
// min_fl,
// out min_time);
// BlowingDetect.GetLimitTimeResult r2 =
// mCurrBlowing.mPDetect.GetLimitTime(
// RotationCnt,
// max_fl,
// out max_time);
// string state = "[min_fl=" + min_fl.ToString() + "m (" + min_time.ToLongTimeString() + ") " + r1.ToString() + "]," +
// "[max_fl=" + max_fl.ToString() + "m (" + max_time.ToLongTimeString() + ") " + r2.ToString() + "] ";
// if ((r1 == BlowingDetect.GetLimitTimeResult.NOEXIST) ||
// (r2 == BlowingDetect.GetLimitTimeResult.NOEXIST))
// {
// //不可能存在的错误
// RotationCnt++;
// state += "Wait 不可能存在的错误 NOEXIST, RotationCnt=" + RotationCnt.ToString();
// State = state;
// return false;
// }
// else if ((r1 == BlowingDetect.GetLimitTimeResult.ISFURTURE) ||
// (r2 == BlowingDetect.GetLimitTimeResult.ISFURTURE))
// {
// //就是它,等!!!!
// state += "Wait ,it is the one!!!!";
// State = state;
// return false;
// }
// else if ((r1 != BlowingDetect.GetLimitTimeResult.OK) ||
// (r2 != BlowingDetect.GetLimitTimeResult.OK))
// {
// //不可能存在的错误
// RotationCnt++;
// state += "Wait 不可能存在的错误 ?????, RotationCnt=" + RotationCnt.ToString();
// State = state;
// return false;
// }
// TimeOfMin = min_time;
// TimeOfMax = max_time;
// return true;
//}
//bool Step03()
//{
// int copy_index_b = -1;
// int copy_index_e = -1;
// int ret = mCurrBlowing.ADListFastSearchIndex(TimeOfMin, out copy_index_b);
// string state;
// state = "TimeOfMin(" + TimeOfMin.ToLongTimeString() + ") (" + copy_index_b.ToString() + ") ";
// if (ret == -1)//发生在过去
// {
// state += " PAST";
// State = state;
// RotationCnt++;
// TimeOfMin = DateTime.MinValue;
// TimeOfMax = DateTime.MinValue;
// return false;
// }
// else if (ret == 1)//发生在未来
// {
// state += " FUTURE";
// State = state;
// return false;
// }
// ret = mCurrBlowing.ADListFastSearchIndex(TimeOfMax, out copy_index_e);
// state += " TimeOfMax(" + TimeOfMax.ToLongTimeString() + ") (" + copy_index_e.ToString() + ")";
// if (ret == -1)//发生在过去
// {
// //异常出错
// throw new ArgumentOutOfRangeException("min_time 在列表中, 但max_time在列表前");
// }
// else if (ret == 1)//发生在未来
// {
// state += " FUTURE";
// return false;
// }
// //复制所有scaninfolist
// for (int i = copy_index_b; i <= copy_index_e; i++)
// {
// mADList.Add(mCurrBlowing.mADList[i].Clone());
// }
// //复制 旋转架检测器
// mCurrRDetect = mCurrBlowing.mPDetect.Clone();
// //数据足够了
// state += " READY";
// State = state;
// return true;
//}
//void Step04()
//{
// //立刻计算
// Thread t = new Thread(Cal)
// {
// Priority = ThreadPriority.Lowest,
// IsBackground = true
// };
// t.Start();
//}
//void Cal()
//{
// //限位时间点,肯定在缓存区的中间!!!!!
// //1.找到限位时间点所在的数据幅
// //2.以该点作为对称点,上下3幅计算thicks,再求相似度
// double min_fl = MinFilmLength;
// double max_fl = MaxFilmLength;
// double maxr = -1;
// double maxr_fl = -1;
// string state;
// double curr_r = CalR(FilmLength);
// for (double i = min_fl; i <= max_fl; i += 0.1)
// {
// double r = CalR(i);
// if (r > maxr)
// {
// maxr = r;
// maxr_fl = i;
// }
// state = "Cal";
// state += " (" + ((i - min_fl) / (max_fl - min_fl) * 100).ToString("F0") + "/100)";
// state += " [" + r.ToString("F3") + "," + i.ToString("N1") + "m]";
// state += " MaxR=[" + maxr.ToString("F3") + "," + maxr_fl.ToString("N1") + "m]";
// state += " CurrR=[" + curr_r.ToString("F3") + "," + FilmLength.ToString("N1") + "m]";
// State = state;
// }
// MaxR = maxr;
// MaxRFilmLength = maxr_fl;
// State = "Cal OK";
// step = 0;
//}
//double CalR(double filmLength)
//{
// mCurrRDetect.FilmLength = filmLength;
// for (int i = 0; i < mADList.Count(); i++)
// {
// ADCell c = mADList[i];
// BlowingDetect.FilmInfo filminfo;
// int ret = mCurrRDetect.GetFilmInfo(out filminfo, mADList[i].dt, 2.3, 0);
// if (ret != 0)
// {
// //异常
// return 0;
// }
// //计算相关性,只使用 膜边=0mm 模式
// c.direction = filminfo.direction;
// c.angles.Add(filminfo.angle1);
// c.angles.Add(filminfo.angle2);
// c.rotationCnt = filminfo.rotationCnt;
// c.velocity = filminfo.filmVelocity;
// c.inCV = filminfo.inCV;
// }
// //找到 rotationCnt 为 RotationCnt-2, 与 RotationCnt-1 的数据,进行相似度计算
// //直接使用角度划分数据, 360°
// //360个数据太多,使用120个数据
// int[] thicks1 = new int[120];
// int[] thicks2 = new int[120];
// for (int i = 0; i < 120; i++)
// {
// thicks1[i] = Misc.MyBase.NULL_VALUE;
// thicks2[i] = Misc.MyBase.NULL_VALUE;
// }
// int sum = 0;
// int cnt = 0;
// //int angle = -1;
// int angle_3 = -1;
// int rotationcnt = 0;
// for (int i = 0; i < mADList.Count(); i++)
// {
// ADCell c = mADList[i];
// if (cnt == 0)
// {
// if (Misc.MyBase.ISVALIDATA(c.ad))
// {
// sum += c.ad;
// cnt++;
// }
// angle_3 = (int)(c.angles.First() / 3);
// rotationcnt = c.rotationCnt;
// }
// else
// {
// bool change = false;
// if ((rotationcnt != c.rotationCnt) ||
// (angle_3 != (int)(c.angles.First() / 3)))
// {
// change = true;
// }
// if (!change)
// {
// if (Misc.MyBase.ISVALIDATA(c.ad))
// {
// sum += c.ad;
// cnt++;
// }
// }
// else
// {
// int[] thicks = null;
// if (rotationcnt == RotationCnt - 2)
// thicks = thicks1;
// else if (rotationcnt == RotationCnt - 1)
// thicks = thicks2;
// if (thicks != null)
// {
// int index = angle_3;
// if (index >= 120)
// index = 119;
// else if (index < 0)
// index = 0;
// if (cnt > 0)
// thicks[index] = sum / cnt;
// else
// thicks[index] = Misc.MyBase.NULL_VALUE;
// }
// sum = 0;
// cnt = 0;
// if (Misc.MyBase.ISVALIDATA(c.ad))
// {
// sum += c.ad;
// cnt++;
// }
// rotationcnt = c.rotationCnt;
// angle_3 = (int)(c.angles.First() / 3);
// }
// }
// }
// //计算相似性
// return Misc.MyMath.Correl(thicks1, thicks2);
//}
protected void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
//string file_path = "bulkdb.json";
public void Save(string file_path)
{
try
{
CalFilmLenJsonDB param = new CalFilmLenJsonDB()
{
RAngle = mRDetectCore.RAngle,
RollPerimeter = mRDetectCore.RollPerimeter,
RenZiJiaPeriod = mRDetectCore.RenZiJiaPeriod,
FilmLength = mRDetectCore.FilmLength,
Is3D = mRDetectCore.Is3D,
mRollList = mRDetectCore.mRollList,
mLimitList = mRDetectCore.mLimitList,
mFilmLength3D = mRDetectCore.mFilmLength3D,
NBolts = NBolts,
OrgBoltNo = OrgBoltNo,
mADList = mADList.Select(a => new ADSingle() { dt = a.Time, thick = a.Ad }).ToList()
};
File.WriteAllText(file_path, JsonConvert.SerializeObject(param, Formatting.Indented));
}
catch
{
//异常,没有json 编码失败
}
}
public void Load(string file_path)
{
try
{
if (File.Exists(file_path))
{
string json = File.ReadAllText(file_path);
var param = JsonConvert.DeserializeObject(json);
Load(param);
}
}
catch
{
//异常,没有json 解码失败
}
}
void Load(CalFilmLenJsonDB param)
{
mRDetectCore.Init(
param.RAngle,
param.RollPerimeter,
param.RenZiJiaPeriod,
param.FilmLength,
param.Is3D,
param.mRollList,
param.mLimitList,
param.mFilmLength3D);
NBolts = param.NBolts;
OrgBoltNo = param.OrgBoltNo;
if (OrgBoltNo < 1)
OrgBoltNo = 1;
FilmLength = param.FilmLength;
mLimitList = param.mLimitList;
mRollList = param.mRollList;
mADList = param.mADList.Select(
a => new ADCell()
{
Ad = a.thick,
Time = a.dt
}
).ToList();
UpdateLimitValues();
UpdateThicknessValues();
UpdateVelocityValues(VelocityFilter);
UpdateADList();
UpdateFrames();
IsDataReady = true;
}
public void Test()
{
CalFilmLenJsonDB param = new CalFilmLenJsonDB()
{
NBolts = 96,
RAngle = 350,
RollPerimeter = 314,
FilmLength = 24,
Is3D = false,
mFilmLength3D = null,
RenZiJiaPeriod = TimeSpan.FromMinutes(6.1),
mADList = new List(),
mLimitList = new List(),
mRollList = new List()
};
#region 虚拟数据
int[] thicks = new int[]{
3518 ,
3484 ,
3634 ,
3620 ,
3579 ,
3625 ,
3635 ,
3638 ,
3635 ,
3606 ,
3611 ,
3603 ,
3590 ,
3631 ,
3646 ,
3647 ,
3710 ,
3705 ,
3607 ,
3720 ,
3680 ,
3637 ,
3659 ,
3703 ,
3860 ,
3720 ,
3615 ,
3810 ,
3772 ,
3666 ,
3614 ,
3627 ,
3618 ,
3502 ,
3575 ,
3583 ,
3615 ,
3680 ,
3730 ,
3840 ,
3927 ,
3946 ,
3923 ,
3841 ,
3797 ,
3865 ,
3810 ,
3711 ,
3754 ,
3705 ,
3723 ,
3699 ,
3723 ,
3801 ,
3786 ,
3798 ,
3907 ,
3945 ,
3828 ,
3860 ,
3846 ,
3903 ,
3871 ,
3844 ,
3759 ,
3816 ,
3886 ,
3815 ,
3789 ,
3876 ,
3942 ,
3854 ,
3842 ,
3921 ,
3846 ,
3835 ,
3886 ,
3881 ,
3820 ,
3787 ,
3730 ,
3617 ,
3650 ,
3610 ,
3536 ,
3545 ,
3564 ,
3584 ,
3580 ,
3572 ,
3571 ,
3579 ,
3620 ,
3634 ,
3484 ,
3518 ,
};
//线速度 m/min
double FilmVelocity = 20;
TimeSpan Cool = TimeSpan.FromSeconds(2.3);
//速度震荡周期 m
double FV_Range = 2;
TimeSpan DataLen = TimeSpan.FromMinutes(30);
DateTime dt_begin = DateTime.Now;
DateTime dt_end = dt_begin + DataLen;
for (TimeSpan ts = TimeSpan.Zero; ts < DataLen; ts += TimeSpan.FromSeconds(1))
{
DateTime dt = dt_begin + ts;
double min = ts.TotalMinutes;
//速度以1/2旋转周期变化
double v = FilmVelocity + Math.Sin(Math.PI * 2 * min / (param.RenZiJiaPeriod.TotalMinutes / 2)) * FV_Range;
if (param.mRollList.Count() == 0)
{
param.mRollList.Add(new RollCell() { dt = dt });
}
else
{
while ((dt - param.mRollList.Last().dt).TotalMinutes * v > (param.RollPerimeter / 1000))
{
param.mRollList.Add(new RollCell()
{
dt = param.mRollList.Last().dt + TimeSpan.FromMinutes((param.RollPerimeter / 1000) / v)
});
}
}
int n = ((int)(min / param.RenZiJiaPeriod.TotalMinutes)) % 2;
double min2 = min - param.FilmLength / v + param.RenZiJiaPeriod.TotalMinutes * 2;
int n2 = ((int)(min2 / param.RenZiJiaPeriod.TotalMinutes)) % 2;
double m = min2 % param.RenZiJiaPeriod.TotalMinutes;
int idx = (int)(thicks.Count() * m / param.RenZiJiaPeriod.TotalMinutes);
if (idx < 0) idx = 0;
else if (idx > thicks.Count()) idx = thicks.Count() - 1;
int thick;
if (n2 == 0)
thick = thicks[idx];
else
thick = thicks[thicks.Count() - 1 - idx];
param.mADList.Add(new ADSingle
{
dt = dt,
thick = thick
});
if (param.mLimitList.Count() == 0)
{
if (dt >= dt_begin + param.RenZiJiaPeriod)
{
param.mLimitList.Add(new LimitCell()
{
dt_begin = dt_begin + param.RenZiJiaPeriod,
dt_end = dt_begin + param.RenZiJiaPeriod + Cool,
no = n
});
}
}
else if (dt >= param.mLimitList.Last().dt_end + param.RenZiJiaPeriod)
{
param.mLimitList.Add(new LimitCell()
{
dt_begin = param.mLimitList.Last().dt_end + param.RenZiJiaPeriod,
dt_end = param.mLimitList.Last().dt_end + param.RenZiJiaPeriod + Cool,
no = n
});
}
}
#endregion
Load(param);
}
}
public class CalFilmLenJsonDB
{
///
/// 离开限位 到 撞下一个限位 的 旋转架转动总角度 单位°
///
public double RAngle;
///
/// 辊周长,单位mm
///
public double RollPerimeter;
///
/// 离开限位 到 撞下一个限位 的 旋转架转动时间, 需要初始值,以后测量出来的
///
public TimeSpan RenZiJiaPeriod;
///
/// 人字架到测厚仪膜长 单位m
///
public double FilmLength;
///
/// 旋转架为立式,测厚仪安装在二牵引前面,膜距离 与 旋转角度 一起变化, 旋转角度越大 膜距离越大
///
public bool Is3D;
///
/// 辊信号列表
///
public List mRollList;
///
/// 转向信号列表
///
public List mLimitList;
///
/// 当为 立式旋转架时,膜距离与旋转角度有关系
/// 列表的长度为 200, 列表的头为信号0离开, 尾为信号1进入
///
public List mFilmLength3D;
public List mADList;
public int NBolts;
public int OrgBoltNo=1;
}
}