using Misc;
using NLog.Fluent;
using NLog.LayoutRenderers.Wrappers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FlyADBase
{
///
/// 高级timegrid助手
/// 使用说明:
/// ADPool 只能储存 1min数据, 其它XXXPool 保存1.5min数据
///
///
/// 获取最后一次运行动作的开始与结束时间
/// bool ret = mTimeGridAdvHelper.GetLastRunningTime(out DateTime beginTime, out DateTime endTime, out int marker, out DRIVE_MAN_ORDER order);
///
/// 获取 指定时间范围的 timegrid 数据
/// var adList = mTimeGridAdvHelper.GetAD(beginTime, endTime, out DateTime reponse_endTime);
///
/// 获取 指定时间范围的 pos 数据
/// var posList = mTimeGridAdvHelper.GetPos(reponse_endTime,adList.Count());
///
/// 获取 指定时间范围的 pos2 数据
/// var pos2List = mTimeGridAdvHelper.GetPos2(reponse_endTime,adList.Count());
///
/// 获取 指定时间范围的 输入口 数据
/// var istatusList = mTimeGridAdvHelper.GetIStatus(reponse_endTime,adList.Count());
///
/// 转为 grid 数据
/// int posLen = 8900;
/// var grid = ToGrid(adList, posList, posOfGrid = 10, gridLen = posLen/10);
///
///
public class TimeGridAdvHelper
{
NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
#region 一分钟数据缓存池, 目标每个AD数据(1ms) 都有对应的其它数据
public const int POOL_SIZE_SECOND = 120;
///
/// AD数据池时间间隔为1ms,数据是肯定是连续的。Add数据时,非连续,填充数据直到连续
///
public List DataPool = new List();
///
/// DriveStatus 数据池, 肯定最少有一个数据
///
public List DriveStatusPool = new List();
#endregion
public DateTime NewestTime = DateTime.MinValue;
///
/// 上一次脉冲改变的时间
///
public DateTime positionChangedTime;
///
/// 上一次脉冲2改变的时间
///
public DateTime position2ChangedTime;
///
/// 上一次输入口改变的时间
///
public DateTime istatusChangedTime;
///
///
///
public void Init()
{
Clear();
}
public int Time2Index(DateTime time)
{
if (time == DateTime.MinValue)
return -1;
return TimeGridAdvHelperExt.Time2Index(DataPool.Count(), NewestTime, time);
}
public DateTime Index2Time(int index)
{
return TimeGridAdvHelperExt.Index2Time(DataPool.Count(), NewestTime, index);
}
public class AddDataResponse
{
public bool isChanged => isPosChanged || isPos2Changed || isIstatusChanged;
public bool isPosChanged;
public bool isPos2Changed;
public bool isIstatusChanged;
public UInt16 ichanged;
}
///
/// 添加数据,且判断数据量是否够触发事件, 时间间隔为 1ms
/// postion, 与 postion2 比较特别。 会记录最后一次改变的时间。
/// 当再此改变, 两个数据点的数据,需要重新修正。 线性插值。
/// 两个时间点限制在150ms内。
///
///
///
///
///
///
///
public AddDataResponse AddData(DateTime dt, int ad, int ad2, int postion, int postion2, UInt16 istatus)
{
if (DataPool.Count()==0)
{
//第1次添加
DataPool.Add(new DateTimeUnit5() { ad = ad, ad2 = ad2, pos = postion, pos2 = postion2, istatus = istatus });
NewestTime = dt;
//记录脉冲改变点
positionChangedTime = NewestTime;
position2ChangedTime = NewestTime;
istatusChangedTime = NewestTime;
return new AddDataResponse();
}
if (dt < NewestTime && NewestTime - dt > TimeSpan.FromMilliseconds(2)) //时间异常,居然早2秒了,数据全部删除
{
//TODO, 不能没有状态
Clear();
DataPool.Add(new DateTimeUnit5() { ad = ad, ad2 = ad2, pos = postion, pos2 = postion2, istatus = istatus });
NewestTime = dt;
//记录脉冲改变点
positionChangedTime = NewestTime;
position2ChangedTime = NewestTime;
istatusChangedTime = NewestTime;
return new AddDataResponse();
}
if ( dt > NewestTime && (dt - NewestTime > TimeSpan.FromSeconds(0.5)))//超过0.5s没放数据,异常
{
//TODO, 不能没有状态
Clear();
DataPool.Add(new DateTimeUnit5() { ad = ad, ad2 = ad2, pos = postion, pos2 = postion2, istatus = istatus });
NewestTime = dt;
//记录脉冲改变点
positionChangedTime = NewestTime;
position2ChangedTime = NewestTime;
istatusChangedTime = NewestTime;
return new AddDataResponse();
}
if (dt <= NewestTime)
{
//把最后一个删除, 换为这个新的
DataPool.RemoveAt(DataPool.Count() - 1);
DataPool.Add(new DateTimeUnit5() { ad = ad, ad2 = ad2, pos = postion, pos2 = postion2, istatus = istatus });
NewestTime = dt;
}
else
{
DateTime last_dt = NewestTime;
while (true)
{
last_dt += TimeSpan.FromTicks(TimeSpan.TicksPerMillisecond);
if (last_dt < dt)
{
//填充之前的数据
DataPool.Add(DataPool.Last());
}
else
{
//填充完了,放入新的数据
DataPool.Add(new DateTimeUnit5() { ad = ad, ad2 = ad2, pos = postion, pos2 = postion2, istatus = istatus });
NewestTime = last_dt;
break;
}
}
}
LimitPool();
AddDataResponse response = new AddDataResponse();
//检查是否改变了
if (DataPool.Count > 1)
{
var data_last_2 = DataPool[DataPool.Count - 2];
response.ichanged = (UInt16)(data_last_2.istatus ^ istatus);
if (response.ichanged != 0)
{
response.isIstatusChanged = true;
istatusChangedTime = NewestTime;
}
if (data_last_2.pos != postion) {
response.isPosChanged = true;
//插值!!!!
LinearInterpolation(1, positionChangedTime);
positionChangedTime = NewestTime;
}
if (data_last_2.pos2 != postion2)
{
response.isPos2Changed = true;
//插值!!!!
LinearInterpolation(2, position2ChangedTime);
position2ChangedTime = NewestTime;
}
}
return response;
}
///
/// 脉冲的线性插值
///
void LinearInterpolation(int posNo, DateTime keyTime)
{
if(posNo!=1 && posNo != 2)
{
throw new Exception($"写错程序, posNo={posNo} 只能是 1或2");
}
//插值!!!!
int len = (int)(NewestTime - keyTime).TotalMilliseconds;
if (len > 150)
{
//限制时间
len = 150;
}
if (len > DataPool.Count - 1)
{
//异常
len = DataPool.Count - 1;
}
var dataLastPoint = DataPool[DataPool.Count - 1];
var dataKeyPoint = DataPool[DataPool.Count - len - 1];
int kp;
int distance;
if (posNo == 1)
{
kp = dataKeyPoint.pos;
distance = (dataLastPoint.pos - dataKeyPoint.pos);
}
else
{
kp = dataKeyPoint.pos2;
distance = (dataLastPoint.pos2 - dataKeyPoint.pos2);
}
for (int i = 0; i < len - 1; i++)
{
int index = DataPool.Count - len + i;
int pos = distance * (i + 1) / len + kp;
var data = DataPool[index];
if(posNo==1)
data.pos = pos;
else
data.pos2 = pos;
DataPool[index] = data;
}
}
void LimitPool()
{
if (NewestTime == DateTime.MinValue)
return;
if (DataPool.Count() < (POOL_SIZE_SECOND + 30) * 1000)
{
//比限定的多了30秒 才会动作
return;
}
//只保持1分钟数据
int remove_cnt = DataPool.Count() - POOL_SIZE_SECOND * 1000;
DataPool.RemoveRange(0, remove_cnt);
//限制的时间
var limitTime_other = NewestTime - TimeSpan.FromSeconds(POOL_SIZE_SECOND + 30);
LimitSimplePool(DriveStatusPool, limitTime_other);
}
///
///
///
/// IDateTimeUnit
/// 缓存区
/// 缓存区容量单位min
void LimitSimplePool(List pool, DateTime limitTime) where T : IDateTimeUnit
{
//删除Pos 数据池
int removeCnt = 0;
for (int i = 0; i < pool.Count(); i++)
{
var cell = pool[i];
if (cell.dt < limitTime)
{
//需要删除
removeCnt = i + 1;
}
else
{
break;
}
}
if (removeCnt > 0)
{
//不能全部数据删除完,必须留一个
if (removeCnt == pool.Count())
{
removeCnt--;
if (removeCnt <= 0)
return;//不用删除了
}
pool.RemoveRange(0, removeCnt);
}
}
///
/// 添加驱动状态, 返回true,则driveStatus变化了
///
///
///
///
public bool AddDriveStatus(DateTime time,DRIVE_MAN_ORDER order, DRIVE_MAN_STATUS driveStatus)
{
var pool = DriveStatusPool;
if (pool.Count > 0)
{
if (pool.Last().dt > time)
{
//异常,把之前的数据删除
pool.Clear();
}
else if (pool.Last().dt == time)
{
//删除之前那个
pool.RemoveAt(pool.Count() - 1);
}
}
pool.Add(new DateTimeUnit4() { dt = time, order = order, driveStatus = driveStatus });
if (pool.Count() > 1)
{
return pool[pool.Count() - 2].driveStatus != driveStatus;
}
return false;
}
///
///
///
public void Clear()
{
DataPool.Clear();
DriveStatusPool.Clear();
}
///
/// 获取最后一次运行的时间段
///
///
///
///
///
public bool GetLastRunningTime(out DateTime begin, out DateTime end, out DRIVE_MAN_ORDER order) {
begin = DateTime.MinValue;
end = DateTime.MinValue;
order = DRIVE_MAN_ORDER.IDLE;
//1. 找 最后一个 driveStatus!=running的
int idxOfStop = -1;
for (int i = DriveStatusPool.Count() - 1; i >= 0; i--)
{
var cell = DriveStatusPool[i];
if (cell.driveStatus != DRIVE_MAN_STATUS.RUNNING)
{
//对!!它是。但继续向前找找看
idxOfStop = i;
}
else
{
if (idxOfStop != -1)
{
//之前已经找到了,
break;
}
}
}
if (idxOfStop == -1)
{
//一直在running,还没停下来
return false;
}
//2. 最向前找running的
int idxOfRunning = -1;
for (int i = idxOfStop - 1; i >= 0; i--)
{
var cell = DriveStatusPool[i];
if (cell.driveStatus == DRIVE_MAN_STATUS.RUNNING)
{
//对!!它是。但继续向前找找看
idxOfRunning = i;
}
else
{
//没了
break;
}
}
if (idxOfRunning == -1)
{
//一直停着,没有运行过
return false;
}
begin = DriveStatusPool[idxOfRunning].dt;
end = DriveStatusPool[idxOfStop].dt;
order = DriveStatusPool[idxOfStop].order;
return true;
}
///
/// 获取最后一次运行中的timegrid;
/// 找到最后一个 driveStatus!=running的, 最向前找running的
///
/// 开始时间
/// 结束时间
///
public List GetData(DateTime begin, DateTime end, out DateTime response_endTime)
{
return TimeGridAdvHelperExt.GetData(DataPool, NewestTime, begin, end, out response_endTime);
}
public List GetData(DateTime begin)
{
return TimeGridAdvHelperExt.GetData(DataPool, NewestTime, begin);
}
}
public interface IDateTimeUnit
{
DateTime dt { get; set; }
}
public struct DateTimeUnit: IDateTimeUnit
{
public int data;
public DateTime dt { get; set; }
public override string ToString()
{
return $"{dt.Ticks} | {data}";
}
}
public struct DateTimeUnit4 : IDateTimeUnit
{
public DateTime dt { get; set; }
public DRIVE_MAN_ORDER order;
public DRIVE_MAN_STATUS driveStatus;
public int marker;
public override string ToString()
{
return $"{dt.Ticks} | {order} | {driveStatus} | {marker}";
}
}
public struct DateTimeUnit5
{
public int ad;
public int ad2;
public int pos;
public int pos2;
public UInt16 istatus;
public int GetPos(int no)
{
if (no == 1)
return pos;
else
return pos2;
}
public int GetPosByIndex(int index)
{
if (index == 0)
return pos;
else
return pos2;
}
public override string ToString()
{
return $"ad={ad} | ad2={ad2} | p={pos} | p2={pos2} | i={istatus:X4}";
}
}
public struct DateTimeUnit2: IDateTimeUnit
{
public DateTime dt { get; set; }
public UInt16 istatus;
public bool isPosValid;
public int pos;
public int pos2;
public override string ToString()
{
if(isPosValid)
return $"{dt.Ticks} | ({istatus:X2}) | 1={pos} | 2={pos2}";
else
return $"{dt.Ticks} | ({istatus:X2})";
}
}
public static class TimeGridAdvHelperExt
{
public static int Time2Index(int dataCount, DateTime newestTime, DateTime time)
{
//TODO .TotalMilliseconds 是double,有机会出现0.99999问题
int index = dataCount - 1 - (int)(newestTime - time).TotalMilliseconds;
return index;
}
public static DateTime Index2Time(int dataCount, DateTime newestTime, int index)
{
return newestTime - TimeSpan.FromMilliseconds(dataCount - 1 - index);
}
///
/// 导出的数据间隔是1ms 一个
///
/// AD缓存区
/// 开始时间点
///
public static List GetData(List dataPool, DateTime newestTime, DateTime begin)
{
//时间转为序号
int begin_idx = Time2Index(dataPool.Count(), newestTime, begin) + 1;
//限制序号位置
if (begin_idx < 0)
begin_idx = 0;
if (begin_idx > dataPool.Count() - 1)
begin_idx = dataPool.Count() - 1;
List reponse = dataPool.GetRange(begin_idx, dataPool.Count()-1 - begin_idx + 1);
return reponse;
}
///
/// 获取 时间在 begin~end 的 Data数据
///
/// 缓存区
/// 缓存区最后一个点的时间
/// 开始时间点
/// 结束时间点
/// 导出数据最后一个点的时间
///
public static List GetData(List dataPool, DateTime newestTime, DateTime begin, DateTime end, out DateTime response_endTime)
{
//时间转为序号
int begin_idx = Time2Index(dataPool.Count(), newestTime, begin) + 1;
//限制序号位置
if (begin_idx < 0)
begin_idx = 0;
if (begin_idx > dataPool.Count() - 1)
begin_idx = dataPool.Count() - 1;
int end_idx = dataPool.Count() - (int)((newestTime - end).TotalMilliseconds);
if (end_idx < 0)
end_idx = 0;
if (end_idx > dataPool.Count() - 1)
end_idx = dataPool.Count() - 1;
if (begin_idx > end_idx)
{
var t = begin_idx;
begin_idx = end_idx;
end_idx=t;
}
response_endTime = newestTime - TimeSpan.FromMilliseconds(dataPool.Count() - 1 - end_idx);
List reponse = dataPool.GetRange(begin_idx, end_idx-begin_idx+1);
return reponse;
}
///
/// 数据滞后
///
///
///
///
public static bool AdLagCorr(List dataPool, ref DateTime endTime, int ad1Lag, int ad2Lag)
{
int lag = Math.Max(ad1Lag, ad2Lag);
if (lag == 0)
return true;
int endIdx = dataPool.Count() - 1 - lag;
if (endIdx < 0)
return false;
int removeCnt = lag;
for (int i = 0; i dataPool.Count() - 1)
continue;
if (idxOfAd2 > dataPool.Count() - 1)
continue;
var data = dataPool[index];
data.ad = dataPool[idxOfAd1].ad;
data.ad2 = dataPool[idxOfAd2].ad2;
dataPool[index] = data;
}
//删除没有改动的数据
if (removeCnt > 0)
{
dataPool.RemoveRange(endIdx + 1, removeCnt);
endTime -= TimeSpan.FromMilliseconds(removeCnt);
}
return true;
}
///
/// 获取平均速度, 单位 脉冲/min
///
/// 脉冲缓存区
/// 开始时间点
/// 结束时间点
///
public static double GetSpeed(List dataPool, DateTime newestTime, DateTime begin, DateTime end, int posNo)
{
if (posNo != 1 && posNo != 2)
throw new Exception($"写错程序 GetSpeed posNo={posNo} 只能是1 或 2");
int begin_idx = dataPool.Count() - (int)((newestTime - begin).TotalMilliseconds);
int end_idx = dataPool.Count() - (int)((newestTime - end).TotalMilliseconds);
if (begin_idx < 0)
begin_idx = 0;
if (end_idx > dataPool.Count() - 1)
end_idx = dataPool.Count() - 1;
var beginPoint = dataPool[begin_idx];
var endPoint = dataPool[end_idx];
return (endPoint.GetPos(posNo) - beginPoint.GetPos(posNo)) / ((end_idx - begin_idx) / 60000.0);
}
///
/// 获取平均速度, 单位 脉冲/min
///
/// 脉冲缓存区
/// 开始时间点
/// 结束时间点
///
public static double GetSpeedByIndex(List dataPool, DateTime newestTime, DateTime begin, DateTime end, int posIndex)
{
if (posIndex != 0 && posIndex != 1)
throw new Exception($"写错程序 GetSpeedByIndex posIndex={posIndex} 只能是0 或 1");
int begin_idx = dataPool.Count() - (int)(newestTime - begin).TotalMilliseconds;
int end_idx = dataPool.Count() - (int)(newestTime - end).TotalMilliseconds;
if (begin_idx < 0)
begin_idx = 0;
if (end_idx > dataPool.Count() - 1)
end_idx = dataPool.Count() - 1;
var beginPoint = dataPool[begin_idx];
var endPoint = dataPool[end_idx];
return (endPoint.GetPosByIndex(posIndex) - beginPoint.GetPosByIndex(posIndex)) / ((end_idx - begin_idx) / 60000.0);
}
///
/// 获取平均速度, 单位 脉冲/min
///
/// 脉冲缓存区
/// 开始时间点
/// 结束时间点
///
public static double GetSpeed(List dataPool, int dataLen, int posNo)
{
if (posNo != 1 && posNo != 2)
throw new Exception($"写错程序 GetSpeed posNo={posNo} 只能是1 或 2");
int begin_idx = dataPool.Count() - dataLen;
int end_idx = dataPool.Count() - 1;
if (begin_idx < 0)
begin_idx = 0;
if (end_idx > dataPool.Count() - 1)
end_idx = dataPool.Count() - 1;
var beginPoint = dataPool[begin_idx];
var endPoint = dataPool[end_idx];
return (endPoint.GetPos(posNo) - beginPoint.GetPos(posNo)) / ((end_idx - begin_idx) / 60000.0);
}
///
/// 获取平均速度, 单位 脉冲/min
///
/// 脉冲缓存区
/// 开始时间点
/// 结束时间点
///
public static double GetSpeedByIndex(List dataPool, int dataLen, int posIndex)
{
if (posIndex != 0 && posIndex != 1)
throw new Exception($"写错程序 GetSpeed posIndex={posIndex} 只能是0 或 1");
int begin_idx = dataPool.Count() - dataLen;
int end_idx = dataPool.Count() - 1;
if (begin_idx < 0)
begin_idx = 0;
if (end_idx > dataPool.Count() - 1)
end_idx = dataPool.Count() - 1;
var beginPoint = dataPool[begin_idx];
var endPoint = dataPool[end_idx];
return (endPoint.GetPosByIndex(posIndex) - beginPoint.GetPosByIndex(posIndex)) / ((end_idx - begin_idx) / 60000.0);
}
///
/// 获取时间对应的 位置点
///
///
/// 脉冲缓存池
/// 查询开始序号
///
public static int GetPos(List dataPool, DateTime newestTime, DateTime dt, int posNo)
{
if (posNo != 1 && posNo != 2)
throw new Exception($"写错程序 GetSpeed posNo={posNo} 只能是1 或 2");
int idx = dataPool.Count() - (int)((newestTime - dt).TotalMilliseconds);
if (idx < 0)
idx = 0;
if (idx > dataPool.Count() - 1)
idx = dataPool.Count() - 1;
var point = dataPool[idx];
return point.GetPos(posNo);
}
///
/// 获取时间对应的 位置点
///
///
/// 脉冲缓存池
/// 查询开始序号
///
public static int GetPosByIndex(List dataPool, DateTime newestTime, DateTime dt, int posIndex)
{
if (posIndex != 0 && posIndex != 1)
throw new Exception($"写错程序 GetSpeed posIndex={posIndex} 只能是0 或 1");
int idx = dataPool.Count() - (int)((newestTime - dt).TotalMilliseconds);
if (idx < 0)
idx = 0;
if (idx > dataPool.Count() - 1)
idx = dataPool.Count() - 1;
var point = dataPool[idx];
return point.GetPosByIndex(posIndex);
}
///
/// 输出 grid图。 dataPool[x+ad0Lag].ad 对应 dataPool[x].position
///
/// 1ms数据缓存区
/// 1grid的脉冲数
/// grid总数
/// 数据有效部分开始点
/// 数据有效部分结束点
/// 导出的AD1 grid图
/// 导出的AD2 grid图
/// AD1 滞后
/// AD2 滞后
/// 裁剪grid图 只导出有效部分
public static void ToGrid(
List dataPool, int posOfGrid,
int gridLen,
out int grid_start, out int grid_end,
out int[] gridsOfAd1, out int[] gridsOfAd2,
bool isMiniGrid=false)
{
int[] gridsOfAd1_sum = new int[gridLen];
int[] gridsOfAd1_cnt = new int[gridLen];
int[] gridsOfAd2_sum = new int[gridLen];
int[] gridsOfAd2_cnt = new int[gridLen];
int grid_idx_last = -1;
grid_start = Misc.MyBase.NULL_VALUE;
grid_end = Misc.MyBase.NULL_VALUE;
//grid_idx 应该要连续变化,不是,那就插值
for (int j = 0; j < dataPool.Count(); j++)
{
int ad1 = dataPool[j].ad;
int ad2 = dataPool[j].ad2;
int pos = dataPool[j].pos;
int grid_idx = pos / posOfGrid;
//grid不能小于0 或 大于等于 gridLen
if (grid_idx < 0 || grid_idx >= gridLen)
continue;
if (!Misc.MyBase.ISVALIDATA(grid_start))
{
grid_start = grid_idx;
grid_end = grid_idx;
}
else
{
if (grid_idx < grid_start)
grid_start = grid_idx;
if (grid_idx > grid_end)
grid_end = grid_idx;
}
if (grid_idx_last != -1 && (Math.Abs(grid_idx_last - grid_idx) > 1))
{
//步子太大,需要插值
if (grid_idx_last < grid_idx)
{
for (int i = grid_idx_last; i < grid_idx; i++)
{
toGrid_step1(gridsOfAd1_sum, gridsOfAd1_cnt, gridLen, i, ad1);
toGrid_step1(gridsOfAd2_sum, gridsOfAd2_cnt, gridLen, i, ad2);
}
}
else
{
for (int i = grid_idx_last; i > grid_idx; i--)
{
toGrid_step1(gridsOfAd1_sum, gridsOfAd1_cnt, gridLen, i, ad1);
toGrid_step1(gridsOfAd2_sum, gridsOfAd2_cnt, gridLen, i, ad2);
}
}
}
toGrid_step1(gridsOfAd1_sum, gridsOfAd1_cnt, gridLen, grid_idx, ad1);
toGrid_step1(gridsOfAd2_sum, gridsOfAd2_cnt, gridLen, grid_idx, ad2);
grid_idx_last = grid_idx;
}
for (int i = 0; i < gridLen; i++)
{
if (gridsOfAd1_cnt[i] == 0)
gridsOfAd1_sum[i] = Misc.MyBase.NULL_VALUE;
else
gridsOfAd1_sum[i] = (int)(gridsOfAd1_sum[i] / gridsOfAd1_cnt[i]);
if (gridsOfAd2_cnt[i] == 0)
gridsOfAd2_sum[i] = Misc.MyBase.NULL_VALUE;
else
gridsOfAd2_sum[i] = (int)(gridsOfAd2_sum[i] / gridsOfAd2_cnt[i]);
}
if (isMiniGrid)
{
//只导出 grid_start~grid_end 数据
if (Misc.MyBase.ISVALIDATA(grid_start))
{
gridsOfAd1 = gridsOfAd1_sum.Skip(grid_start).Take(grid_end - grid_start + 1).ToArray();
gridsOfAd2 = gridsOfAd2_sum.Skip(grid_start).Take(grid_end - grid_start + 1).ToArray();
return;
}
else {
//一个数据都没有
gridsOfAd1 = null;
gridsOfAd2 = null;
return;
}
}
else
{
gridsOfAd1 = gridsOfAd1_sum;
gridsOfAd2 = gridsOfAd2_sum;
}
}
static void toGrid_step1(int[] grids_sum, int[] grids_cnt, int gridLen, int grid_idx, int ad)
{
if ((grid_idx < 0) || (grid_idx >= gridLen))
{
return;
}
if (!Misc.MyBase.ISVALIDATA(ad))
return;
grids_cnt[grid_idx]++;
grids_sum[grid_idx] += ad;
}
///
/// data0s 的 输入口=false 序号范围
/// data1s 的 输入口=true 序号范围
///
/// 数据池
/// 数据池最后一个数据时间
/// 输入口序号
/// 开始时间
/// 结束时间
/// 输入口=false 序号范围<
/// 输入口=true 序号范围
public static void GetIStatusRange(
List dataPool,
DateTime newestTime,
int istatusIndex,
DateTime beginTime, DateTime endTime,
out List data0s, out List data1s)
{
data0s = new List();
data1s = new List();
Range range = new Range();
bool is1 = false;
int begin_idx = dataPool.Count() - (int)((newestTime - beginTime).TotalMilliseconds);
if (begin_idx < 0)
begin_idx = 0;
if (begin_idx > dataPool.Count() - 1)
begin_idx = dataPool.Count() - 1;
int end_idx = dataPool.Count() - (int)((newestTime - endTime).TotalMilliseconds);
if (end_idx < 0)
end_idx = 0;
if (end_idx > dataPool.Count() - 1)
end_idx = dataPool.Count() - 1;
for (int i = begin_idx; i <= end_idx; i++)
{
var data = dataPool[i];
bool istatus_bit = Misc.MyBase.CHECKBIT(data.istatus, istatusIndex);
if (!range.IsValid)
{
//第1次
range.Begin = i;
range.End = i;
is1 = istatus_bit;
if (is1)
{
data1s.Add(range);
}
else
{
data0s.Add(range);
}
}
else
{
if (istatus_bit == is1)
{
//信号一样
range.End = i;
}
else {
//信号改变了
range = new Range();
range.Begin = i;
range.End = i;
is1 = istatus_bit;
if (is1)
{
data1s.Add(range);
}
else
{
data0s.Add(range);
}
}
}
}
}
///
/// data0s 的 输入口=false 序号范围
/// data1s 的 输入口=true 序号范围
///
/// 数据池
/// 数据池最后一个数据时间
/// 输入口序号
/// 开始时间
/// 结束时间
/// 输入口=false 序号范围<
/// 输入口=true 序号范围
public static void GetIStatusRange(
List dataPool,
int istatusIndex,
int dataLen,
out List data0s, out List data1s)
{
data0s = new List();
data1s = new List();
Range range = new Range();
bool is1 = false;
int begin_idx = dataPool.Count() - dataLen;
if (begin_idx < 0)
begin_idx = 0;
if (begin_idx > dataPool.Count() - 1)
begin_idx = dataPool.Count() - 1;
int end_idx = dataPool.Count() - 1;
for (int i = begin_idx; i <= end_idx; i++)
{
var data = dataPool[i];
bool istatus_bit = Misc.MyBase.CHECKBIT(data.istatus, istatusIndex);
if (!range.IsValid)
{
//第1次
range.Begin = i;
range.End = i;
is1 = istatus_bit;
if (is1)
{
data1s.Add(range);
}
else
{
data0s.Add(range);
}
}
else
{
if (istatus_bit == is1)
{
//信号一样
range.End = i;
}
else
{
//信号改变了
range = new Range();
range.Begin = i;
range.End = i;
is1 = istatus_bit;
if (is1)
{
data1s.Add(range);
}
else
{
data0s.Add(range);
}
}
}
}
}
}
public class Range_DateTime
{
public DateTime Begin;
public DateTime End;
}
}