Commit c87c3df7 authored by 潘栩锋's avatar 潘栩锋 🚴

添加 加热PLC控制精度提升到0.1%

添加 中心偏厚控制
parent 2caca8bf
......@@ -323,10 +323,10 @@ namespace FLY.FilmCasting.AutoDie.UI.Client
CallDiffResult result = new CallDiffResult();
double[] thickpercents0 = ucThickHeatVms[0].GetThickPercents(boltmap, uniformShrinkPercent);
int[] heats0 = ucThickHeatVms[0].GetHeats();
double[] heats0 = ucThickHeatVms[0].GetHeats();
double[] thickpercents1 = ucThickHeatVms[1].GetThickPercents(boltmap, uniformShrinkPercent);
int[] heats1 = ucThickHeatVms[1].GetHeats();
double[] heats1 = ucThickHeatVms[1].GetHeats();
int channelCnt = feedback.ChannelCnt;
......
......@@ -34,7 +34,7 @@ namespace FLY.FilmCasting.AutoDie.UI.Client
/// 厚度%
/// </summary>
public ChartValues<double> ThickPercents { get; } = new ChartValues<double>();
public ChartValues<int> Heats { get; } = new ChartValues<int>();
public ChartValues<double> Heats { get; } = new ChartValues<double>();
public double Kp { get; set; } = 3;
public int MaxHeat { get; set; } = 100;
......@@ -384,7 +384,7 @@ namespace FLY.FilmCasting.AutoDie.UI.Client
//return GetThickPercents(frame.BoltMapInfo.UniformShrinkPercent, frame.BoltMapInfo.MidOffset, frame.Boltmap);
return GetThickPercents(frame.Boltmap, frame.BoltMapInfo.UniformShrinkPercent);
}
public int[] GetHeats()
public double[] GetHeats()
{
return frame.Heats.ToArray();
}
......
......@@ -33,7 +33,7 @@ namespace FLY.FilmCasting.AutoDie.UI.Client
int kp = 3;
int[] heats = new int[nbolts];
double[] heats = new double[nbolts];
for (int i = 0; i < nbolts; i++)
{
heats[i] = (int)((Math.Sin(i * Math.PI / nbolts)) * 20 + 30 + (random.NextDouble() - 0.5) * 5);
......
......@@ -55,17 +55,24 @@
<StackPanel Margin="{StaticResource ControlMargin}">
<TextBlock Style="{StaticResource Styles.Text.FieldHeader.Editable}" Text="控制线" />
<StackPanel Orientation="Horizontal">
<TextBox Style="{StaticResource Styles.Text.FieldContent.Input.Card}" Text="{Binding CtrlLine}"/>
<TextBox Style="{StaticResource Styles.Text.FieldContent.Input.Card}" Text="{Binding CtrlLine,StringFormat={}{0:0.#}}"/>
<TextBlock Style="{StaticResource Styles.Text.FieldContent.Unit}" Text="%" />
</StackPanel>
</StackPanel>
<StackPanel Margin="{StaticResource ControlMargin}" >
<TextBlock Style="{StaticResource Styles.Text.FieldHeader.Editable}" Text="Kp" />
<StackPanel Orientation="Horizontal">
<TextBox Style="{StaticResource Styles.Text.FieldContent.Input.Card}" Text="{Binding Kp, StringFormat={}{0:F1}}"/>
<TextBox Style="{StaticResource Styles.Text.FieldContent.Input.Card}" Text="{Binding Kp, StringFormat={}{0:0.#}}"/>
<TextBlock Style="{StaticResource Styles.Text.FieldContent.Unit}" Text="加热/厚度" />
</StackPanel>
</StackPanel>
<StackPanel Margin="{StaticResource ControlMargin}" >
<TextBlock Style="{StaticResource Styles.Text.FieldHeader.Editable}" Text="中心偏厚" />
<StackPanel Orientation="Horizontal">
<TextBox Style="{StaticResource Styles.Text.FieldContent.Input.Card}" Text="{Binding CenterTarget, StringFormat={}{0:0.#}}"/>
<TextBlock Style="{StaticResource Styles.Text.FieldContent.Unit}" Text="%" />
</StackPanel>
</StackPanel>
<StackPanel Margin="{StaticResource ControlMargin}" >
<TextBlock Style="{StaticResource Styles.Text.FieldHeader.Editable}" Text="平滑阀值" />
<StackPanel Orientation="Horizontal">
......@@ -124,6 +131,7 @@
<TextBlock Style="{StaticResource Styles.Text.FieldContent.Unit}" Text="m" />
</StackPanel>
</StackPanel>
</StackPanel >
<StackPanel Orientation="Horizontal" >
<StackPanel Margin="{StaticResource ControlMargin}">
......@@ -151,7 +159,7 @@
</TextBlock>
</StackPanel>
<StackPanel Margin="{StaticResource ControlMargin}" DataContext="{Binding Feedback}">
<TextBlock Style="{StaticResource Styles.Text.FieldHeader}" Text="风机" />
<TextBlock Style="{StaticResource Styles.Text.FieldHeader}" Text="总电源" />
<TextBlock>
<TextBlock.Style>
<Style TargetType="TextBlock" BasedOn="{StaticResource Styles.Text.FieldContent}">
......
......@@ -62,7 +62,7 @@ namespace FLY.FilmCasting.AutoDie.UI.Client
public int[] HeatEffectCurve { get; set; }
public bool IsForbidUpDown { get; set; }
public int CtrlLine { get; set; }
public double CtrlLine { get; set; }
public double Kp { get; set; }
/// <summary>
......@@ -80,6 +80,10 @@ namespace FLY.FilmCasting.AutoDie.UI.Client
/// </summary>
public int RangeOfOffset { get; set; } = 50;
/// <summary>
/// 中心偏厚 单位 %
/// </summary>
public double CenterTarget { get; set; }
/// <summary>
/// 混合数
/// </summary>
......@@ -132,6 +136,8 @@ namespace FLY.FilmCasting.AutoDie.UI.Client
Misc.BindingOperations.SetBinding(this.HeatCell, nameof(IHeatCellService.Kp), this, nameof(Kp));
Misc.BindingOperations.SetBinding(this.HeatCell, nameof(IHeatCellService.MaxHeat), this, nameof(MaxHeat));
Misc.BindingOperations.SetBinding(this.HeatCell, nameof(IHeatCellService.RangeOfOffset), this, nameof(RangeOfOffset));
Misc.BindingOperations.SetBinding(this.HeatCell, nameof(IHeatCellService.CenterTarget), this, nameof(CenterTarget));
Misc.BindingOperations.SetBinding(this.Feedback, nameof(IFeedbackHeatService.Step), this, nameof(Step));
Misc.BindingOperations.SetBinding(this.Feedback, nameof(IFeedbackHeatService.HasCheck), this, nameof(HasCheck));
......@@ -226,10 +232,11 @@ namespace FLY.FilmCasting.AutoDie.UI.Client
//参数设置
HeatCell.ThresholdHeatSigma=this.ThresholdHeatSigma;
HeatCell.IsForbidUpDown = this.IsForbidUpDown;
HeatCell.CtrlLine = this.CtrlLine;
HeatCell.CtrlLine = Math.Round(this.CtrlLine, 1);
HeatCell.Kp = this.Kp;
HeatCell.MaxHeat = this.MaxHeat;
HeatCell.RangeOfOffset = this.RangeOfOffset;
HeatCell.CenterTarget = Math.Round(this.CenterTarget, 1);
Feedback.Step=this.Step;
Feedback.HasCheckFilmVelocity=this.HasCheckFilmVelocity;
......
......@@ -34,12 +34,11 @@ namespace FLY.FilmCasting.AutoDie.UI.Client.UiModule
/// 厚度%
/// </summary>
public ChartValues<double> ThickPercents { get; } = new ChartValues<double>();
public ChartValues<int> PreHeats { get; } = new ChartValues<int>();
public ChartValues<int> Heats { get; } = new ChartValues<int>();
public ChartValues<int> HeatOffsets { get; } = new ChartValues<int>();
public ChartValues<double> PreHeats { get; } = new ChartValues<double>();
public ChartValues<double> Heats { get; } = new ChartValues<double>();
public ChartValues<double> HeatOffsets { get; } = new ChartValues<double>();
public ChartValues<bool> Bads { get; } = new ChartValues<bool>();
public ChartValues<bool> IsStables { get; } = new ChartValues<bool>();
public object MapperPreHeats { get; private set; }
[PropertyChanged.DependsOn(nameof(Kp))]
......
......@@ -35,7 +35,7 @@ namespace FLY.FilmCasting.AutoDie.UI.Client.UiModule
{
thickpercents[i] = 100 * (datas[i] - avg) / avg;
}
int[] heatoffsets = new int[nbolts];
var heatoffsets = new double[nbolts];
for (int i = 0; i < nbolts; i++)
{
heatoffsets[i] = (int)(thickpercents[i] * kp);
......@@ -43,13 +43,13 @@ namespace FLY.FilmCasting.AutoDie.UI.Client.UiModule
int baseHeat = 20;
int[] preheats = new int[nbolts];
var preheats = new double[nbolts];
for (int i = 0; i < nbolts; i++)
{
preheats[i] = heatoffsets[i] + baseHeat;
}
int[] heats = new int[nbolts];
var heats = new double[nbolts];
for (int i = 0; i < nbolts; i++)
{
heats[i] = (int)((Math.Sin(i * Math.PI / nbolts)) * 20 + 30 + (random.NextDouble() - 0.5) * 5);
......
......@@ -36,7 +36,7 @@ namespace FLY.FilmCasting.AutoDie.Client
/// <summary>
/// 厚度控制线 , 厚度% 大于 厚度控制线 自动才会加热控制
/// </summary>
public int CtrlLine { get; set; }
public double CtrlLine { get; set; }
/// <summary>
/// 最大加热量 默认100%
......@@ -48,6 +48,10 @@ namespace FLY.FilmCasting.AutoDie.Client
/// </summary>
public int RangeOfOffset { get; set; }
/// <summary>
/// 中心目标厚度 ,希望生产出来的产品中心比较厚点
/// </summary>
public double CenterTarget { get; set; }
#endregion
......@@ -66,7 +70,7 @@ namespace FLY.FilmCasting.AutoDie.Client
/// <summary>
/// 当前方向的加热策略,必须保证 0~100
/// </summary>
public int[] Heats { get; set; }
public double[] Heats { get; set; }
private int Base { get; set; }
......@@ -76,13 +80,13 @@ namespace FLY.FilmCasting.AutoDie.Client
/// <summary>
/// 加热偏移量
/// </summary>
public int[] Offsets { get; set; }
public double[] Offsets { get; set; }
/// <summary>
/// Heats+Offsets+Base
/// </summary>
public int[] PreHeats { get; set; }
public double[] PreHeats { get; set; }
/// <summary>
......
......@@ -7,7 +7,7 @@ namespace FLY.FilmCasting.AutoDie.Common
public class ChannelValuesMark
{
public string name;
public int[] channelValues;
public double[] channelValues;
}
public class ChannelValuesMarkJsonDb
......
......@@ -57,6 +57,7 @@
<Compile Include="IService\IBulkDbService.cs" />
<Compile Include="IService\IHeatBufService.cs" />
<Compile Include="IService\IFeedbackHeatService.cs" />
<Compile Include="IService\IPlcLinkExt.cs" />
<Compile Include="OBJ_INTERFACE\OBJ_INTERFACE_ID.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Server.OBJProxy\OBJProxy.cs" />
......@@ -73,6 +74,7 @@
<Compile Include="Server\Model\LcTable.cs" />
<Compile Include="Server\Model\Lc_AutoMapperProfile.cs" />
<Compile Include="Server\PLCLink.cs" />
<Compile Include="Server\PlcLinkExt.cs" />
<Compile Include="Server\SysParam.cs" />
<Compile Include="Server\TDGage.cs" />
</ItemGroup>
......
......@@ -28,7 +28,7 @@ namespace FLY.FilmCasting.AutoDie.IService
/// <summary>
/// 厚度控制线 , 厚度% 大于 厚度控制线 自动才会加热控制
/// </summary>
int CtrlLine { get; set; }
double CtrlLine { get; set; }
/// <summary>
/// 最大加热量 默认100%, 也是 当前量界面的显示范围
......@@ -40,6 +40,10 @@ namespace FLY.FilmCasting.AutoDie.IService
/// </summary>
int RangeOfOffset { get; set; }
/// <summary>
/// 中心目标厚度 ,希望生产出来的产品中心比较厚点
/// </summary>
double CenterTarget { get; set; }
#endregion
#region 状态
......@@ -55,17 +59,17 @@ namespace FLY.FilmCasting.AutoDie.IService
/// <summary>
/// 当前加热策略,必须保证 0~100
/// </summary>
int[] Heats { get; }
double[] Heats { get; }
/// <summary>
/// 加热偏移量
/// </summary>
int[] Offsets { get; }
double[] Offsets { get; }
/// <summary>
/// Heats+Offsets+Base, 必须保证0~100
/// </summary>
int[] PreHeats { get; }
double[] PreHeats { get; }
/// <summary>
/// PreHeat 每3个计算的sigma, 最大值
......
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FLY.FilmCasting.AutoDie.IService
{
public interface IPlcLinkExt : INotifyPropertyChanged
{
#region 当前值
/// <summary>
/// 当前电流 有没?
/// </summary>
bool HasElectricity { get; }
/// <summary>
/// 风机是否启动?
/// </summary>
bool HasFan { get; }
bool IsConected { get; }
#endregion
#region 输出
void SetChannelCnt(int channelCnt);
/// <summary>
/// 设置加热量
/// </summary>
/// <param name="values"></param>
void SetHeats(IEnumerable<double> values);
#endregion
}
}
......@@ -131,8 +131,8 @@ namespace FLY.FilmCasting.AutoDie.Server
#endregion
IPLCLink plc;
PLCLink basePlc;
PlcLinkExt plc;
FLY.Thick.FilmCasting.IService.IBoltMapFilmCastingService boltMapFilmCasting;
FLY.Thick.FilmCasting.IService.IBulkDbService bulkDb;
FLY.Thick.Base.IService.ITDGageService gageService;
......@@ -153,7 +153,7 @@ namespace FLY.FilmCasting.AutoDie.Server
/// </summary>
string heats_dir = "feedbackheats";
int[] lastHeats;
double[] lastHeats;
/// <summary>
/// 最后一次保存的记录,
/// 用于当加热改变时,保存记录到数据库
......@@ -193,19 +193,14 @@ namespace FLY.FilmCasting.AutoDie.Server
mHistoryDb = historyDb;
plc = new PLCLink(Misc.StringConverter.ToIPEndPoint(PLCep));
basePlc = new PLCLink(Misc.StringConverter.ToIPEndPoint(PLCep));
plc = new PlcLinkExt();
plc.Init(basePlc);
Misc.BindingOperations.SetBinding(plc, nameof(plc.IsConected), this, nameof(IsConnectedWithPLC));
Misc.BindingOperations.SetBinding(plc, nameof(plc.HasElectricity), this, nameof(HasElectricity));
Misc.BindingOperations.SetBinding(plc, nameof(plc.HasFan), this, nameof(HasFan));
Misc.BindingOperations.SetBinding(plc, nameof(plc.IsConected), () => {
if (plc.IsConected == true)
{
//刚成功连接上
//重新复制数据到 PLC
RecoverPLC();
}
});
InitBuf();
......@@ -313,7 +308,8 @@ namespace FLY.FilmCasting.AutoDie.Server
InitError();
((PLCLink)plc).Start();
basePlc.Start();
}
private void DynArea_PropertyChanged(object sender, PropertyChangedEventArgs e)
......@@ -497,15 +493,15 @@ namespace FLY.FilmCasting.AutoDie.Server
return;//异常
//定位加热
int[] heats = new int[mHeatCell.ChannelCnt];
Array.Clear(heats, 0, heats.Count());
heats[boltIndex1-1] = 80;
heats[boltIndex1] = 80;
heats[boltIndex1+1] = 80;
double[] heats = new double[mHeatCell.ChannelCnt];
heats[boltIndex1-1] = mHeatCell.MaxHeat;
heats[boltIndex1] = mHeatCell.MaxHeat;
heats[boltIndex1+1] = mHeatCell.MaxHeat;
heats[boltIndex2 - 1] = 80;
heats[boltIndex2] = 80;
heats[boltIndex2 + 1] = 80;
heats[boltIndex2 - 1] = mHeatCell.MaxHeat;
heats[boltIndex2] = mHeatCell.MaxHeat;
heats[boltIndex2 + 1] = mHeatCell.MaxHeat;
......@@ -612,7 +608,7 @@ namespace FLY.FilmCasting.AutoDie.Server
IsAuto = false;
//备份 加热策略
int[] preheats = mHeatCell.PreHeats.ToArray();
var preheats = mHeatCell.PreHeats.ToArray();
bool needrestore = true;
//停止检测加热棒
......@@ -648,48 +644,11 @@ namespace FLY.FilmCasting.AutoDie.Server
}
void Output(int[] heats)
{
List<UInt16> list = new List<UInt16>();
for (int i = 0; i < ChannelCnt; i++)
{
UInt16 heat = (UInt16)heats[i];
if (heat < 0)
heat = 0;
else if (heat > 100)
heat = 100;
list.Add(heat);
}
plc.SetHeat(list);
UInt16 heatupdate = (UInt16)(plc.HeatUpdate_R + 1);
if (heatupdate > 100)
heatupdate = 1;
plc.SetHeatUpdate(heatupdate);
}
void RecoverPLC()
void Output(double[] heats)
{
plc.SetChannelCnt((UInt16)ChannelCnt);
if (lastHeats != null)
{
plc.SetHeat(lastHeats.Select(h => (UInt16)h));
}
else
{
//设置全部0进去
plc.SetHeat(new UInt16[ChannelCnt]);
plc.SetHeats(heats);
}
//这里是在 plc.IsConnected = true, 才会触发。
//只有读取一次PLC后,IsConnected 才会=true,
//所以 HeatUpdate_R 肯定是对的
UInt16 heatupdate = (UInt16)(plc.HeatUpdate_R + 1);
if (heatupdate > 100)
heatupdate = 1;
plc.SetHeatUpdate(heatupdate);
}
void setLcThickHeatIsStable(Lc_ThickHeat lcThickHeat)
......
......@@ -229,7 +229,10 @@ namespace FLY.FilmCasting.AutoDie.Server
{
for (int i = 0; i < thks.Count(); i++)
{
thickpercents[i] = (thks[i] - avg) / avg * 100;
if (double.IsNaN(thks[i]))
thickpercents[i] = double.NaN;
else
thickpercents[i] = Math.Round((thks[i] - avg) / avg * 100, 2);
}
}
return thickpercents;
......
......@@ -43,7 +43,7 @@ namespace FLY.FilmCasting.AutoDie.Server
/// <summary>
/// 厚度控制线 , 厚度% 大于 厚度控制线 自动才会加热控制
/// </summary>
public int CtrlLine { get; set; } = 2;
public double CtrlLine { get; set; } = 1;
/// <summary>
/// 最大加热量 默认100%
......@@ -53,6 +53,11 @@ namespace FLY.FilmCasting.AutoDie.Server
/// 偏移量界面的显示范围
/// </summary>
public int RangeOfOffset { get; set; } = 50;
/// <summary>
/// 中心目标厚度 ,希望生产出来的产品中心比较厚点
/// </summary>
public double CenterTarget { get; set; }
#endregion
#region 状态
......@@ -61,7 +66,6 @@ namespace FLY.FilmCasting.AutoDie.Server
/// <summary>
/// 对应的100% 数据,单位是% 数量是ChannelCnt, 数据肯定是完整的!!!!!
/// </summary>
[DoNotCheckEquality]
public double[] ThickPercents { get; set; }
......@@ -73,7 +77,7 @@ namespace FLY.FilmCasting.AutoDie.Server
/// <summary>
/// 当前方向的加热策略,必须保证 0~100
/// </summary>
public int[] Heats { get; protected set; }
public double[] Heats { get; protected set; }
private int Base { get; set; } = 0;
......@@ -85,14 +89,14 @@ namespace FLY.FilmCasting.AutoDie.Server
/// 加热偏移量
/// </summary>
[DoNotCheckEquality]
public int[] Offsets { get; protected set; }
public double[] Offsets { get; protected set; }
/// <summary>
/// Heats+Offsets+Base
/// </summary>
[DoNotCheckEquality]
public int[] PreHeats { get; protected set; }
public double[] PreHeats { get; protected set; }
/// <summary>
......@@ -106,9 +110,16 @@ namespace FLY.FilmCasting.AutoDie.Server
#endregion
public int ChannelCnt { get; set; }
int BoltCnt;
HeatBuf mHeatBuf;
//IBlowingService blowingService;
/// <summary>
/// 厚度 目标值,正常情况全部都是0
/// </summary>
double[] thickPercentTargets;
double centerTarget;
int dataBegin;
int dataEnd;
public Func<object, bool> PreHeatApplyEvent;
public event Action<object> AfterHeatApplyEvent;
public event Action<object> AfterClearOffsetsEvent;
......@@ -144,7 +155,18 @@ namespace FLY.FilmCasting.AutoDie.Server
public void Init(HeatBuf heatBuf)
{
mHeatBuf = heatBuf;
this.PropertyChanged += HeatCell_PropertyChanged;
}
private void HeatCell_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == nameof(CenterTarget))
{
updateThickPercentTargets();
}
}
//public void Init3(IBlowingService blowingService)
//{
// this.blowingService = blowingService;
......@@ -169,10 +191,40 @@ namespace FLY.FilmCasting.AutoDie.Server
MaxHeatSigma = 0;
ThickPercents = new double[ChannelCnt];
Heats = new int[ChannelCnt];
PreHeats = new int[ChannelCnt];
Offsets = new int[ChannelCnt];
Heats = new double[ChannelCnt];
PreHeats = new double[ChannelCnt];
Offsets = new double[ChannelCnt];
create_thickPercentTargets();
}
void create_thickPercentTargets()
{
create_thickPercentTargets(CenterTarget, 0, ChannelCnt - 1);
}
void create_thickPercentTargets(double centerTarget, int dataBegin, int dataEnd)
{
if (centerTarget == 0)
{
thickPercentTargets = new double[ChannelCnt];
this.centerTarget = 0;
this.dataBegin = 0;
this.dataEnd = ChannelCnt - 1;
return;
}
int cnt = (dataEnd - dataBegin) + 1;
double k = Math.Sqrt(centerTarget * 2) / (cnt / 2);
this.thickPercentTargets = new double[ChannelCnt];
for (int i = 0; i < this.thickPercentTargets.Count(); i++)
this.thickPercentTargets[i] = double.NaN;
for (int i = dataBegin; i <= dataEnd; i++)
{
int n = i - cnt / 2;
double t = Math.Pow(k * n, 2);
t = centerTarget - t;
this.thickPercentTargets[i] = Math.Round(t, 2);
}
this.centerTarget = centerTarget;
this.dataBegin = dataBegin;
this.dataEnd = dataEnd;
}
/// <summary>
......@@ -189,14 +241,14 @@ namespace FLY.FilmCasting.AutoDie.Server
//转为 加热棒数量
var thickPercents = ThickPercents;
int[] offsets = new int[ChannelCnt];
double[] offsets = new double[ChannelCnt];
for (int i = 0; i < ChannelCnt; i++)
{
if (!double.IsNaN(thickPercents[i]) &&
if (!double.IsNaN(thickPercents[i]) && !double.IsNaN(thickPercentTargets[i]) &&
mHeatBuf.BoltIsStable[i] && //稳定
(Math.Abs(thickPercents[i]) > CtrlLine))//在控制线已外
{
offsets[i] = (int)Math.Round(thickPercents[i] * Kp);
offsets[i] = (thickPercents[i] - thickPercentTargets[i]) * Kp;//保留一位小数
}
}
......@@ -216,8 +268,49 @@ namespace FLY.FilmCasting.AutoDie.Server
public void SetThickPercents(double[] thkpercents)
{
// Math.Round(double.NaN , 2) 也是 NaN
ThickPercents = thkpercents.Select(tp => Math.Round(tp, 2)).ToArray();
ThickPercents = thkpercents.ToArray();
updateThickPercentTargets();
}
void updateThickPercentTargets()
{
var centerTarget = Math.Round(CenterTarget, 1);
if(centerTarget == 0)
{
create_thickPercentTargets();
return;
}
//找到 ThickPercents 有效数据的开始, 与结束
int dataBegin =-1;
for (int i = 0; i < ThickPercents.Count(); i++)
{
if (!double.IsNaN(ThickPercents[i]))
{
dataBegin = i;
break;
}
}
if (dataBegin == -1) {
//全部数据无效
return;
}
int dataEnd = -1;
for (int i = ThickPercents.Count()-1; i >=0; i--)
{
if (!double.IsNaN(ThickPercents[i]))
{
dataEnd = i;
break;
}
}
if (dataEnd == -1)
{
//全部数据无效
return;
}
//创建目标曲线
create_thickPercentTargets(centerTarget, dataBegin, dataEnd);
}
#region IHeatCell 接口 成员函数
......@@ -254,12 +347,12 @@ namespace FLY.FilmCasting.AutoDie.Server
/// </summary>
void ModifyBase()
{
int[] preheat = new int[ChannelCnt];
double[] preheat = new double[ChannelCnt];
for (int i = 0; i < ChannelCnt; i++)
preheat[i] = Heats[i] + Offsets[i] + Base;
int min = preheat.Min();
int max = preheat.Max();
int min = (int)preheat.Min();
int max = (int)preheat.Max();
int avg = (int)preheat.Average();
int base_offset;
......@@ -317,16 +410,14 @@ namespace FLY.FilmCasting.AutoDie.Server
/// </summary>
public void ClearPreHeats()
{
int[] heats = new int[ChannelCnt];
Array.Clear(heats, 0, ChannelCnt);
ModifyPreHeats(heats);
ModifyPreHeats(new double[ChannelCnt]);
}
/// <summary>
/// 调整PreHeats
/// </summary>
/// <param name="heats"></param>
public void ModifyPreHeats(int[] heats)
public void ModifyPreHeats(double[] heats)
{
if (heats.Count() != ChannelCnt)
......@@ -341,7 +432,7 @@ namespace FLY.FilmCasting.AutoDie.Server
NotifyPropertyChanged(nameof(PreHeats));
UpdateHeatSigmas();
}
public void ModifyHeats(int[] heats)
public void ModifyHeats(double[] heats)
{
if (heats.Count() != ChannelCnt)
return;
......@@ -350,10 +441,11 @@ namespace FLY.FilmCasting.AutoDie.Server
Base = 0;
for (int i = 0; i < ChannelCnt; i++)
{
if (Heats[i] != heats[i])
var h = Math.Round(heats[i], 1);
if (Heats[i] != h)
{
isChanged = true;
Heats[i] = heats[i];
Heats[i] = h;
Offsets[i] = PreHeats[i] - Heats[i];
}
}
......@@ -369,20 +461,20 @@ namespace FLY.FilmCasting.AutoDie.Server
/// </summary>
public void Cal()
{
var thickpercents = ThickPercents;// Common.MyMath.ZoomOut(ThickPercents, BoltCnt / ChannelCnt);
int[] offsets = new int[ChannelCnt];
var thickpercents = ThickPercents;
double[] offsets = new double[ChannelCnt];
for (int i = 0; i < ChannelCnt; i++)
{
if (double.IsNaN(thickpercents[i]))
if (double.IsNaN(thickpercents[i]) || double.IsNaN(thickPercentTargets[i]))
offsets[i] = 0;
else
offsets[i] = (int)Math.Round(thickpercents[i] * Kp);
offsets[i] = (thickpercents[i] - thickPercentTargets[i]) * Kp;
}
Offsets = offsets;
UpdatePreHeats();
}
#region PreHeats 平滑处理
double[] GetHeatSigmas(int[] heats)
double[] GetHeatSigmas(double[] heats)
{
var heatsigmas = new double[ChannelCnt];
for (int i = 0; i < ChannelCnt; i++)
......@@ -418,12 +510,11 @@ namespace FLY.FilmCasting.AutoDie.Server
/// </summary>
public void Smooth()
{
int[] heats = PreHeats.ToArray();
int[] heats2 = new int[ChannelCnt];
bool hasChanged = false;
double[] heats = PreHeats.ToArray();
double[] heats2 = new double[ChannelCnt];
bool hasChanged2 = false;
double[] heatsigmas;
do
while(true)
{
//1.更新sigma
heatsigmas = GetHeatSigmas(heats);
......@@ -434,25 +525,8 @@ namespace FLY.FilmCasting.AutoDie.Server
if (heatsigmas[i] > (ThresholdHeatSigma)) //不行,要滤波!!!
{
//连续3个滤波
int[] dat = getSubArray(heats, i);
heats2[i] = (int)Math.Round(dat.Average());
//if (heats2[i] == heats[i])
//{
// //居然一样,修改旁边的两个的值
// if (i > 0) {
// int idx = i-1;
// dat = getSubArray(heats, idx);
// heats2[idx] = (int)Math.Round(dat.Average());
// }
// if (i == heats.Count() - 1)
// {
// int idx = 0;
// dat = getSubArray(heats, idx);
// heats2[idx] = (int)Math.Round(dat.Average());
// }
//}
double[] dat = getSubArray(heats, i);
heats2[i] = Math.Round(dat.Average(), 1);
}
else
{
......@@ -461,7 +535,8 @@ namespace FLY.FilmCasting.AutoDie.Server
}
//3.有滤波行为,继续求循环,求sigma,判断。。。。。
hasChanged = false;
bool hasChanged = false;
for (int i = 0; i < heats.Count(); i++)
{
if (heats[i] != heats2[i])
......@@ -472,8 +547,10 @@ namespace FLY.FilmCasting.AutoDie.Server
}
if (hasChanged)
hasChanged2 = true;
else
break;
} while (hasChanged);
}
if (hasChanged2)
{
......@@ -505,18 +582,19 @@ namespace FLY.FilmCasting.AutoDie.Server
{
Offsets[i] = 0;
int heat = PreHeats[i];
if (heat < 0)
var h = Math.Round(PreHeats[i], 1);
if (h < 0)
{
//需要整体提升
heat = 0;
h = 0;
}
else if (heat > 100)
else if (h > 100)
{
//需要整体调低
heat = 100;
h = 100;
}
Heats[i] = heat;
Heats[i] = h;
}
NotifyPropertyChanged(nameof(Offsets));
......@@ -534,13 +612,13 @@ namespace FLY.FilmCasting.AutoDie.Server
{
for (int i = 0; i < ChannelCnt; i++)
{
int preheat = Heats[i] + Offsets[i] + Base;
double h = Heats[i] + Offsets[i] + Base;
if (preheat > 100)
preheat = 100;
else if (preheat < 0)
preheat = 0;
PreHeats[i] = preheat;
if (h > 100)
h = 100;
else if (h < 0)
h = 0;
PreHeats[i] = h;
}
UpdateHeatSigmas();
NotifyPropertyChanged(nameof(PreHeats));
......@@ -648,9 +726,9 @@ namespace FLY.FilmCasting.AutoDie.Server
/// <summary>
/// 厚度控制线 , 厚度% 大于 厚度控制线 自动才会加热控制
/// </summary>
public int CtrlLine = 2;
public double CtrlLine = 1;
public double CenterTarget = 0;
#endregion
}
......
......@@ -586,24 +586,22 @@ namespace FLY.FilmCasting.AutoDie.Server
}
int[] getSingleHeat_100(int channelcnt, params int[] index)
double[] getSingleHeat_100(int channelcnt, params int[] index)
{
int[] heats = new int[channelcnt];
Array.Clear(heats, 0, heats.Count());
double[] heats = new double[channelcnt];
foreach (int i in index)
heats[i] = 100;
return heats;
}
int[] getSingleHeat_100(int channelcnt, int index)
double[] getSingleHeat_100(int channelcnt, int index)
{
int[] heats = new int[channelcnt];
Array.Clear(heats, 0, heats.Count());
double[] heats = new double[channelcnt];
heats[index] = 100;
return heats;
}
int[] getAllHeat_30(int channelcnt)
double[] getAllHeat_30(int channelcnt)
{
int[] heats = new int[channelcnt];
double[] heats = new double[channelcnt];
for (int i = 0; i < heats.Count(); i++)
{
heats[i] = 30;
......
......@@ -93,7 +93,7 @@ namespace FLY.FilmCasting.AutoDie.Server.Model
/// <summary>
/// 1幅加热数据 %
/// </summary>
public int[] Heats { get; set; }
public double[] Heats { get; set; }
}
......
using FLY.FilmCasting.AutoDie.IService;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Threading;
namespace FLY.FilmCasting.AutoDie.Server
{
/// <summary>
/// PlcLink 只有 1~100, 最小单位1, 扩展它, 1~100, 最小单位 0.1
/// </summary>
public class PlcLinkExt: IPlcLinkExt
{
/// <summary>
/// 每颗粒时间 5s
/// </summary>
const int CellSec = 3;
/// <summary>
/// 占空比,总颗粒数
/// </summary>
const int DutyCount = 10;
int channelCnt = 96;
double[] heats;
/// <summary>
/// 当前电流 有没?
/// </summary>
public bool HasElectricity { get; private set; }
/// <summary>
/// 风机是否启动?
/// </summary>
public bool HasFan { get; private set; }
public bool IsConected { get; private set; }
public event PropertyChangedEventHandler PropertyChanged;
PLCLink plcLink;
DispatcherTimer timer;
Stopwatch stopwatch;
int dutyIndex = 0;
public PlcLinkExt()
{
}
public void Init(PLCLink plcLink)
{
this.plcLink = plcLink;
Misc.BindingOperations.SetBinding(plcLink, nameof(plcLink.IsConected), this, nameof(IsConected));
Misc.BindingOperations.SetBinding(plcLink, nameof(plcLink.HasElectricity), this, nameof(HasElectricity));
Misc.BindingOperations.SetBinding(plcLink, nameof(plcLink.HasFan), this, nameof(HasFan));
this.PropertyChanged += PlcLinkExt_PropertyChanged;
timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromSeconds(1);
timer.Tick += Timer_Tick;
stopwatch = new Stopwatch();
if (plcLink.IsConected)
{
//刚连上,把 之前的数据都重新发给它。
plcLink.SetChannelCnt((UInt16)channelCnt);
DutyStart();
}
}
void DutyStart()
{
stopwatch.Restart();
timer.Start();
dutyIndex = 0;
setHeats();
}
void DutyStop()
{
stopwatch.Stop();
timer.Stop();
}
void setHeats()
{
if (!plcLink.IsConected)
return;
UInt16[] plcHeats = heats.Select(h => {
int h_int = (int)h;
int v = (int)((h - h_int) * DutyCount);
if (v > dutyIndex)
{
return (UInt16)(h_int + 1);
}
else {
return (UInt16)h_int;
}
}) as UInt16[];
plcLink.SetHeat(plcHeats);
UInt16 heatupdate = (UInt16)(plcLink.HeatUpdate_R + 1);
if (heatupdate > 100)
heatupdate = 1;
plcLink.SetHeatUpdate(heatupdate);
}
private void Timer_Tick(object sender, EventArgs e)
{
if (stopwatch.Elapsed < TimeSpan.FromSeconds(CellSec))
{
return;
}
stopwatch.Restart();
setHeats();
dutyIndex++;
if (dutyIndex > DutyCount)
dutyIndex = 0;
}
private void PlcLinkExt_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == nameof(plcLink.IsConected))
{
if (plcLink.IsConected)
{
//刚连上,把 之前的数据都重新发给它。
plcLink.SetChannelCnt((UInt16)channelCnt);
DutyStart();
}
else {
DutyStop();
}
}
}
public void SetChannelCnt(int channelCnt)
{
this.channelCnt = channelCnt;
plcLink.SetChannelCnt((UInt16)channelCnt);
}
/// <summary>
/// 设置加热量
/// </summary>
/// <param name="values"></param>
public void SetHeats(IEnumerable<double> values)
{
heats = values.Select(h =>
{
if (h < 0) h = 0;
else if (h > 100) h = 100;
return h;
}).ToArray();
setHeats();
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment