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
///
const double Mmpp2 = 0.24925;
///
/// 编码器1 mm/p
///
public double Mmpp { get; set; } = 0.2;
public double VSignOffset { get; set; }
public double SensorWidth { get; set; } = 25;
///
/// 长度为 SensorWidth 的卷积核
///
public List 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 conv = new List();
//用圆形代替
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);
}
}
}