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

GridAdv 调试完成

parent d9662735
...@@ -18,7 +18,7 @@ namespace FlyADBase ...@@ -18,7 +18,7 @@ namespace FlyADBase
/// <summary> /// <summary>
/// 通过脉冲计算速度,不使用AD盒的输出 /// 通过脉冲计算速度,不使用AD盒的输出
/// </summary> /// </summary>
public bool IsCalSpeed { get; set; } = true; public bool IsCalSpeed { get; set; }// = true;
private int gridsmooth = 0; private int gridsmooth = 0;
/// <summary> /// <summary>
...@@ -97,7 +97,7 @@ namespace FlyADBase ...@@ -97,7 +97,7 @@ namespace FlyADBase
Speed = speed; Speed = speed;
Speed2 = speed2; Speed2 = speed2;
} }
}, TimeSpan.FromSeconds(0.5)); }, TimeSpan.FromSeconds(1));
} }
private void FlyAD7_PropertyChanged1(object sender, System.ComponentModel.PropertyChangedEventArgs e) private void FlyAD7_PropertyChanged1(object sender, System.ComponentModel.PropertyChangedEventArgs e)
...@@ -440,14 +440,16 @@ namespace FlyADBase ...@@ -440,14 +440,16 @@ namespace FlyADBase
#endregion #endregion
} }
/// <summary> /// <summary>
/// 转为 grid 数据 /// 转为 grid 数据
/// </summary> /// </summary>
/// <param name="gridAdvUnits"></param> /// <param name="gridAdvUnits"></param>
/// <param name="dat"></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 class PushGridInfo
{ {
......
...@@ -124,12 +124,14 @@ namespace FlyADBase ...@@ -124,12 +124,14 @@ namespace FlyADBase
/// <param name="dat">grid 数据</param> /// <param name="dat">grid 数据</param>
void GetGrid(DIRECTION direction, out int[] dat); void GetGrid(DIRECTION direction, out int[] dat);
/// <summary> /// <summary>
/// 转为 grid 数据 /// 转为 grid 数据
/// </summary> /// </summary>
/// <param name="gridAdvUnits"></param> /// <param name="gridAdvUnits"></param>
/// <param name="dat"></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>
/// 动作完成 /// 动作完成
/// </summary> /// </summary>
......
...@@ -30,7 +30,19 @@ namespace FlyADBase ...@@ -30,7 +30,19 @@ namespace FlyADBase
/// </summary> /// </summary>
RList<DataTimeUnit2> IStatusPool = new RList<DataTimeUnit2>(60000); 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>
/// ///
/// </summary> /// </summary>
...@@ -137,7 +149,7 @@ namespace FlyADBase ...@@ -137,7 +149,7 @@ namespace FlyADBase
ADPool.Clear(); ADPool.Clear();
IStatusPool.Clear(); IStatusPool.Clear();
istatus_start_idx = -1; ResetSearch();
} }
/// <summary> /// <summary>
...@@ -151,18 +163,7 @@ namespace FlyADBase ...@@ -151,18 +163,7 @@ namespace FlyADBase
bool GetIdxFromPosPool(int start_pos, DateTime endtime, out int start_idx, out int end_idx) bool GetIdxFromPosPool(int start_pos, DateTime endtime, out int start_idx, out int end_idx)
{ {
start_idx = -1; start_idx = -1;
end_idx = -1; end_idx = searchIndex(PosPool, endtime, -1);
for (int i = 0; i < PosPool.Count(); i++)
{
int idx = PosPool.Count() - 1 - i;
if (PosPool[idx].dt <= endtime)
{
//从这个点开始找
end_idx = idx;
break;
}
}
if (end_idx == -1) if (end_idx == -1)
{ {
//endtime 发生在过去很久以前 //endtime 发生在过去很久以前
...@@ -217,92 +218,41 @@ namespace FlyADBase ...@@ -217,92 +218,41 @@ namespace FlyADBase
} }
/// <summary>
/// 上一次查找istatus的序号
/// </summary>
int istatus_start_idx = -1;
/// <summary> /// <summary>
/// 根据时间点,获取输入口状态 /// 根据时间点,获取输入口状态
/// </summary> /// </summary>
/// <param name="time"></param> /// <param name="dt"></param>
/// <returns></returns> /// <returns></returns>
UInt16 GetIStatus(DateTime time) UInt16 GetIStatus(DateTime dt)
{
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 位置 本来就在前面,看看后面再决定
{ {
for (int j = start_idx + 1; j < IStatusPool.Count(); j++) int index = searchIndex(IStatusPool, dt, istatus_start_idx);
{ istatus_start_idx = index;
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;
}
}
}
//在前面发生的!!! if (index < 0)
if (IStatusPool.Count() > 0) return 0xffff;
{
istatus_start_idx = 0;
return (UInt16)IStatusPool[istatus_start_idx].istatus;
}
else else
{ return (UInt16)IStatusPool[index].istatus;
//异常,一个数据都没有
istatus_start_idx = -1;
return (UInt16)0xff;
}
} }
/// <summary> /// <summary>
/// 根据时间点,获取输入口状态 /// 根据时间点,获取输入口状态
/// </summary> /// </summary>
/// <param name="time"></param> /// <param name="dt"></param>
/// <param name="istatus_idx">用于加快查找速度</param> /// <param name="index"></param>
/// <returns></returns> /// <returns></returns>
UInt16 GetIStatus(DateTime time, out int istatus_idx) UInt16 GetIStatus(DateTime dt, out int index)
{ {
UInt16 istatus = GetIStatus(time); index = searchIndex(IStatusPool, dt, istatus_start_idx);
istatus_idx = istatus_start_idx; istatus_start_idx = index;
return istatus;
if (index < 0)
return 0xffff;
else
return (UInt16)IStatusPool[index].istatus;
} }
/// <summary> /// <summary>
/// 以 [idx,idx+1] 的比例, 给出 time 计算 pos /// 以 [idx,idx+1] 的比例, 给出 time 计算 pos
/// </summary> /// </summary>
...@@ -320,7 +270,7 @@ namespace FlyADBase ...@@ -320,7 +270,7 @@ namespace FlyADBase
if (idx < 0) if (idx < 0)
idx = 0; idx = 0;
if (idx >= PosPool.Count()) if (idx >= PosPool.Count()-1)
idx = PosPool.Count() - 2; idx = PosPool.Count() - 2;
double d_pos = PosPool[idx].data - PosPool[idx + 1].data; double d_pos = PosPool[idx].data - PosPool[idx + 1].data;
...@@ -331,34 +281,116 @@ namespace FlyADBase ...@@ -331,34 +281,116 @@ namespace FlyADBase
return (int)(p + PosPool[idx + 1].data); return (int)(p + PosPool[idx + 1].data);
} }
enum SearchState
{
ContinueLastTime,
Back,
ForwToCheck
}
/// <summary> /// <summary>
/// 获取时间对应的 位置点 /// 找到 时间 dt 落在 [idx,idx+1] 之间的 idx,
/// 返回 -1,证明dt 在列表在前面, 或列表数据量为=0,
/// </summary> /// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="list">列表</param>
/// <param name="dt"></param> /// <param name="dt"></param>
/// <param name="searchStartIdx">从列表的某个位置开始向前查找</param>
/// <returns></returns> /// <returns></returns>
int GetPos(DateTime dt) int searchIndex<T>(List<T> list, DateTime dt, int searchStartIdx ) where T: IDataTimeUnit
{ {
int index = -1; if (list.Count() == 0)
for (int i = 0; i < PosPool.Count(); i++)//从后面开始查找 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; index = max_index;
if (PosPool[idx].dt <= dt) state = SearchState.Back;
}
//从上次位置开始查找
while (true)
{
DateTime time = list[index].dt;
switch (state)
{ {
//找到了 case SearchState.ContinueLastTime:
index = idx; {
if (time <= dt)
{
//可能找到了
//再向前看看
state = SearchState.ForwToCheck;
index++;
}
else
{
state = SearchState.Back;
index--;
}
}
break; break;
case SearchState.ForwToCheck:
{
if (index > max_index)
{
index--;
//最后一个就是了
goto _finish;
} }
if (time > dt)
{
//就是之前那个
index--;
goto _finish;
} }
else
if (index == PosPool.Count() - 1)
{ {
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); return GetPos(dt, index);
} }
...@@ -414,6 +446,7 @@ namespace FlyADBase ...@@ -414,6 +446,7 @@ namespace FlyADBase
public List<GridAdvUnit> GetTimeGridAdv(DateTime end_dt, DIRECTION direction, int grid_start, int grid_len, int posOfGrid) public List<GridAdvUnit> GetTimeGridAdv(DateTime end_dt, DIRECTION direction, int grid_start, int grid_len, int posOfGrid)
{ {
ResetSearch();
List<GridAdvUnit> result = new List<GridAdvUnit>(); List<GridAdvUnit> result = new List<GridAdvUnit>();
int grid_mid = grid_start + grid_len / 2; int grid_mid = grid_start + grid_len / 2;
int grid_begin = (direction == DIRECTION.FORWARD) ? grid_start : grid_start + grid_len - 1; int grid_begin = (direction == DIRECTION.FORWARD) ? grid_start : grid_start + grid_len - 1;
...@@ -507,7 +540,19 @@ namespace FlyADBase ...@@ -507,7 +540,19 @@ namespace FlyADBase
result.Reverse(); result.Reverse();
return result; 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> /// <summary>
/// 把 TimeGridAdv 转为 Grid /// 把 TimeGridAdv 转为 Grid
/// </summary> /// </summary>
...@@ -519,20 +564,34 @@ namespace FlyADBase ...@@ -519,20 +564,34 @@ namespace FlyADBase
{ {
int[] grids_sum = new int[gridLen]; int[] grids_sum = new int[gridLen];
int[] grids_cnt = new int[gridLen]; int[] grids_cnt = new int[gridLen];
int grid_idx_last = -1;
//grid_idx 应该要连续变化,不是,那就插值
foreach (var gridAdvUnit in gridAdvUnits) foreach (var gridAdvUnit in gridAdvUnits)
{ {
int grid_idx = gridAdvUnit.pos / posOfGrid; 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++) for(int i=0;i< gridLen;i++)
{ {
if (grids_cnt[i] == 0) if (grids_cnt[i] == 0)
...@@ -544,6 +603,65 @@ namespace FlyADBase ...@@ -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 变化 #region 子功能,grid istatus 变化
...@@ -611,6 +729,7 @@ namespace FlyADBase ...@@ -611,6 +729,7 @@ namespace FlyADBase
} }
} }
/// <summary> /// <summary>
/// 触发GridIStatusEvent事件 /// 触发GridIStatusEvent事件
/// </summary> /// </summary>
...@@ -619,6 +738,7 @@ namespace FlyADBase ...@@ -619,6 +738,7 @@ namespace FlyADBase
/// <param name="pos_len"></param> /// <param name="pos_len"></param>
/// <param name="marker"></param> /// <param name="marker"></param>
/// <param name="dt"></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) public void NotifyGridIStatusEvent(DIRECTION direction, int pos_start, int pos_len, int marker, DateTime dt, object sender)
{ {
if (mGridIStatusEventList.Count() <= 0) if (mGridIStatusEventList.Count() <= 0)
...@@ -681,10 +801,7 @@ namespace FlyADBase ...@@ -681,10 +801,7 @@ namespace FlyADBase
{ {
data0 = new List<Range>(); data0 = new List<Range>();
data1 = new List<Range>(); data1 = new List<Range>();
UInt16 istatus = GetIStatus(start_dt, out int istatus_idx);
istatus_start_idx = -1;
int istatus_idx;
UInt16 istatus = GetIStatus(start_dt, out istatus_idx);
if (istatus_idx == -1)//异常,列表没有数据 if (istatus_idx == -1)//异常,列表没有数据
{ {
...@@ -769,20 +886,24 @@ namespace FlyADBase ...@@ -769,20 +886,24 @@ namespace FlyADBase
} }
#endregion #endregion
} }
struct DataTimeUnit interface IDataTimeUnit
{
DateTime dt { get; set; }
}
struct DataTimeUnit: IDataTimeUnit
{ {
public int data; public int data;
public DateTime dt; public DateTime dt { get; set; }
public override string ToString() public override string ToString()
{ {
return data.ToString() + " |" + dt.Ticks.ToString(); return data.ToString() + " |" + dt.Ticks.ToString();
} }
} }
struct DataTimeUnit2 struct DataTimeUnit2: IDataTimeUnit
{ {
public UInt16 istatus; public UInt16 istatus;
public int pos; public int pos;
public DateTime dt; public DateTime dt { get; set; }
public override string ToString() public override string ToString()
{ {
return pos.ToString() + "(" + istatus.ToString("X2") + ") |" + dt.ToString(); return pos.ToString() + "(" + istatus.ToString("X2") + ") |" + dt.ToString();
......
...@@ -12,6 +12,7 @@ namespace Flyad7_WPF ...@@ -12,6 +12,7 @@ namespace Flyad7_WPF
public class DebugAppParam : INotifyPropertyChanged public class DebugAppParam : INotifyPropertyChanged
{ {
public string EPStr { get; set; } = "192.168.251.10:20006"; public string EPStr { get; set; } = "192.168.251.10:20006";
public bool HasTimeGrid { get; set; } public bool HasTimeGrid { get; set; }
...@@ -30,12 +31,12 @@ namespace Flyad7_WPF ...@@ -30,12 +31,12 @@ namespace Flyad7_WPF
public int FB_Pos2 { get; set; } = 3000; public int FB_Pos2 { get; set; } = 3000;
public UInt32 Velocity; public UInt32 Velocity { get; set; }
public UInt32 SVelocity; public UInt32 SVelocity { get; set; }
public UInt32 ATime; public UInt32 ATime { get; set; }
public UInt32 DTime; public UInt32 DTime { get; set; }
public UInt32 HVelocity1; public UInt32 HVelocity1 { get; set; }
public UInt32 HVelocity2; public UInt32 HVelocity2 { get; set; }
public int PosLen; public int PosLen;
public int ADLag { get; set; } public int ADLag { get; set; }
...@@ -46,52 +47,16 @@ namespace Flyad7_WPF ...@@ -46,52 +47,16 @@ namespace Flyad7_WPF
public void Save() public void Save()
{ {
try Misc.SaveToXmlHepler.Save(file_path, this);
{
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 编码失败
}
} }
string file_path = "param.json"; string file_path = "param.xml";
public void Load() public void Load()
{ {
try Misc.SaveToXmlHepler.Load(file_path, this);
{
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 解码失败
}
} }
} }
public class DebugAppParamJsonDB public class DebugAppParamJsonDB
{ {
......
...@@ -173,6 +173,9 @@ ...@@ -173,6 +173,9 @@
<Resource Include="chip_128px_1093586_easyicon.net.ico" /> <Resource Include="chip_128px_1093586_easyicon.net.ico" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="AutoMapper">
<Version>9.0.0</Version>
</PackageReference>
<PackageReference Include="Costura.Fody"> <PackageReference Include="Costura.Fody">
<Version>3.3.3</Version> <Version>3.3.3</Version>
</PackageReference> </PackageReference>
......
...@@ -326,14 +326,19 @@ ...@@ -326,14 +326,19 @@
<TabControl x:Name="tabControl" > <TabControl x:Name="tabControl" >
<TabItem Header="TimeGrid"> <TabItem Header="TimeGrid">
<Grid> <Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="141*"/>
<ColumnDefinition Width="524*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="auto" /> <RowDefinition Height="auto" />
<RowDefinition /> <RowDefinition />
</Grid.RowDefinitions> </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" /> <CheckBox Content="接收TimeGrid" IsChecked="{Binding DataContext.HasTimeGrid,ElementName=grid_param}" VerticalAlignment="Center" Margin="3" />
</StackPanel> </StackPanel>
<WindowsFormsHost Grid.Row="1"> <WindowsFormsHost Grid.Row="1" Grid.ColumnSpan="2">
<Chr:Chart x:Name="chart2" /> <Chr:Chart x:Name="chart2" />
</WindowsFormsHost> </WindowsFormsHost>
</Grid> </Grid>
...@@ -366,10 +371,30 @@ ...@@ -366,10 +371,30 @@
<RowDefinition Height="auto" /> <RowDefinition Height="auto" />
<RowDefinition /> <RowDefinition />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<StackPanel Name="stackpanel_graph_gridadv">
<StackPanel Orientation="Horizontal" Name="stackpanel_graph_gridadv"> <StackPanel Orientation="Horizontal" >
<CheckBox Content="接收GridAdv" IsChecked="{Binding DataContext.HasGridAdv,ElementName=grid_param}" VerticalAlignment="Center" Margin="3" /> <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>
</StackPanel>
<WindowsFormsHost Grid.Row="1"> <WindowsFormsHost Grid.Row="1">
<Chr:Chart x:Name="chart3" /> <Chr:Chart x:Name="chart3" />
</WindowsFormsHost> </WindowsFormsHost>
......
...@@ -20,13 +20,16 @@ using Misc; ...@@ -20,13 +20,16 @@ using Misc;
using System.Threading; using System.Threading;
using System.Windows.Threading; using System.Windows.Threading;
using System.Windows.Forms.DataVisualization.Charting; using System.Windows.Forms.DataVisualization.Charting;
using Microsoft.Win32;
using System.IO;
using System.Threading.Tasks;
namespace Flyad7_WPF namespace Flyad7_WPF
{ {
/// <summary> /// <summary>
/// MainWindow.xaml 的交互逻辑 /// MainWindow.xaml 的交互逻辑
/// </summary> /// </summary>
public partial class MainWindow : Window public partial class MainWindow : Window,INotifyPropertyChanged
{ {
FlyAD7 flyad; FlyAD7 flyad;
DebugAppParam param; DebugAppParam param;
...@@ -34,6 +37,7 @@ namespace Flyad7_WPF ...@@ -34,6 +37,7 @@ namespace Flyad7_WPF
FlyADClientUI flyad_clientui; FlyADClientUI flyad_clientui;
AutoSync mAutoSync; AutoSync mAutoSync;
int timeGridAdvIndex = 0; int timeGridAdvIndex = 0;
List<IEnumerable<GridAdvUnit>> gridAdvUnits = new List<IEnumerable<GridAdvUnit>>();
public MainWindow() public MainWindow()
{ {
InitializeComponent(); InitializeComponent();
...@@ -56,6 +60,7 @@ namespace Flyad7_WPF ...@@ -56,6 +60,7 @@ namespace Flyad7_WPF
Misc.BindingOperations.SetBinding(param, "FB_Pos2", autofb, "FB_Pos2", Misc.BindingOperations.BindingMode.TwoWay); Misc.BindingOperations.SetBinding(param, "FB_Pos2", autofb, "FB_Pos2", Misc.BindingOperations.BindingMode.TwoWay);
this.DataContext = flyad; this.DataContext = flyad;
this.stackpanel_graph_gridadv.DataContext = this;
this.grid_param.DataContext = param; this.grid_param.DataContext = param;
this.groupBox_fb.DataContext = autofb; this.groupBox_fb.DataContext = autofb;
this.groupBox_adpos.DataContext = flyad_clientui; this.groupBox_adpos.DataContext = flyad_clientui;
...@@ -242,6 +247,12 @@ namespace Flyad7_WPF ...@@ -242,6 +247,12 @@ namespace Flyad7_WPF
chartArea1.BorderDashStyle = System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.Solid; chartArea1.BorderDashStyle = System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.Solid;
chartArea1.Name = "Default"; chartArea1.Name = "Default";
chartArea1.ShadowColor = System.Drawing.Color.Transparent; 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.IsLogarithmic = true;
//chartArea1.AxisY.LogarithmBase = Math.E; //chartArea1.AxisY.LogarithmBase = Math.E;
...@@ -327,34 +338,6 @@ namespace Flyad7_WPF ...@@ -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) private void button_cleargrid_Click(object sender, RoutedEventArgs e)
{ {
...@@ -418,7 +401,208 @@ namespace Flyad7_WPF ...@@ -418,7 +401,208 @@ namespace Flyad7_WPF
GetGrid(Misc.DIRECTION.BACKWARD); GetGrid(Misc.DIRECTION.BACKWARD);
} }
#endregion #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; int timecnt = 0;
class MaxMin class MaxMin
{ {
...@@ -437,6 +621,8 @@ namespace Flyad7_WPF ...@@ -437,6 +621,8 @@ namespace Flyad7_WPF
} }
List<MaxMin> mMMList = new List<MaxMin>(); List<MaxMin> mMMList = new List<MaxMin>();
public event PropertyChangedEventHandler PropertyChanged;
void flyad_TimeGridEvent(object sender, TimeGridEventArgs e) void flyad_TimeGridEvent(object sender, TimeGridEventArgs e)
{ {
if (!param.HasTimeGrid) if (!param.HasTimeGrid)
...@@ -608,6 +794,7 @@ namespace Flyad7_WPF ...@@ -608,6 +794,7 @@ namespace Flyad7_WPF
flyad.RuntoMax(); 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