From 1e38390fc61503d27876554a0897f212b75d2b81 Mon Sep 17 00:00:00 2001 From: xu Date: Mon, 3 Feb 2020 23:44:55 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8C=89VID=E6=8E=92=E5=BA=8F=20=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E8=87=AA=E5=8A=A8=E7=BC=96=E5=8F=B7=E9=80=BB=E8=BE=91?= =?UTF-8?q?=20//=E7=9B=AE=E5=89=8D=E6=96=B9=E6=A1=88=E6=98=AF=20=20=20=20?= =?UTF-8?q?=20=20=20=20=20=20=20=20=20=20=20=20=20//1.=E4=BF=9D=E8=AF=81?= =?UTF-8?q?=E6=89=80=E6=9C=89=E6=B2=A1=E6=9C=89=E6=AD=A3=E7=A1=AE=E5=AE=9A?= =?UTF-8?q?=E4=BD=8D=E7=9A=84=E9=A3=9E=E6=9C=BA=E9=83=BD=E4=BA=BA=E5=B7=A5?= =?UTF-8?q?=E7=BC=96=E5=8F=B7=EF=BC=8C=20=20=20=20=20=20=20=20=20=20=20=20?= =?UTF-8?q?=20=20=20=20=20//2.=E7=84=B6=E5=90=8E=E9=80=89=E4=B8=AD2-3?= =?UTF-8?q?=E6=9E=B6=E9=A3=9E=E6=9C=BA=EF=BC=8C1=E5=8F=B7=E9=A3=9E?= =?UTF-8?q?=E6=9C=BA=EF=BC=8C=E7=AC=AC=E4=B8=80=E6=8E=92=E4=BB=BB=E6=84=8F?= =?UTF-8?q?=E9=A3=9E=E6=9C=BA=EF=BC=8C=E7=AC=AC=E4=B8=80=E5=88=97=E4=BB=BB?= =?UTF-8?q?=E6=84=8F=E9=A3=9E=E6=9C=BA=EF=BC=88=E5=B0=BD=E9=87=8F=E8=BF=9C?= =?UTF-8?q?=E7=A6=BB1=E5=8F=B7=E6=9C=BA=EF=BC=89=EF=BC=8C=20=20=20=20=20?= =?UTF-8?q?=20=20=20=20=20=20=20=20=20=20=20=20//3.=E5=BC=80=E5=A7=8B?= =?UTF-8?q?=E8=AE=A1=E7=AE=97=20=E4=BF=AE=E6=94=B93=E9=A3=9E=E6=9C=BA?= =?UTF-8?q?=E4=BF=A1=E6=81=AF=E9=80=9A=E9=81=93=E6=95=B0=E6=8D=AE=E6=94=B9?= =?UTF-8?q?=E4=B8=BA=E7=94=B5=E6=B1=A0=E5=9B=BE=E6=A0=87=EF=BC=8C=E5=B9=B6?= =?UTF-8?q?=E4=B8=94=E4=B8=8D=E8=AE=A9=E6=8B=96=E5=8A=A8=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=20=E6=98=BE=E7=A4=BAVID=E5=8F=98=E6=8D=A2=E9=BB=84=E8=89=B2?= =?UTF-8?q?=EF=BC=8C=E4=BB=A5=E5=89=8D=E6=98=AF=E7=BA=A2=E8=89=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Formation/CopterManager.cs | 55 ++- .../ViewModels/ConfigVirtualIdViewModel.cs | 366 +++++++----------- .../ViewModels/CopterListViewModel.cs | 59 ++- .../Views/ConfigVirtualIdView.xaml | 17 +- .../Views/CopterInfoView.xaml | 210 ++++++++-- .../Views/CopterInfoView.xaml.cs | 6 +- .../Views/CopterListView.xaml | 6 + .../Views/MapView_CopterDrawing.cs | 2 +- 8 files changed, 437 insertions(+), 284 deletions(-) diff --git a/Plane.FormationCreator/Formation/CopterManager.cs b/Plane.FormationCreator/Formation/CopterManager.cs index 4f16573..d6be8cb 100644 --- a/Plane.FormationCreator/Formation/CopterManager.cs +++ b/Plane.FormationCreator/Formation/CopterManager.cs @@ -18,7 +18,7 @@ namespace Plane.FormationCreator.Formation /// 实现排序插入 /// /// - public int AddCopter(ICopter entityObject) + public int AddCopter(ICopter entityObject,bool sortbyid=true) { ////给第三方时候限制数量和时间用 DateTime dateTime2019 = DateTime.Parse("2020-03-01"); @@ -50,14 +50,29 @@ namespace Plane.FormationCreator.Formation bool isInsret = false; for (int i = 0; i < this.Count; i++) { - if ( int.Parse(this[i].Id) > int.Parse(entityObject.Id)) - //if (String.Compare(this[i].Name, entityObject.Name, false) >= 0) + //按ID排序插入 + if (sortbyid) { - InsertItem(i, entityObject); - isInsret = true; - _index= i; - break; - + if (int.Parse(this[i].Id) > int.Parse(entityObject.Id)) + { + InsertItem(i, entityObject); + isInsret = true; + _index = i; + break; + + } + }else + //按VID排序插入 + { + + if (this[i].VirtualId > entityObject.VirtualId) + { + InsertItem(i, entityObject); + isInsret = true; + _index = i; + break; + + } } } if (!isInsret) @@ -88,6 +103,8 @@ namespace Plane.FormationCreator.Formation public List ShowCopter = new List(); + + public CopterCollection Copters { get;} = new CopterCollection(); public ArrayList CopterStatus = new ArrayList(); @@ -149,6 +166,28 @@ namespace Plane.FormationCreator.Formation { _selectCopterAction(copter); } + /// + /// 按VID重新排序飞机 + /// + public void sortbyvid() + { + List tempCopters = new List(); + tempCopters.AddRange(Copters); + Copters.Clear(); + foreach (var copter in tempCopters) + Copters.AddCopter(copter,false); + } + /// + /// 按原始ID重新排序飞机 + /// + public void sortbyid() + { + List tempCopters = new List(); + tempCopters.AddRange(Copters); + Copters.Clear(); + foreach (var copter in tempCopters) + Copters.AddCopter(copter); + } } diff --git a/Plane.FormationCreator/ViewModels/ConfigVirtualIdViewModel.cs b/Plane.FormationCreator/ViewModels/ConfigVirtualIdViewModel.cs index 112b552..3ff025d 100644 --- a/Plane.FormationCreator/ViewModels/ConfigVirtualIdViewModel.cs +++ b/Plane.FormationCreator/ViewModels/ConfigVirtualIdViewModel.cs @@ -10,6 +10,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Input; +using Microsoft.Practices.ServiceLocation; namespace Plane.FormationCreator.ViewModels { @@ -28,12 +29,7 @@ namespace Plane.FormationCreator.ViewModels set { Set(nameof(SingleVirtualId), ref _SingleVirtualId, value); } } - private int _SingleRowCount = 0; - public int SingleRowCount - { - get { return _SingleRowCount; } - set { Set(nameof(SingleRowCount), ref _SingleRowCount, value); } - } + /// /// 清除所有编号 @@ -88,250 +84,160 @@ namespace Plane.FormationCreator.ViewModels { get { - return _AutoLocationNumsCommand ?? (_AutoLocationNumsCommand = new RelayCommand(async () => - { - int colCount = SingleRowCount; - int copterCount = _copterManager.Copters.Count; - - /* - if (copterCount % colCount != 0) - { - Alert.Show($"列数设置错误!"); - return; - } - */ - //列数用户设置colCount - //计算行数rowCount - int rowCount = copterCount / colCount; - //有多的飞机,多一行 - //有整除余,代表最后一行是否没有满 - bool havemode = (copterCount % colCount != 0); - - //if (havemode) - // rowCount++; - int num = 1; - //目前方案是 选中3架飞机,1号飞机,第一排任意飞机,第一列任意飞机(尽量远离1号机) - //用于计算横向和纵向的角度 - if (_copterManager.AcceptingControlCopters.Count() == 3) - { - var copters = _copterManager.AcceptingControlCopters.ToList(); - var firstCopter = copters[0]; - var secondCopter = copters[1]; - var thirdCopter = copters[2]; - // var fourthCopter = copters[3]; - - //第一列角度(1,3) 用于计算每行第一架飞机 - float firstColDirect =(float) GeographyUtils.RadToDeg(firstCopter.CalcDirection2D(thirdCopter)); - //最后列角度(2,4) 用于计算每行最后一架飞机 - float lastColDirect =(float) GeographyUtils.RadToDeg(secondCopter.CalcDirection2D(fourthCopter)); + //目前方案是 + //1.保证所有没有正确定位的飞机都人工编号, + //2.然后选中3架飞机,1号飞机,第一排任意飞机,第一列任意飞机(尽量远离1号机), + //3.开始计算 + return _AutoLocationNumsCommand ?? (_AutoLocationNumsCommand = new RelayCommand( () => + { + //飞机摆放最小间距 + FlightTaskManager _flightTaskManager = ServiceLocator.Current.GetInstance(); + float StepDis_Row = _flightTaskManager.ColumnDistance; //行内间距-列间距 + float StepDis_Col = _flightTaskManager.RowDistance ; //列间距-行间距 + float FindDis =Math.Min(StepDis_Row, StepDis_Col); //查找半径 + if (_copterManager.AcceptingControlCopters.Count() >= 2) + { + var copters = _copterManager.AcceptingControlCopters.ToList(); + var firstCopter = copters[0]; + var secondCopter = copters[1]; + ICopter thirdCopter=null; + if (_copterManager.AcceptingControlCopters.Count()>2) + thirdCopter = copters[2]; - - /* - // //四个角从1号机开始选取(第一排第一个1, 第一排最后2, 最后一排第一个3 , 最后一排最后4) - //第一列角度(1,3) 用于计算每行第一架飞机 - float firstColazimuth = GeographyUtils.RadToDeg(GeographyUtils.CalcDirection2D( - firstCopter.Latitude, firstCopter.Longitude, - thirdCopter.Latitude, thirdCopter.Longitude)); - //最后列角度(2,4) 用于计算每行最后一架飞机 - float lastColazimuth = GeographyUtils.RadToDeg(GeographyUtils.CalcDirection2D( - secondCopter.Latitude, secondCopter.Longitude, - fourthCopter.Latitude, fourthCopter.Longitude)); - - */ - - ICopter destCopter = null; - ICopter sourceCopter = null; - ICopter rowfirstCopter = null; - ICopter rowlastCopter = null; - //行头位置,行尾位置,用ILocation2D不用ICopter是因为可能没有飞机 - ILocation2D rowLocfirst = null; - ILocation2D rowLoclast = null; - - //行查找步长 - int rowfindstep = 1; - //按行循环 - for (int i = 0; i < rowCount; i++) + //行角度(1,2) 用于查找每行的飞机位置 + float RowDirect = (float)GeographyUtils.RadToDeg(firstCopter.CalcDirection2D(secondCopter)); + //列角度(1,3) 用于查找每行第一架飞机 + float ColDirect = 0; + if (thirdCopter!=null) + ColDirect = (float)GeographyUtils.RadToDeg(firstCopter.CalcDirection2D(thirdCopter)); + ICopter FindedCopter = firstCopter; + ICopter LastCopter = firstCopter; + ILocation2D LastRowHewadCopter = firstCopter; + + firstCopter.VirtualId = 1; + while (FindedCopter!=null) { - - //第一行开始结束是(1,2) - if (i == 0) - { - rowfirstCopter = firstCopter; - rowLocfirst = rowfirstCopter; - rowlastCopter = secondCopter; - rowLoclast = rowlastCopter; - } - //最后一行(3,4) - else if (i == rowCount - 1) - { - rowfirstCopter = thirdCopter; - rowLocfirst = rowfirstCopter; - rowlastCopter = fourthCopter; - rowLoclast = rowlastCopter; - } - else - //中间的行找该行的第一架和最后一架飞机 - { - - rowLocfirst=rowLocfirst.CalcLatLngSomeMetersAway2D(firstColDirect, 1.5f); - rowLoclast = rowLoclast.CalcLatLngSomeMetersAway2D(firstColDirect, 1.5f); - - rowLocfirst.CalcLatLngSomeMetersAway2D(firstColDirect, 1.5f); - - - - rowfirstCopter = FindNextCopter(rowLocfirst, firstColDirect, 1); - rowlastCopter = FindNextCopter(rowLoclast, lastColDirect, 1); - } - - if (rowfirstCopter == null) - Message.Show($"无法找到第{i + 1}行的起始飞机"); - if (rowlastCopter == null) - Message.Show($"无法找到第{i + 1}行的结束飞机"); - - rowfindstep = 1; - //每一行按列循环 - for (int j = 0; j < colCount; j++) - { - - //计算每一行方向 - double curRowAzimuth = GeographyUtils.RadToDeg(GeographyUtils.CalcDirection2D( - rowfirstCopter.Latitude, rowfirstCopter.Longitude, - rowlastCopter.Latitude, rowlastCopter.Longitude)); - if (j == 0) - { - destCopter = rowfirstCopter; - sourceCopter = rowfirstCopter; - } - else if (j == colCount - 1) - { - destCopter = rowlastCopter; - } - else - //按行查找飞机 - { - ICopter tempCopter = null; - tempCopter = _copterManager.Copters.FirstOrDefault(o => o.VirtualId == num); - while (tempCopter != null) - { - num++; - j++; - tempCopter = _copterManager.Copters.FirstOrDefault(o => o.VirtualId == num); - } - - //根据当前飞机destCopter,按curRowAzimuth方向按间距1.5米找下一个飞机 - destCopter = FindNextCopter(sourceCopter, curRowAzimuth, rowfindstep); - - if (destCopter == null) - { - Message.Show($"在寻找第{num}号位置时候无法找到对应位置飞机"); - //增加步长继续找 - rowfindstep++; - - - //Alert.Show($"在寻找第{num}号位置时候无法找到对应位置飞机"); - //return; - } - else - { - rowfindstep = 1; - sourceCopter = destCopter; - - - - } - - } - if (destCopter != null) - { - //赋予虚拟ID - destCopter.VirtualId = num; - - Message.Show($"飞机{destCopter.Name} 虚拟ID = {destCopter.VirtualId}"); - } - num++; - } + //按一行找飞机 + FindedCopter = FindNextCopter(LastCopter, RowDirect, StepDis_Row, FindDis); + //一行找不到了 找下一行的前3架飞机 + if ((FindedCopter == null)&&(thirdCopter!=null)) + FindedCopter = FindNextColHeadCopter(out LastRowHewadCopter,LastRowHewadCopter, ColDirect, StepDis_Col, RowDirect, StepDis_Row, 3, FindDis); + //如果找到了分配ID + if (FindedCopter != null) + { + FindedCopter.VirtualId = GetVID(LastCopter.VirtualId); + Message.Show($"分配飞机VID:{FindedCopter.VirtualId}"); + LastCopter = FindedCopter; + } } - } - await Task.Delay(10); + } })); } } - - private ICopter FindNextCopter(ILocation2D startLoc, double azimuth, int findstep) + //根据位置和查找范围查找飞机 + private ICopter FindCopteratLoc(ILocation2D startLoc, float findDis) { ICopter retCopter = null; - bool foundCopter = false; - float stepLength = 0; - double mindis = 500.0f; - - while (!foundCopter) + ICopter foundCopter = null; + double mindis = 1000; + //所有没有虚拟ID的飞机 + List NoVIDCopters = _copterManager.Copters.Where(o => o.VirtualId == 0).ToList(); + //找距离startLoc最近的飞机 + foreach (var copter in NoVIDCopters) { - mindis = 500.0f; - stepLength += 1.5f * findstep; - //计算startCopter按azimuth方向移动stepLength后的位置targetLatLng - Tuple targetLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D( - startLoc.Latitude, startLoc.Longitude, (float)azimuth, stepLength); - - //所有没有虚拟ID的飞机 - List remainCopters = _copterManager.Copters.Where(o => o.VirtualId == 0).ToList(); - - - - foreach (var copter in remainCopters) + //计算这些飞机和startLoc的距离 + double temp = startLoc.CalcDistance2D(copter); + //找最近的飞机 + if (temp < mindis) { - //计算这些飞机和targetLatLng的距离 - double temp = GeographyUtils.CalcDistance2D(copter.Latitude, copter.Longitude, - targetLatLng.Item1, targetLatLng.Item2); - - //找最近的飞机 - if (temp < mindis) - { - mindis = temp; - retCopter = copter; - } - - - //如果目标点最近未标注飞机小于1米就认为找到了 - if (mindis < 1.0) - { - foundCopter = true; - retCopter = copter; - break; - } - } - //不找更多步长 - break; - if (stepLength > 15) - { - break; + mindis = temp; + foundCopter = copter; } } - - if (foundCopter) - return retCopter; - else - return null; + + //如果找到的最近的飞机小于查找半径就认为找到了 + if (mindis < findDis) + retCopter = foundCopter; + return retCopter; } - - - - //根据当前位置和角度距离查找下一个位置 - private ILocation2D FindNextLocal(ILocation2D startLoc, float directionDegrees, float distance) + + //根据VID查找飞机 + private ICopter FindCopteratVID(int VID) { - ILocation2D retLoc = null; + List HaveVIDCopters = _copterManager.Copters.Where(o => o.VirtualId == VID).ToList(); + if (HaveVIDCopters.Count==1) + return HaveVIDCopters[0]; + return null; + } - - - //计算startCopter按azimuth方向移动stepLength后的位置targetLatLng - Tuple targetLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D( - startLoc.Latitude, startLoc.Longitude, directionDegrees, distance); - return retLoc; + //计算VID,找下一个没有提前分配的VID + private int GetVID(int VirtualId) + { + int retvid = VirtualId+1; + ICopter Copter = FindCopteratVID(retvid); + while (Copter!=null) + Copter = FindCopteratVID(++retvid); + return retvid; } + /// + /// 按方向步长等找下一架飞机 + /// + /// 起始飞机 + /// 方向 + /// 步长 + /// 查找半径 + /// 找到的飞机 + private ICopter FindNextCopter(ILocation2D Copter, float Direct,float findstep,float finddis,int findstepnum=5) + { + ICopter FindedCopter = null; + ILocation2D FindLoc = null; + int step = 1; + while ((FindedCopter == null) && (step <= findstepnum)) + { + //查找下一个飞机应在摆放的位置 + FindLoc = Copter.CalcLatLngSomeMetersAway2D(Direct, findstep * step++); + //该位置是否有飞机 + FindedCopter = FindCopteratLoc(FindLoc, finddis); + } + return FindedCopter; + } + + + /// + ///按方向步长等找下一行的第一架飞机同时输出该行第一个应该摆放飞机的位置 + /// + /// 输出第一架飞机应该在的位置 + /// 起始飞机 + /// 列角度 + /// 列步长 + /// 行角度 + /// 行步长 + /// 行查找深度 + /// 位置查找范围 + /// 找到的飞机 + private ICopter FindNextColHeadCopter(out ILocation2D HeadLoc, ILocation2D Copter, float ColDirect, float Colstep, + float RowDirect, float Rowstep, int Rowstepnum,float finddis, int Colfindstepnum = 5) + { + ICopter FindedCopter = null; + HeadLoc = null; + int step = 1; + while ((FindedCopter == null) && (step <= Colfindstepnum)) + { + //查找下一行第一架飞机应在摆放的位置 + HeadLoc = Copter.CalcLatLngSomeMetersAway2D(ColDirect, Colstep * step++); + //该位置是否有飞机 + FindedCopter = FindCopteratLoc(HeadLoc, finddis); + //如果没有飞机,横着找找行有没飞机 + if (FindedCopter==null) + FindedCopter=FindNextCopter(HeadLoc, RowDirect, Rowstep, finddis, Rowstepnum); + } + return FindedCopter; + } + } diff --git a/Plane.FormationCreator/ViewModels/CopterListViewModel.cs b/Plane.FormationCreator/ViewModels/CopterListViewModel.cs index 34b3bf6..36ac0cf 100644 --- a/Plane.FormationCreator/ViewModels/CopterListViewModel.cs +++ b/Plane.FormationCreator/ViewModels/CopterListViewModel.cs @@ -158,6 +158,38 @@ namespace Plane.FormationCreator.ViewModels })); } } + + + + private ICommand _SortbyVIdCommand; + public ICommand SortbyVIdCommand + { + get + { + return _SortbyVIdCommand ?? (_SortbyVIdCommand = new RelayCommand( () => + { + _copterManager.sortbyvid(); + + })); + } + } + + + private ICommand _SortbyIdCommand; + public ICommand SortbyIdCommand + { + get + { + return _SortbyVIdCommand ?? (_SortbyVIdCommand = new RelayCommand(() => + { + _copterManager.sortbyid(); + + })); + } + } + + + private ICommand _ShowAllCoptersCommand; public ICommand ShowAllCoptersCommand @@ -180,14 +212,13 @@ namespace Plane.FormationCreator.ViewModels { get { - return _SwitchIdVirtualIdCommand ?? (_SwitchIdVirtualIdCommand = new RelayCommand(async () => + return _SwitchIdVirtualIdCommand ?? (_SwitchIdVirtualIdCommand = new RelayCommand(() => { showVirtualId = !showVirtualId; foreach (var copter in _copterManager.Copters) { copter.DisplayVirtualId = showVirtualId; } - await Task.Delay(10); })); } } @@ -223,11 +254,12 @@ namespace Plane.FormationCreator.ViewModels //内蒙地区 -// if (center.Lat < 37.4307185218 || center.Lat > 45.6754821756 -// || center.Lng < 97.3493089056 || center.Lng > 115.8006783856) -// return ; + // if (center.Lat < 37.4307185218 || center.Lat > 45.6754821756 + // || center.Lng < 97.3493089056 || center.Lng > 115.8006783856) + // return ; - + + LatLng? colLatLng = new LatLng(center.Lat, center.Lng); @@ -247,7 +279,7 @@ namespace Plane.FormationCreator.ViewModels else { if (currcol < colnum) - targetLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D(colLatLng.Value.Lat, colLatLng.Value.Lng , orientation + 90, currcol * coldis); + targetLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D(colLatLng.Value.Lat, colLatLng.Value.Lng , orientation + 90, (currcol * coldis)); else { currrow++; @@ -257,7 +289,17 @@ namespace Plane.FormationCreator.ViewModels colheadLatLng = targetLatLng; } - _lastVirtualCopterLocation= new LatLng(targetLatLng.Item1, targetLatLng.Item2); +/* + //随机位置,偏差40cm + Random r1 = new Random(); + float rdrad= ((float)r1.Next(0, 360)); + float rddis = ((float)r1.Next(-40, 40) / 100.0f); + + targetLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D(targetLatLng.Item1, targetLatLng.Item2, rdrad, rddis); +*/ + + + _lastVirtualCopterLocation = new LatLng(targetLatLng.Item1, targetLatLng.Item2); } currcol++; @@ -271,6 +313,7 @@ namespace Plane.FormationCreator.ViewModels */ + var copter = new FakeCopter(SynchronizationContext.Current); copter.SetProperties( diff --git a/Plane.FormationCreator/Views/ConfigVirtualIdView.xaml b/Plane.FormationCreator/Views/ConfigVirtualIdView.xaml index 579fdb6..005ea53 100644 --- a/Plane.FormationCreator/Views/ConfigVirtualIdView.xaml +++ b/Plane.FormationCreator/Views/ConfigVirtualIdView.xaml @@ -15,7 +15,7 @@ -