Commit 248af6bc authored by 潘栩锋's avatar 潘栩锋 🚴

GridAdv 调试完成

parent d9662735
......@@ -18,7 +18,7 @@ namespace FlyADBase
/// <summary>
/// 通过脉冲计算速度,不使用AD盒的输出
/// </summary>
public bool IsCalSpeed { get; set; } = true;
public bool IsCalSpeed { get; set; }// = true;
private int gridsmooth = 0;
/// <summary>
......@@ -97,7 +97,7 @@ namespace FlyADBase
Speed = speed;
Speed2 = speed2;
}
}, TimeSpan.FromSeconds(0.5));
}, TimeSpan.FromSeconds(1));
}
private void FlyAD7_PropertyChanged1(object sender, System.ComponentModel.PropertyChangedEventArgs e)
......@@ -440,14 +440,16 @@ namespace FlyADBase
#endregion
}
/// <summary>
/// 转为 grid 数据
/// </summary>
/// <param name="gridAdvUnits"></param>
/// <param name="dat"></param>
public void ToGrid(IEnumerable<GridAdvUnit> gridAdvUnits, out int[] dat)
/// <param name="adLag">测试功能,让ad值滞后</param>
public void ToGrid(IEnumerable<GridAdvUnit> gridAdvUnits, out int[] dat, int adLag=0)
{
dat = mTimeGridAdvHelper.ToGrid(gridAdvUnits, PosOfGrid, SGrid.GRID_MAX_SIZE);
dat = mTimeGridAdvHelper.ToGrid(gridAdvUnits, PosOfGrid, SGrid.GRID_MAX_SIZE, adLag);
}
class PushGridInfo
{
......
......@@ -124,12 +124,14 @@ namespace FlyADBase
/// <param name="dat">grid 数据</param>
void GetGrid(DIRECTION direction, out int[] dat);
/// <summary>
/// 转为 grid 数据
/// </summary>
/// <param name="gridAdvUnits"></param>
/// <param name="dat"></param>
void ToGrid(IEnumerable<GridAdvUnit> gridAdvUnits, out int[] dat);
/// <param name="adLag">测试功能 ad值滞后</param>
void ToGrid(IEnumerable<GridAdvUnit> gridAdvUnits, out int[] dat,int adLag);
/// <summary>
/// 动作完成
/// </summary>
......
......@@ -30,7 +30,19 @@ namespace FlyADBase
/// </summary>
RList<DataTimeUnit2> IStatusPool = new RList<DataTimeUnit2>(60000);
/// <summary>
/// 上一次查找istatus的序号
/// </summary>
int istatus_start_idx = -1;
/// <summary>
/// 上一次查找pos的序号
/// </summary>
int pos_start_idx = -1;
void ResetSearch()
{
istatus_start_idx = -1;
pos_start_idx = -1;
}
/// <summary>
///
/// </summary>
......@@ -137,7 +149,7 @@ namespace FlyADBase
ADPool.Clear();
IStatusPool.Clear();
istatus_start_idx = -1;
ResetSearch();
}
/// <summary>
......@@ -151,18 +163,7 @@ namespace FlyADBase
bool GetIdxFromPosPool(int start_pos, DateTime endtime, out int start_idx, out int end_idx)
{
start_idx = -1;
end_idx = -1;
for (int i = 0; i < PosPool.Count(); i++)
{
int idx = PosPool.Count() - 1 - i;
if (PosPool[idx].dt <= endtime)
{
//从这个点开始找
end_idx = idx;
break;
}
}
end_idx = searchIndex(PosPool, endtime, -1);
if (end_idx == -1)
{
//endtime 发生在过去很久以前
......@@ -217,92 +218,41 @@ namespace FlyADBase
}
/// <summary>
/// 上一次查找istatus的序号
/// </summary>
int istatus_start_idx = -1;
/// <summary>
/// 根据时间点,获取输入口状态
/// </summary>
/// <param name="time"></param>
/// <param name="dt"></param>
/// <returns></returns>
UInt16 GetIStatus(DateTime time)
{
int start_idx = istatus_start_idx;
if (start_idx >= 0 && start_idx < IStatusPool.Count())
{
for (int i = start_idx; i >= 0; i--)
{
int idx = i;
if (time >= IStatusPool[idx].dt)
{
if (idx == start_idx)//有可能start_idx 位置 本来就在前面,看看后面再决定
UInt16 GetIStatus(DateTime dt)
{
for (int j = start_idx + 1; j < IStatusPool.Count(); j++)
{
idx = j;
if (time < IStatusPool[idx].dt)
{
//找到了
istatus_start_idx = idx - 1;
return (UInt16)IStatusPool[istatus_start_idx].istatus;
}
}
//找到最后
istatus_start_idx = idx;
return (UInt16)IStatusPool[istatus_start_idx].istatus;
}
//找到
istatus_start_idx = idx;
return (UInt16)IStatusPool[istatus_start_idx].istatus;
}
}
}
else
{
//没有以前的记录
//从列表的后面向前查找
for (int i = 0; i < IStatusPool.Count(); i++)
{
int idx = IStatusPool.Count() - 1 - i;
if (time >= IStatusPool[idx].dt)
{
//找到
istatus_start_idx = idx;
return (UInt16)IStatusPool[istatus_start_idx].istatus;
}
}
}
int index = searchIndex(IStatusPool, dt, istatus_start_idx);
istatus_start_idx = index;
//在前面发生的!!!
if (IStatusPool.Count() > 0)
{
istatus_start_idx = 0;
return (UInt16)IStatusPool[istatus_start_idx].istatus;
}
if (index < 0)
return 0xffff;
else
{
//异常,一个数据都没有
istatus_start_idx = -1;
return (UInt16)0xff;
}
return (UInt16)IStatusPool[index].istatus;
}
/// <summary>
/// 根据时间点,获取输入口状态
/// </summary>
/// <param name="time"></param>
/// <param name="istatus_idx">用于加快查找速度</param>
/// <param name="dt"></param>
/// <param name="index"></param>
/// <returns></returns>
UInt16 GetIStatus(DateTime time, out int istatus_idx)
UInt16 GetIStatus(DateTime dt, out int index)
{
UInt16 istatus = GetIStatus(time);
istatus_idx = istatus_start_idx;
return istatus;
index = searchIndex(IStatusPool, dt, istatus_start_idx);
istatus_start_idx = index;
if (index < 0)
return 0xffff;
else
return (UInt16)IStatusPool[index].istatus;
}
/// <summary>
/// 以 [idx,idx+1] 的比例, 给出 time 计算 pos
/// </summary>
......@@ -320,7 +270,7 @@ namespace FlyADBase
if (idx < 0)
idx = 0;
if (idx >= PosPool.Count())
if (idx >= PosPool.Count()-1)
idx = PosPool.Count() - 2;
double d_pos = PosPool[idx].data - PosPool[idx + 1].data;
......@@ -331,34 +281,116 @@ namespace FlyADBase
return (int)(p + PosPool[idx + 1].data);
}
enum SearchState
{
ContinueLastTime,
Back,
ForwToCheck
}
/// <summary>
/// 获取时间对应的 位置点
/// 找到 时间 dt 落在 [idx,idx+1] 之间的 idx,
/// 返回 -1,证明dt 在列表在前面, 或列表数据量为=0,
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="list">列表</param>
/// <param name="dt"></param>
/// <param name="searchStartIdx">从列表的某个位置开始向前查找</param>
/// <returns></returns>
int GetPos(DateTime dt)
int searchIndex<T>(List<T> list, DateTime dt, int searchStartIdx ) where T: IDataTimeUnit
{
int index = -1;
for (int i = 0; i < PosPool.Count(); i++)//从后面开始查找
if (list.Count() == 0)
return -1;
int max_index = list.Count() - 1;
int index = searchStartIdx;
SearchState state = SearchState.ContinueLastTime;
if ((index < 0) || (index >= max_index))//重新开始
{
int idx = PosPool.Count() - 1 - i;
if (PosPool[idx].dt <= dt)
index = max_index;
state = SearchState.Back;
}
//从上次位置开始查找
while (true)
{
DateTime time = list[index].dt;
switch (state)
{
//找到了
index = idx;
case SearchState.ContinueLastTime:
{
if (time <= dt)
{
//可能找到了
//再向前看看
state = SearchState.ForwToCheck;
index++;
}
else
{
state = SearchState.Back;
index--;
}
}
break;
case SearchState.ForwToCheck:
{
if (index > max_index)
{
index--;
//最后一个就是了
goto _finish;
}
if (time > dt)
{
//就是之前那个
index--;
goto _finish;
}
if (index == PosPool.Count() - 1)
else
{
index = index - 1;
//找过头了
index++;
}
else if (index == -1)
}
break;
case SearchState.Back:
{
index = 0;
if (time <= dt)
{
//就是它
goto _finish;
}
index--;
}
break;
default:
{
throw new Exception("程序出错, 不可以有第4种情况");
}
break;
}
}
_finish:
return index;
}
/// <summary>
/// 获取时间对应的 位置点
/// </summary>
/// <param name="dt"></param>
/// <returns></returns>
int GetPos(DateTime dt)
{
//找到 时间落在 [idx,idx+1] 之间的
int index = searchIndex(PosPool, dt, pos_start_idx);
pos_start_idx = index;
if (index < 0)
index = 0;
return GetPos(dt, index);
}
......@@ -414,6 +446,7 @@ namespace FlyADBase
public List<GridAdvUnit> GetTimeGridAdv(DateTime end_dt, DIRECTION direction, int grid_start, int grid_len, int posOfGrid)
{
ResetSearch();
List<GridAdvUnit> result = new List<GridAdvUnit>();
int grid_mid = grid_start + grid_len / 2;
int grid_begin = (direction == DIRECTION.FORWARD) ? grid_start : grid_start + grid_len - 1;
......@@ -507,7 +540,19 @@ namespace FlyADBase
result.Reverse();
return result;
}
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;
}
/// <summary>
/// 把 TimeGridAdv 转为 Grid
/// </summary>
......@@ -519,20 +564,34 @@ namespace FlyADBase
{
int[] grids_sum = new int[gridLen];
int[] grids_cnt = new int[gridLen];
int grid_idx_last = -1;
//grid_idx 应该要连续变化,不是,那就插值
foreach (var gridAdvUnit in gridAdvUnits)
{
int grid_idx = gridAdvUnit.pos / posOfGrid;
if ((grid_idx < 0) || (grid_idx >= gridLen))
if (grid_idx_last != -1 && (Math.Abs(grid_idx_last - grid_idx)>1))
{
continue;
//步子太大,需要插值
if (grid_idx_last < grid_idx)
{
for (int i = grid_idx_last; i < grid_idx; i++)
{
toGrid_step1(grids_sum, grids_cnt, gridLen, i, gridAdvUnit.ad);
}
}
else
{
for (int i = grid_idx_last; i > grid_idx; i--)
{
toGrid_step1(grids_sum, grids_cnt, gridLen, i, gridAdvUnit.ad);
}
if (!Misc.MyBase.ISVALIDATA(gridAdvUnit.ad))
continue;
grids_cnt[grid_idx]++;
grids_sum[grid_idx] += gridAdvUnit.ad;
}
}
toGrid_step1(grids_sum, grids_cnt, gridLen, grid_idx, gridAdvUnit.ad);
grid_idx_last = grid_idx;
}
for(int i=0;i< gridLen;i++)
{
if (grids_cnt[i] == 0)
......@@ -544,6 +603,65 @@ namespace FlyADBase
}
/// <summary>
/// 把 TimeGridAdv 转为 Grid, adLag, 把AD值滞后 n * 1.28ms
/// </summary>
/// <param name="gridAdvUnits"></param>
/// <param name="posOfGrid"></param>
/// <param name="gridLen"></param>
/// <param name="adLag"></param>
/// <returns></returns>
public int[] ToGrid(IEnumerable<GridAdvUnit> gridAdvUnits, int posOfGrid, int gridLen, int adLag)
{
int[] grids_sum = new int[gridLen];
int[] grids_cnt = new int[gridLen];
int grid_idx_last = -1;
//grid_idx 应该要连续变化,不是,那就插值
for (int j = 0; j < gridAdvUnits.Count(); j++)
{
var gridAdvUnit = gridAdvUnits.ElementAt(j);
int j_lag = j - adLag;
if (j_lag < 0)
j_lag = 0;
else if (j_lag > gridAdvUnits.Count() - 1)
j_lag = gridAdvUnits.Count() - 1;
var gridAdvUnit_lag = gridAdvUnits.ElementAt(j_lag);
int ad = gridAdvUnit_lag.ad;
int grid_idx = gridAdvUnit.pos / posOfGrid;
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(grids_sum, grids_cnt, gridLen, i, ad);
}
}
else
{
for (int i = grid_idx_last; i > grid_idx; i--)
{
toGrid_step1(grids_sum, grids_cnt, gridLen, i, ad);
}
}
}
toGrid_step1(grids_sum, grids_cnt, gridLen, grid_idx, ad);
grid_idx_last = grid_idx;
}
for (int i = 0; i < gridLen; i++)
{
if (grids_cnt[i] == 0)
grids_sum[i] = Misc.MyBase.NULL_VALUE;
else
grids_sum[i] = (int)(grids_sum[i] / grids_cnt[i]);
}
return grids_sum;
}
#region 子功能,grid istatus 变化
......@@ -611,6 +729,7 @@ namespace FlyADBase
}
}
/// <summary>
/// 触发GridIStatusEvent事件
/// </summary>
......@@ -619,6 +738,7 @@ namespace FlyADBase
/// <param name="pos_len"></param>
/// <param name="marker"></param>
/// <param name="dt"></param>
/// <param name="sender"></param>
public void NotifyGridIStatusEvent(DIRECTION direction, int pos_start, int pos_len, int marker, DateTime dt, object sender)
{
if (mGridIStatusEventList.Count() <= 0)
......@@ -681,10 +801,7 @@ namespace FlyADBase
{
data0 = new List<Range>();
data1 = new List<Range>();
istatus_start_idx = -1;
int istatus_idx;
UInt16 istatus = GetIStatus(start_dt, out istatus_idx);
UInt16 istatus = GetIStatus(start_dt, out int istatus_idx);
if (istatus_idx == -1)//异常,列表没有数据
{
......@@ -769,20 +886,24 @@ namespace FlyADBase
}
#endregion
}
struct DataTimeUnit
interface IDataTimeUnit
{
DateTime dt { get; set; }
}
struct DataTimeUnit: IDataTimeUnit
{
public int data;
public DateTime dt;
public DateTime dt { get; set; }
public override string ToString()
{
return data.ToString() + " |" + dt.Ticks.ToString();
}
}
struct DataTimeUnit2
struct DataTimeUnit2: IDataTimeUnit
{
public UInt16 istatus;
public int pos;
public DateTime dt;
public DateTime dt { get; set; }
public override string ToString()
{
return pos.ToString() + "(" + istatus.ToString("X2") + ") |" + dt.ToString();
......
......@@ -12,6 +12,7 @@ namespace Flyad7_WPF
public class DebugAppParam : INotifyPropertyChanged
{
public string EPStr { get; set; } = "192.168.251.10:20006";
public bool HasTimeGrid { get; set; }
......@@ -30,12 +31,12 @@ namespace Flyad7_WPF
public int FB_Pos2 { get; set; } = 3000;
public UInt32 Velocity;
public UInt32 SVelocity;
public UInt32 ATime;
public UInt32 DTime;
public UInt32 HVelocity1;
public UInt32 HVelocity2;
public UInt32 Velocity { get; set; }
public UInt32 SVelocity { get; set; }
public UInt32 ATime { get; set; }
public UInt32 DTime { get; set; }
public UInt32 HVelocity1 { get; set; }
public UInt32 HVelocity2 { get; set; }
public int PosLen;
public int ADLag { get; set; }
......@@ -46,52 +47,16 @@ namespace Flyad7_WPF
public void Save()
{
try
{
DebugAppParamJsonDB param = new DebugAppParamJsonDB()
{
EPStr = EPStr,
HasTimeGrid = HasTimeGrid,
HasGrid = HasGrid,
HasGridAdv = HasGridAdv,
HasCRC = HasCRC,
FB_Pos1 = FB_Pos1,
FB_Pos2 = FB_Pos2
};
File.WriteAllText(file_path, JsonConvert.SerializeObject(param, Formatting.Indented));
}
catch
{
//异常,没有json 编码失败
}
Misc.SaveToXmlHepler.Save(file_path, this);
}
string file_path = "param.json";
string file_path = "param.xml";
public void Load()
{
try
{
if (File.Exists(file_path))
{
string json = File.ReadAllText(file_path);
var param = JsonConvert.DeserializeObject<DebugAppParamJsonDB>(json);
EPStr = param.EPStr;
HasTimeGrid = param.HasTimeGrid;
HasGrid = param.HasGrid;
HasGridAdv = param.HasGridAdv;
HasCRC = param.HasCRC;
FB_Pos1 = param.FB_Pos1;
FB_Pos2 = param.FB_Pos2;
}
}
catch
{
//异常,没有json 解码失败
}
Misc.SaveToXmlHepler.Load(file_path, this);
}
}
public class DebugAppParamJsonDB
{
......
......@@ -173,6 +173,9 @@
<Resource Include="chip_128px_1093586_easyicon.net.ico" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="AutoMapper">
<Version>9.0.0</Version>
</PackageReference>
<PackageReference Include="Costura.Fody">
<Version>3.3.3</Version>
</PackageReference>
......
......@@ -326,14 +326,19 @@
<TabControl x:Name="tabControl" >
<TabItem Header="TimeGrid">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="141*"/>
<ColumnDefinition Width="524*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition />
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal" Name="stackpanel_graph">
<StackPanel Orientation="Horizontal" Name="stackpanel_graph" Grid.ColumnSpan="2">
<CheckBox Content="接收TimeGrid" IsChecked="{Binding DataContext.HasTimeGrid,ElementName=grid_param}" VerticalAlignment="Center" Margin="3" />
</StackPanel>
<WindowsFormsHost Grid.Row="1">
<WindowsFormsHost Grid.Row="1" Grid.ColumnSpan="2">
<Chr:Chart x:Name="chart2" />
</WindowsFormsHost>
</Grid>
......@@ -366,10 +371,30 @@
<RowDefinition Height="auto" />
<RowDefinition />
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal" Name="stackpanel_graph_gridadv">
<StackPanel Name="stackpanel_graph_gridadv">
<StackPanel Orientation="Horizontal" >
<CheckBox Content="接收GridAdv" IsChecked="{Binding DataContext.HasGridAdv,ElementName=grid_param}" VerticalAlignment="Center" Margin="3" />
<Button Padding="20,5" Margin="3" Content="保存GridAdv" Click="btnSaveGridAdvClick" />
<Button Padding="20,5" Margin="3" Content="读取GridAdv" Click="btnLoadGridAdvClick" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<Button Padding="20,5" Margin="3" Content="计算滞后" Click="btnCalAdLagClick" />
<TextBlock Margin="10,0">
当前相关性=<Run Text="{Binding CurrR, StringFormat={}{0:F4}, Mode=OneWay}"/>
</TextBlock>
<StackPanel>
<TextBlock Margin="10,0">
计算进度 AdLag=<Run Text="{Binding ProgressOfAdLag, Mode=OneWay}"/> | R=<Run Text="{Binding ProgressOfR, StringFormat={}{0:F4}, Mode=OneWay}"/>
</TextBlock>
<TextBlock Margin="10,0">
结果 AdLag=<Run Text="{Binding BestAdLag, Mode=OneWay}"/> | R=<Run Text="{Binding BestR, StringFormat={}{0:F4}, Mode=OneWay}"/>
</TextBlock>
</StackPanel>
</StackPanel>
</StackPanel>
<WindowsFormsHost Grid.Row="1">
<Chr:Chart x:Name="chart3" />
</WindowsFormsHost>
......
......@@ -20,13 +20,16 @@ using Misc;
using System.Threading;
using System.Windows.Threading;
using System.Windows.Forms.DataVisualization.Charting;
using Microsoft.Win32;
using System.IO;
using System.Threading.Tasks;
namespace Flyad7_WPF
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
public partial class MainWindow : Window,INotifyPropertyChanged
{
FlyAD7 flyad;
DebugAppParam param;
......@@ -34,6 +37,7 @@ namespace Flyad7_WPF
FlyADClientUI flyad_clientui;
AutoSync mAutoSync;
int timeGridAdvIndex = 0;
List<IEnumerable<GridAdvUnit>> gridAdvUnits = new List<IEnumerable<GridAdvUnit>>();
public MainWindow()
{
InitializeComponent();
......@@ -56,6 +60,7 @@ namespace Flyad7_WPF
Misc.BindingOperations.SetBinding(param, "FB_Pos2", autofb, "FB_Pos2", Misc.BindingOperations.BindingMode.TwoWay);
this.DataContext = flyad;
this.stackpanel_graph_gridadv.DataContext = this;
this.grid_param.DataContext = param;
this.groupBox_fb.DataContext = autofb;
this.groupBox_adpos.DataContext = flyad_clientui;
......@@ -242,6 +247,12 @@ namespace Flyad7_WPF
chartArea1.BorderDashStyle = System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.Solid;
chartArea1.Name = "Default";
chartArea1.ShadowColor = System.Drawing.Color.Transparent;
chartArea1.CursorX.IsUserEnabled = true;
chartArea1.CursorX.IsUserSelectionEnabled = true;
chartArea1.CursorX.SelectionColor = System.Drawing.SystemColors.Highlight;
chartArea1.CursorY.IsUserEnabled = true;
chartArea1.CursorY.IsUserSelectionEnabled = true;
chartArea1.CursorY.SelectionColor = System.Drawing.SystemColors.Highlight;
//对数坐标
//chartArea1.AxisY.IsLogarithmic = true;
//chartArea1.AxisY.LogarithmBase = Math.E;
......@@ -327,34 +338,6 @@ namespace Flyad7_WPF
}
private void flyad_TimeGridAdvEvent(object sender, TimeGridAdvEventArgs e)
{
if (!param.HasGridAdv)
return;
flyad.ToGrid(e.Data, out int[] datas);
//画图
timeGridAdvIndex++;
if (timeGridAdvIndex >= chart3.Series.Count())
timeGridAdvIndex = 0;
System.Windows.Forms.DataVisualization.Charting.Series series = chart3.Series[timeGridAdvIndex];
series.Points.Clear();
int gridLen = flyad.PosLen / flyad.PosOfGrid;
for (int i = 0; i < datas.Length; i++)
{
int pos = i * flyad.PosOfGrid;
int ad = datas[i];
series.Points.AddXY(pos, ad);
if (ad == Misc.MyBase.NULL_VALUE)
series.Points[i].IsEmpty = true;
}
chart1.ChartAreas[0].AxisX.Minimum = 0;
chart1.ChartAreas[0].AxisX.Maximum = flyad.PosLen;
}
private void button_cleargrid_Click(object sender, RoutedEventArgs e)
{
......@@ -418,7 +401,208 @@ namespace Flyad7_WPF
GetGrid(Misc.DIRECTION.BACKWARD);
}
#endregion
#region timeGridAdv
private async void flyad_TimeGridAdvEvent(object sender, TimeGridAdvEventArgs e)
{
if (!param.HasGridAdv)
return;
if (gridAdvUnits == null)
gridAdvUnits = new List<IEnumerable<GridAdvUnit>>();
gridAdvUnits.Add(e.Data);
await Task.Factory.StartNew(() =>
{
//画图
DrawGridAdv(gridAdvUnits.Last());
while (gridAdvUnits.Count > chart3.Series.Count())
gridAdvUnits.RemoveAt(0);
if (gridAdvUnits.Count() >= 2)
{
CurrR = CalGridAdvR(gridAdvUnits[gridAdvUnits.Count() - 1], gridAdvUnits[gridAdvUnits.Count() - 2], 0);
}
});
}
void DrawGridAdv(IEnumerable<GridAdvUnit> units, int adLag=0)
{
flyad.ToGrid(units, out int[] datas, adLag);
//画图
timeGridAdvIndex++;
if (timeGridAdvIndex >= chart3.Series.Count())
timeGridAdvIndex = 0;
this.Dispatcher.Invoke(() =>
{
System.Windows.Forms.DataVisualization.Charting.Series series = chart3.Series[timeGridAdvIndex];
series.Points.Clear();
int gridLen = flyad.PosLen / flyad.PosOfGrid;
for (int i = 0; i < datas.Length; i++)
{
int pos = i * flyad.PosOfGrid;
int ad = datas[i];
series.Points.AddXY(pos, ad);
if (ad == Misc.MyBase.NULL_VALUE)
series.Points[i].IsEmpty = true;
}
chart1.ChartAreas[0].AxisX.Minimum = 0;
chart1.ChartAreas[0].AxisX.Maximum = flyad.PosLen;
});
}
//计算相关性
public int BestAdLag { get; private set; }
public double BestR { get; private set; }
public double CurrR { get; private set; }
public double ProgressOfAdLag { get; private set; }
public double ProgressOfR { get; private set; }
double CalGridAdvR(IEnumerable<GridAdvUnit> units1, IEnumerable<GridAdvUnit> units2, int adLag)
{
flyad.ToGrid(units1, out int[] datas1, adLag);
flyad.ToGrid(units2, out int[] datas2, adLag);
return Misc.MyMath.Correl(datas1, datas2);
}
void CalAdLag(IEnumerable<GridAdvUnit> units1, IEnumerable<GridAdvUnit> units2, int adLag, int range, double targetR, out int bestAdLag, out double bestR)
{
int step = range / 5;
if (step < 0)
step = 1;
List<AdLagAndR> rList = new List<AdLagAndR>();
for (int i = 0; i < range; i+=step)
{
int _adLag = adLag - i;
double _r = CalGridAdvR(units1, units2, _adLag);
rList.Add(new AdLagAndR() { AdLag = _adLag, R = _r });
ProgressOfAdLag = _adLag;
ProgressOfR = _r;
}
for (int i = step; i < range; i += step)
{
int _adLag = adLag + i;
double _r = CalGridAdvR(units1, units2, _adLag);
rList.Add(new AdLagAndR() { AdLag = _adLag, R = _r });
ProgressOfAdLag = _adLag;
ProgressOfR = _r;
}
double maxR = rList.Max(lr => lr.R);
adLag = rList.Find(_lr => _lr.R == maxR).AdLag;
if (step == 1)
{
//已经是最小查找步进
bestAdLag = adLag;
bestR = maxR;
return;
}
if (maxR >= targetR)
{
//找到了
bestAdLag = adLag;
bestR = maxR;
return;
}
//缩小范围,继续找
range = step * 2;
CalAdLag(units1, units2, adLag, range, targetR, out bestAdLag, out bestR);
}
class AdLagAndR
{
public int AdLag;
public double R;
}
private void btnSaveGridAdvClick(object sender, RoutedEventArgs e)
{
string strDesktopPath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
string path = System.IO.Path.Combine(strDesktopPath, $"{DateTime.Now.ToString("yyyyMMdd_HHmmss")}.json");
string json = Newtonsoft.Json.JsonConvert.SerializeObject(gridAdvUnits);
File.WriteAllText(path, json);
MessageBox.Show($"成功保存到 {path}");
}
private async void btnLoadGridAdvClick(object sender, RoutedEventArgs e)
{
string strDesktopPath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.DefaultExt = ".json";
openFileDialog.Filter = "json文件|*.json";
openFileDialog.InitialDirectory = strDesktopPath;
if (openFileDialog.ShowDialog() != true)
return;
string path = openFileDialog.FileName;
string json = File.ReadAllText(path);
try
{
gridAdvUnits = Newtonsoft.Json.JsonConvert.DeserializeObject<List<IEnumerable<GridAdvUnit>>>(json);
}
catch (Exception ex)
{
MessageBox.Show($"读取失败 {ex}");
return;
}
if (gridAdvUnits == null)
{
gridAdvUnits = new List<IEnumerable<GridAdvUnit>>();
MessageBox.Show($"读取失败 没有数据");
}
else
{
await Task.Factory.StartNew(() =>
{
foreach (var units in gridAdvUnits)
{
DrawGridAdv(units);
}
if (gridAdvUnits.Count > chart3.Series.Count())
gridAdvUnits.RemoveAt(0);
if (gridAdvUnits.Count() >= 2)
{
CurrR = CalGridAdvR(gridAdvUnits[gridAdvUnits.Count() - 1], gridAdvUnits[gridAdvUnits.Count() - 2], 0);
}
});
MessageBox.Show($"读取成功");
}
}
private async void btnCalAdLagClick(object sender, RoutedEventArgs e)
{
if (gridAdvUnits.Count() < 2)
{
MessageBox.Show("数量小于2次");
return;
}
int bestAdLag=0;
double bestR=-1;
await Task.Factory.StartNew(() => {
CalAdLag(gridAdvUnits[gridAdvUnits.Count() - 1], gridAdvUnits[gridAdvUnits.Count() - 2],
0, (int)(1000 / 1.28), 0.99, out bestAdLag, out bestR);
});
BestAdLag = bestAdLag;
BestR = bestR;
await Task.Factory.StartNew(() => {
DrawGridAdv(gridAdvUnits[gridAdvUnits.Count() - 1], BestAdLag);
DrawGridAdv(gridAdvUnits[gridAdvUnits.Count() - 2], BestAdLag);
});
MessageBox.Show($"计算完成 最佳滞后={BestAdLag}");
}
#endregion
int timecnt = 0;
class MaxMin
{
......@@ -437,6 +621,8 @@ namespace Flyad7_WPF
}
List<MaxMin> mMMList = new List<MaxMin>();
public event PropertyChangedEventHandler PropertyChanged;
void flyad_TimeGridEvent(object sender, TimeGridEventArgs e)
{
if (!param.HasTimeGrid)
......@@ -608,6 +794,7 @@ namespace Flyad7_WPF
flyad.RuntoMax();
}
}
}
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