using FLY.Thick.Base.Common; using FLY.Thick.Base.Server; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; namespace FLY.Simulation.Battery.RayLaser { public class GageAd_Ray : ISimulationGageAD { CurveCollection curve; /// 编码器2 mm/p 胶轮周长200mm,编码器 转1圈800脉冲 正确应该0.25 /// </summary> const double Mmpp2 = 0.24925; /// <summary> /// 编码器1 mm/p /// </summary> public double Mmpp { get; set; } = 0.2; public double VSignOffset { get; set; } public double SensorWidth { get; set; } = 25; /// <summary> /// 长度为 SensorWidth 的卷积核 /// </summary> public List<double> Conv { get; private set; } public int TotalLength { get; private set; } GageAd gageAd; public GageAd_Ray() { } public void Init(GageAd gageAd) { this.gageAd = gageAd; curve = gageAd.curve_ray; VSignOffset = gageAd.VSignOffsetRay; TotalLength = gageAd.TotalLength; updateConv(); } void updateConv() { List<double> conv = new List<double>(); //用圆形代替 double sensorRadius = SensorWidth / 2.0; for (int i = 0; i < SensorWidth; i++) { double r = Math.Abs(-sensorRadius + i); double h = Math.Sqrt(Math.Pow(sensorRadius, 2) - Math.Pow(r, 2)); conv.Add(h * 2); } double sum = conv.Sum(); conv = conv.Select(v => v / sum).ToList(); Conv = conv; } int GetAdMm(int mm, int mm_v_offset) { int posLength = (int)(gageAd.FilmPosition*1000 - VSignOffset+ mm_v_offset); double value = gageAd.GetValue(true, mm, posLength, out GageAd.PosType posType); if (posType == GageAd.PosType.Hold) { return 0; } int ad = curve.Value2Ad(value, AD2ValueFlag.NoRevised); if (ad > 65535) ad = 65535; else if (ad < 0) ad = 0; return ad; } Random random = new Random(); public int GetAD(int mm) { //需要对探头直径范围的数据求均值 double hValue = 0; for (int i = 0; i < Conv.Count(); i++) { int mm2 = (int)(mm - Conv.Count()/2.0 + i); hValue += GetAdMm(mm2, 0) * Conv[i]; } double vValue = 0; for (int i = 0; i < Conv.Count(); i++) { int mm_v_offset = (int)(-Conv.Count() / 2.0 + i); vValue += GetAdMm(mm, mm_v_offset) * Conv[i]; } int ad = (int)((hValue + vValue) / 2); return ad; } public void OnPoll(DateTime now) { //不实现 gageAd.OnPoll(now); } public UInt16 GetInput() { UInt16 istatus = 0x0fff; if (gageAd.IsVSignLight) Misc.MyBase.CLEARBIT(ref istatus, IODefinition.IN_VSENSOR); if(gageAd.IsSyncLight) Misc.MyBase.CLEARBIT(ref istatus, IODefinition.IN_SYNC); return istatus; } public void SetOutput(UInt16 output) { if (!Misc.MyBase.CHECKBIT(output, IODefinition.OUT_SYNC)) gageAd.IsSyncLight = true; else gageAd.IsSyncLight = false; } public int GetPosition2() { return (int)(gageAd.FilmPosition * 1000 / Mmpp2); } public int GetSpeed2() { return (int)(gageAd.FilmVelocity * 1000 / 60 / Mmpp2); } } }