为三亚做准备:

导入起飞位置
导入C4D关键帧
碰撞检测不暂停任务
起飞摆放高度
添加分组设置
灯光设置优化
当前检测碰撞为1.8米
This commit is contained in:
zxd 2019-03-23 21:43:51 +08:00
parent 9c70ad73ea
commit cce5722a52
22 changed files with 474 additions and 72 deletions

View File

@ -33,7 +33,6 @@ namespace Plane.FormationCreator
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("en-US");
ServiceLocatorConfigurer.Instance.Configure();
_logger = ServiceLocator.Current.GetInstance<ILogger>();
_copterManager = ServiceLocator.Current.GetInstance<CopterManager>();
_formationController = ServiceLocator.Current.GetInstance<FormationController>();

View File

@ -145,6 +145,7 @@ namespace Plane.FormationCreator.Formation
{
_selectCopterAction(copter);
}
}
public class SelectedCoptersChangedEventArgs : EventArgs

View File

@ -14,7 +14,7 @@ namespace Plane.FormationCreator.Formation
{
public const float GpsArrivedDis = 2.0f; //GPS模式下航点到达精度
public const float RTKArrivedDis = 1.5f; //RTK模式航点达到精度
public const float GpsCloseDis = 1.5f; //GPS模式下碰撞检测最近距离
public const float GpsCloseDis = 1.8f; //GPS模式下碰撞检测最近距离
public const float RTKClosedDis = 0.5f; //RTK模式下碰撞检测最近距离
@ -81,14 +81,14 @@ namespace Plane.FormationCreator.Formation
public static bool IsTooCloseTo(this ICopter copter, ICopter copter2)
{
if ((copter.GpsFixType == GpsFixType.RTKFIXED)&& (copter2.GpsFixType == GpsFixType.RTKFIXED))
//return false; //效果图用 不检测碰撞
if (copter.Altitude < 3 || copter2.Altitude < 3)
return false;
if ((copter.GpsFixType == GpsFixType.RTKFIXED) && (copter2.GpsFixType == GpsFixType.RTKFIXED))
return copter.DistanceTo(copter2) < RTKClosedDis; //最近距离0.5米
else
return copter.DistanceTo(copter2) < GpsCloseDis; //最近距离2米
}
}
}

View File

@ -88,7 +88,6 @@ namespace Plane.FormationCreator.Formation
}
private CopterManager _copterManager;
private int _TakeOffNumAttr = 1;
public int TakeOffNumAttr
@ -417,6 +416,49 @@ namespace Plane.FormationCreator.Formation
}
}
public void ImportC4DFlytoTask(string txt)
{
string[] lines = txt.Replace("\r\n", "\n").Split('\n');
if (lines.Length != _copterManager.Copters.Count)
return;
var lastTask = Tasks.LastOrDefault();
var newTask = new FlightTask(FlightTaskType.FlyTo) { StaggerRoutes = true, FlytoTime = 10, LoiterTime = 10 };
int i = 0;
foreach (string line in lines)
{
string[] parameters = line.Split(' ');
string id = parameters[0];
string frame = parameters[1];
string x = parameters[2]; //左右 经度
string y = parameters[3]; //上下 高度
string z = parameters[4]; //前后 纬度
Tuple<double, double> observationLatLng = null;
observationLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D(
OriginLat,
OriginLng,
90,
Convert.ToSingle(x) / 100);
observationLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D(
observationLatLng.Item1,
observationLatLng.Item2,
0,
Convert.ToSingle(z) / 100);
var thisSingleCopterInfo = FlightTaskSingleCopterInfo.CreateForFlyToTask(
_copterManager.Copters[Convert.ToInt32(id)], new LatLng(observationLatLng.Item1 - OriginLat, observationLatLng.Item2 - OriginLng),
Convert.ToSingle(y)/100, false);
newTask.SingleCopterInfos.Add(thisSingleCopterInfo);
i++;
}
Tasks.Add(newTask);
TaskAdded?.Invoke(this, new FlightTaskAddedEventArgs { LastTask = lastTask, AddedTask = newTask });
}
public void ImportBlenderFlyToTask(string blenderVectors)
{
string[] lineVectors = blenderVectors.Replace("\r\n","\n").Split('\n');
@ -683,7 +725,7 @@ namespace Plane.FormationCreator.Formation
}
//导出任务
public string ExportTasks()
public IEnumerable<object> ExportTasks()
{
// For reference.
//var tasks = new object[]
@ -927,14 +969,13 @@ namespace Plane.FormationCreator.Formation
throw new NotImplementedException(type + " task export not implemented.");
}
});
return JsonConvert.SerializeObject(tasks);
return tasks;
}
//导入任务,可设置导入哪些步骤
public void ImportTasksindex(string tasksText,int startindex,int endindex)
public void ImportTasksindex(dynamic tasks, int startindex,int endindex)
{
dynamic tasks = JsonConvert.DeserializeObject(tasksText);
var copters = _copterManager.Copters;
if (Tasks.Count == 0)
@ -1125,14 +1166,13 @@ namespace Plane.FormationCreator.Formation
}
// 导入任务
public void ImportTasks(string tasksText)
public void ImportTasks(dynamic tasks)
{
dynamic tasks = JsonConvert.DeserializeObject(tasksText);
var copters = _copterManager.Copters;
if (Tasks.Count == 0)
AddTakeOffTask(copters);
foreach (var task in tasks)
{
switch ((FlightTaskType)task.type)
@ -1170,6 +1210,16 @@ namespace Plane.FormationCreator.Formation
}
}
private void ImportCoptersLocate(dynamic coptersLocate)
{
}
private void ImportGroupsInfo(dynamic coptersLocate)
{
}
public void Select(int taskIndex, ICopter copter)
{
this.SelectedTaskIndex = taskIndex;
@ -1325,6 +1375,7 @@ namespace Plane.FormationCreator.Formation
task.Status = FlightTaskStatus.Running;
CurrentRunningTask = task;
CurrentRunningTaskIndex = i;
Message.Show($"任务{i+1}开始执行");
await task.RunAsync().ConfigureAwait(false);
// 1. 被暂停时,中断 RunAsync。继续运行时将把此时运行了一半的 CurrentRunningTask 重新运行一遍。
if (IsPaused == true)
@ -1373,10 +1424,10 @@ namespace Plane.FormationCreator.Formation
{
if (copter != anotherCopter && copter.IsTooCloseTo(anotherCopter))
{
Pause();
//Pause();
Message.Show($"{copter.Name} 与 {anotherCopter.Name} 距离过近,已中止任务。");
// Alert.Show($"{copter.Name} 与 {anotherCopter.Name} 距离过近,已中止任务。");
return;
//return;
}
}
}

View File

@ -144,6 +144,45 @@ namespace Plane.FormationCreator.Formation
}
private int _TakeOffMinTime = 0;
public int TakeOffMinTime
{
get { return _TakeOffMinTime; }
set { Set(nameof(TakeOffMinTime), ref _TakeOffMinTime, value); }
}
private int _TakeOffMaxTime = 10;
public int TakeOffMaxTime
{
get { return _TakeOffMaxTime; }
set { Set(nameof(TakeOffMaxTime), ref _TakeOffMaxTime, value); }
}
private ICommand _SetRandomOffWaitDelayCommand;
public ICommand SetRandomOffWaitDelayCommand
{
get
{
return _SetRandomOffWaitDelayCommand ?? (_SetRandomOffWaitDelayCommand = new RelayCommand<double>(async =>
{
foreach (FlightTaskSingleCopterInfo info in _flightTaskManager.SelectedTask.SingleCopterInfos)
{
if (_copterManager.AcceptingControlCopters.Contains(info.Copter))
{
Random random = new Random(Guid.NewGuid().GetHashCode());
ushort delay = (ushort)random.Next(TakeOffMinTime, TakeOffMaxTime);
info.TakeOffWaitTime = delay;
}
}
}));
}
}
public LatLng LatLngOffset
{
get

View File

@ -188,15 +188,34 @@ namespace Plane.FormationCreator.Formation
await Task.Delay(10).ConfigureAwait(false); //判断是否到达位置10hz
// if (info.LEDInfos.Count > 0)
// {
// string LEDRGB = "";
// List<LEDInfo> LedControl = info.LEDInfos.OrderBy(i=>i.Delay).ToList();
// for (int i = 0; i < LedControl.Count; i++)
// {
// var led = LedControl[i];
// if (ts.TotalMilliseconds >= led.Delay * 1000)
// LEDRGB = info.LEDInfos[i].LEDRGB;
// else
// break;
// }
// info.Copter.LEDColor = LEDRGB;
//
// }
if (info.LEDInfos.Count > 0)
{
string LEDRGB = "";
List<LEDInfo> LedControl = info.LEDInfos.OrderBy(i=>i.Delay).ToList();
List<LEDInfo> LedControl = info.LEDInfos.ToList();
double time = 0;
for (int i = 0; i < LedControl.Count; i++)
{
var led = LedControl[i];
if (ts.TotalMilliseconds >= led.Delay * 1000)
time += led.Delay * 1000;
if (ts.TotalMilliseconds >= time)
LEDRGB = info.LEDInfos[i].LEDRGB;
else
break;
@ -205,7 +224,7 @@ namespace Plane.FormationCreator.Formation
}
if (ts.TotalMilliseconds / 10 > sendFlyToTimes) // 每500ms发送一遍指点坐标
{

View File

@ -37,8 +37,8 @@
</c:MetroWindow.Resources>
<c:MetroWindow.RightWindowCommands>
<c:WindowCommands>
@ -73,23 +73,28 @@
<Button Name="btnConnect"
Content="连接"
Click="btnConnect_Click" />
<Menu Name="menuTask" VerticalAlignment="Center" >
<Menu Name="menuTask" Background="Transparent" VerticalAlignment="Center" >
<MenuItem Header="导入导出" Margin="0,2,0,0" Foreground="#969696">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Button BorderThickness="1" Content="导出任务" Margin="0,8,0,8"
Command="{Binding ExportTasksCommand}"/>
<CheckBox Content="只导出航点" Grid.Column="1" Margin="0,8,0,8" Foreground="#969696"
IsChecked="{Binding OnlyImpotWaypointS}"/>
<Button BorderThickness="1" BorderBrush="#FFFFFF" Content="导入任务" Margin="0,8,0,8" Grid.Row="1"
Command="{Binding ImportTasksCommand}"></Button>
Command="{Binding ImportTasksCommand}"/>
<StackPanel VerticalAlignment="Center" Margin="0,8,0,8" Grid.Row="1" Grid.Column="1" Orientation="Horizontal">
<TextBlock Foreground="#969696" VerticalAlignment="Center" Text="起始步骤:"/>
<TextBox VerticalAlignment="Bottom" Width="40"
@ -98,13 +103,17 @@
<TextBox VerticalAlignment="Bottom" Width="40"
Text="{Binding txtendindex, UpdateSourceTrigger=PropertyChanged}"/>
</StackPanel>
<Button BorderThickness="1" BorderBrush="#FFFFFF" Content="导入摆放位置" Margin="25,8,0,8" Grid.Row="2"
Command="{Binding ImportTasksCommand}"/>
</Grid>
</MenuItem>
</Menu>
<Menu Name="otherWindows" Background="Transparent" VerticalAlignment="Center">
<MenuItem Header="窗口" Margin="0,2,0,0" Foreground="#969696">
<CheckBox Content="属性设置" Margin="0,8,0,8" IsChecked="False" Click="btnAttribute_Click"/>
<CheckBox Content="分组设置" Margin="0,8,0,8" IsChecked="False" Click="btnGroup_Click"/>
</MenuItem>
</Menu>
</c:WindowCommands>
</c:MetroWindow.RightWindowCommands>
@ -132,8 +141,7 @@
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TabControl SelectedIndex="{Binding MapMode,UpdateSourceTrigger=PropertyChanged}">
<TabControl SelectedIndex="{Binding MapMode,UpdateSourceTrigger=PropertyChanged}" Grid.RowSpan="3">
<TabItem Visibility="Collapsed">
<v:MapView x:Name="map"/>
</TabItem >
@ -142,15 +150,28 @@
</TabItem>
</TabControl>
<Grid Grid.Row="1" HorizontalAlignment="Right">
<WrapPanel Orientation="Vertical">
<v:CopterAttributeView
x:Name="attributeView"
Visibility="Collapsed"
DataContext="{Binding Path=CopterListViewModel}">
</v:CopterAttributeView>
<v:CopterGroupsView
x:Name="groupsView"
Visibility="Collapsed">
</v:CopterGroupsView>
</WrapPanel>
</Grid>
<!--
<v:MapView x:Name="map"/>
-->
<v:TaskBarView
Grid.Row="2"
x:Name="TaskbarControl"
VerticalAlignment="Bottom"
Visibility="{Binding Source={x:Static local:AppEx.Current}, Path=AppMode, Converter={StaticResource AppModeToVisibilityConverter}, ConverterParameter=TaskBarView}" />
@ -169,18 +190,12 @@
<v:CopterListView />
<StackPanel Grid.Row="1">
<StackPanel Grid.Row="2"
Visibility="{Binding AppEx.ShowModifyTaskView, Converter={StaticResource InversiveBooleanToVisibilityConverter}}">
<Separator Grid.ColumnSpan="2" />
<v:ControlPanelView />
</StackPanel>
<StackPanel Visibility="{Binding AppEx.ShowModifyTaskView, Converter={StaticResource BooleanToVisibilityConverter}}">
<Separator />
<v:ModifyTaskView />

View File

@ -507,5 +507,23 @@ namespace Plane.FormationCreator
map.Opacity = 1;
}
}
private void btnAttribute_Click(object sender, RoutedEventArgs e)
{
CheckBox checkbox = sender as CheckBox;
if (checkbox.IsChecked == false)
attributeView.Visibility = Visibility.Collapsed;
else
attributeView.Visibility = Visibility.Visible;
}
private void btnGroup_Click(object sender, RoutedEventArgs e)
{
CheckBox checkbox = sender as CheckBox;
if (checkbox.IsChecked == false)
groupsView.Visibility = Visibility.Collapsed;
else
groupsView.Visibility = Visibility.Visible;
}
}
}

View File

@ -174,6 +174,7 @@
<Compile Include="Formation\FlightTask_Turn.cs" />
<Compile Include="Formation\FormationController.cs" />
<Compile Include="Formation\CopterManager.cs" />
<Compile Include="Formation\GroupManager.cs" />
<Compile Include="Formation\LatLng.cs" />
<Compile Include="Formation\MapManager.cs" />
<Compile Include="Formation\MapServer.cs" />
@ -196,6 +197,7 @@
<Compile Include="ViewModels\ConnectViewModel.cs" />
<Compile Include="ViewModels\ControlPanelViewModel.cs" />
<Compile Include="ViewModels\CopterListViewModel.cs" />
<Compile Include="ViewModels\GroupsViewModel.cs" />
<Compile Include="ViewModels\MainViewModel.cs" />
<Compile Include="ViewModels\MapViewModel.cs" />
<Compile Include="ViewModels\ModifyTaskViewModel.cs" />
@ -208,6 +210,12 @@
<Compile Include="Views\ControlPanelView.xaml.cs">
<DependentUpon>ControlPanelView.xaml</DependentUpon>
</Compile>
<Compile Include="Views\CopterAttributeView.xaml.cs">
<DependentUpon>CopterAttributeView.xaml</DependentUpon>
</Compile>
<Compile Include="Views\CopterGroupsView.xaml.cs">
<DependentUpon>CopterGroupsView.xaml</DependentUpon>
</Compile>
<Compile Include="Views\CopterInfoView.xaml.cs">
<DependentUpon>CopterInfoView.xaml</DependentUpon>
</Compile>
@ -325,6 +333,14 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\CopterAttributeView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\CopterGroupsView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\CopterInfoView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>

View File

@ -34,9 +34,11 @@ namespace Plane.FormationCreator
_container.Register<View3DViewModel>();
_container.Register<ModifyTaskViewModel>();
_container.Register<CalibrationViewModel>();
_container.Register<GroupsViewModel>();
_container.Register<ILogger>(() => new LocalFileLogger(new DebugLogger()));
_container.Register<GroupManager>();
_container.Register<CopterManager>();
_container.Register<MapManager>();
_container.Register<View3DManager>();

View File

@ -159,7 +159,7 @@ namespace Plane.FormationCreator.ViewModels
await commModule.DoCalibrationCompassAsync(_copterManager.SelectedCopters);
await Task.Delay(50).ConfigureAwait(false);
/*
/*
IsCalibration = true;
CompassPercent = 0;

View File

@ -125,6 +125,13 @@ namespace Plane.FormationCreator.ViewModels
set { Set(nameof(CopterNum), ref _CopterNum, value); }
}
private string _CopterColor = "";
public string CopterColor
{
get { return _CopterColor; }
set { Set(nameof(CopterColor), ref _CopterColor, value); }
}
private ICommand _WriteIdCommand;
public ICommand WriteIdCommand
{
@ -215,7 +222,7 @@ namespace Plane.FormationCreator.ViewModels
{
return _CommDataAsync ?? (_CommDataAsync = new RelayCommand(async () =>
{
await commModule.TestLED((short)CopterNum);
await commModule.TestLED((short)CopterNum, CopterColor);
}
));
}

View File

@ -978,7 +978,7 @@ namespace Plane.FormationCreator.ViewModels
int utcsecond = DateTime.UtcNow.AddSeconds(5).Second;
Message.Show("开始任务");
//循环3次 发送起飞命令 避免通信问题
for (int i = 0; i < 5; i++)
for (int i = 0; i < 10; i++)
{
await _commModuleManager.DoMissionStartAsync(utchour,
utcminute,
@ -1001,6 +1001,7 @@ namespace Plane.FormationCreator.ViewModels
await Task.Delay(10).ConfigureAwait(false);
}
Alert.Show("所有飞机开始执行航点任务。请勿多次开始任务!", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
}));
}
}
@ -1144,10 +1145,12 @@ namespace Plane.FormationCreator.ViewModels
/// <returns></returns>
private async Task CollectMissions(int i)
{
float groudAlt = _copterManager.Copters[i].GroundAlt;
var missions = new List<IMission>();
var _flightTaskManager = ServiceLocator.Current.GetInstance<FlightTaskManager>();
for (int j = 0; j < _flightTaskManager.Tasks.Count; j++)
{
switch (_flightTaskManager.Tasks[j].TaskType)
{
case FlightTaskType.TakeOff:
@ -1158,11 +1161,12 @@ namespace Plane.FormationCreator.ViewModels
_flightTaskManager.Tasks[j].TakeOffTime,
_flightTaskManager.Tasks[j + 1].SingleCopterInfos[i].TargetLat - _flightTaskManager.OriginLat,
_flightTaskManager.Tasks[j + 1].SingleCopterInfos[i].TargetLng - _flightTaskManager.OriginLng,
_flightTaskManager.Tasks[j + 1].SingleCopterInfos[i].TargetAlt)
_flightTaskManager.Tasks[j + 1].SingleCopterInfos[i].TargetAlt - groudAlt)
);
break;
case FlightTaskType.FlyTo:
missions.AddRange(CreateLEDMissions(_flightTaskManager.Tasks[j].SingleCopterInfos[i].LEDInfos));
if (_flightTaskManager.Tasks[j].SingleCopterInfos[i].IsChangeSpeed)
{
@ -1179,12 +1183,13 @@ namespace Plane.FormationCreator.ViewModels
Lat = 90;
Lng = 180;
}
missions.Add(Mission.CreateWaypointMission(
_flightTaskManager.Tasks[j].LoiterTime,
_flightTaskManager.Tasks[j].FlytoTime,
Lat,
Lng,
_flightTaskManager.Tasks[j].SingleCopterInfos[i].TargetAlt)
_flightTaskManager.Tasks[j].SingleCopterInfos[i].TargetAlt - groudAlt)
);
break;
case FlightTaskType.Loiter:

View File

@ -17,16 +17,20 @@ using Plane.Communication;
using Plane.Geography;
using Microsoft.Practices.ServiceLocation;
using Plane.FormationCreator.Util;
using Newtonsoft.Json;
using System.IO;
using Newtonsoft.Json.Linq;
namespace Plane.FormationCreator.ViewModels
{
public class CopterListViewModel : ViewModelBase
{
public CopterListViewModel(CopterManager copterManager, MapManager mapManager, FlightTaskManager flightTaskManager)
public CopterListViewModel(CopterManager copterManager, MapManager mapManager, FlightTaskManager flightTaskManager, GroupManager groupManager)
{
_copterManager = copterManager;
_mapManager = mapManager;
_flightTaskManager = flightTaskManager;
_groupManager = groupManager;
/*
System.Timers.Timer t = new System.Timers.Timer(5000); //实例化Timer类设置间隔时间为1秒
t.Elapsed += new System.Timers.ElapsedEventHandler(theout); //到达时间的时候执行事件;
@ -55,12 +59,14 @@ namespace Plane.FormationCreator.ViewModels
allsend / _copterManager.Copters.Count+"/s";
}
private GroupManager _groupManager;
private CopterManager _copterManager;
private MapManager _mapManager;
private FlightTaskManager _flightTaskManager;
private View3DManager _view3DManager = ServiceLocator.Current.GetInstance<View3DManager>();
public CopterManager CopterManager { get { return _copterManager; } }
private ICopter _SelectedCopter;
public ICopter SelectedCopter
@ -93,7 +99,9 @@ namespace Plane.FormationCreator.ViewModels
set { Set(nameof(ContinuousNum), ref _ContinuousNum, value); }
}
public ObservableCollection<string[]> CopterGroups { get; } = new ObservableCollection<string[]>();
private ICommand _IntervalSelectCoptersCommand;
public ICommand IntervalSelectCoptersCommand
@ -296,7 +304,128 @@ namespace Plane.FormationCreator.ViewModels
}
}
// private ICommand _ImportCoptersLocationCommand;
// public ICommand ImportCoptersLocationCommand
// {
// get
// {
// return _ImportCoptersLocationCommand ?? (_ImportCoptersLocationCommand = new RelayCommand(async() =>
// {
// var dialog = new Microsoft.Win32.OpenFileDialog
// {
// DefaultExt = "json",
// Filter = "编队飞行任务 (*.json)|*.json"
// };
// if (dialog.ShowDialog() == true)
// {
// var locationsText = File.ReadAllText(dialog.FileName);
// dynamic coptersLocation = JsonConvert.DeserializeObject(locationsText);
// foreach (var location in coptersLocation)
// {
// var name = location.Name;
// JArray locations = location.Value as JArray;
// var x = ((Newtonsoft.Json.Linq.JValue)(locations[0])).Value;
// float fx = Convert.ToSingle(x);
// var y = ((Newtonsoft.Json.Linq.JValue)(locations[1])).Value;
// float fy = Convert.ToSingle(y);
//
// var fc = _copterManager.Copters[int.Parse(name) - 1] as FakeCopter;
// Tuple<double, double> observationLatLng = null;
// observationLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D(
// _flightTaskManager.OriginLat,
// _flightTaskManager.OriginLng,
// 90,
// fx);
//
//
// observationLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D(
// observationLatLng.Item1,
// observationLatLng.Item2,
// 0,
// fy);
//
// fc.SetProperties(
// latitude: observationLatLng.Item1,
// longitude: observationLatLng.Item2
// );
// }
// }
//
// await Task.Delay(10);
// }));
// }
// }
private ICommand _ImportCoptersLocationCommand;
public ICommand ImportCoptersLocationCommand
{
get
{
return _ImportCoptersLocationCommand ?? (_ImportCoptersLocationCommand = new RelayCommand(async () =>
{
var dialog = new Microsoft.Win32.OpenFileDialog
{
DefaultExt = "txt",
Filter = "编队飞行任务 (*.json)|*.txt"
};
if (dialog.ShowDialog() == true)
{
var locationsText = File.ReadAllText(dialog.FileName);
string[] coptersLocation = locationsText.Replace("\r\n","\n").Split('\n');
foreach (var location in coptersLocation)
{
string[] locations = location.Split(' ');
var name = locations[0];
var x = locations[2];
float fx = Convert.ToSingle(x)/100;
var y = locations[4];
float fy = Convert.ToSingle(y)/100;
var fc = _copterManager.Copters[int.Parse(name)] as FakeCopter;
Tuple<double, double> observationLatLng = null;
observationLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D(
_flightTaskManager.OriginLat,
_flightTaskManager.OriginLng,
90,
fx);
observationLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D(
observationLatLng.Item1,
observationLatLng.Item2,
0,
fy);
fc.SetProperties(
latitude: observationLatLng.Item1,
longitude: observationLatLng.Item2
);
}
}
await Task.Delay(10);
}));
}
}
private ICommand _ApplyGroundAltCommand;
public ICommand ApplyGroundAltCommand
{
get
{
return _ApplyGroundAltCommand ?? (_ApplyGroundAltCommand = new RelayCommand(async () =>
{
foreach (var copter in _copterManager.SelectedCopters)
{
copter.GroundAlt = SelectedCopter.GroundAlt;
}
await Task.Delay(10);
}));
}
}
}
}

View File

@ -12,6 +12,7 @@ using System.Windows.Input;
using Microsoft.Win32;
using Microsoft.Practices.ServiceLocation;
using System.IO;
using Newtonsoft.Json;
namespace Plane.FormationCreator.ViewModels
{
@ -32,6 +33,9 @@ namespace Plane.FormationCreator.ViewModels
private CopterListViewModel _copterListViewModel;
public CopterListViewModel CopterListViewModel { get { return _copterListViewModel; } }
private FlightTaskManager _flightTaskManager = ServiceLocator.Current.GetInstance<FlightTaskManager>();
private GroupManager _groupManager = ServiceLocator.Current.GetInstance<GroupManager>();
private CopterManager _copterManager = ServiceLocator.Current.GetInstance<CopterManager>();
public AppEx AppEx { get; } = AppEx.Current;
private void AppEx_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
@ -171,7 +175,12 @@ namespace Plane.FormationCreator.ViewModels
}
private bool _OnlyImpotWaypointS = true;
public bool OnlyImpotWaypointS
{
get { return _OnlyImpotWaypointS; }
set { Set(nameof(OnlyImpotWaypointS), ref _OnlyImpotWaypointS, value); }
}
private ICommand _ExportTasksCommand;
public ICommand ExportTasksCommand
@ -185,7 +194,28 @@ namespace Plane.FormationCreator.ViewModels
Alert.Show("作为参照的原点未设置,无法导出相对位置!", "提示");
return;
}
var exportedText = _flightTaskManager.ExportTasks();
string exportedText;
var taskObject = _flightTaskManager.ExportTasks();
if (OnlyImpotWaypointS)
{
exportedText = JsonConvert.SerializeObject(taskObject);
}
else
{
var groupObject = _groupManager.ExportGroups();
var locateObject = ExportLocate();
object obj = new
{
groups = groupObject,
locate = locateObject,
tasks = taskObject
};
exportedText = JsonConvert.SerializeObject(obj);
}
var dialog = new SaveFileDialog
{
DefaultExt = "fcg",
@ -199,6 +229,20 @@ namespace Plane.FormationCreator.ViewModels
}
}
private List<object> ExportLocate()
{
List<object> locateList = new List<object>();
foreach (var copter in _copterManager.Copters)
{
double[] locate = new double[3];
locate[0] = copter.Latitude - _flightTaskManager.OriginLat;
locate[1] = copter.Longitude - _flightTaskManager.OriginLng;
locate[2] = copter.GroundAlt;
locateList.Add(locate);
}
return locateList;
}
private int _txtStarindex = 0;
public int txtStarindex
@ -236,9 +280,32 @@ namespace Plane.FormationCreator.ViewModels
int _startindex = txtStarindex;
int _endindex = txtendindex;
var tasksText = File.ReadAllText(dialog.FileName);
var importText = File.ReadAllText(dialog.FileName);
dynamic importInfo = JsonConvert.DeserializeObject(importText);
dynamic taskinfo = null;
if (importInfo is Newtonsoft.Json.Linq.JObject)
{
taskinfo = importInfo.tasks;
if (importInfo.locate != null)
{
//ImportCoptersLocate(importInfo.locate);
}
if (importInfo.groups != null)
{
_groupManager.ImportGroupsInfo(importInfo.groups);
}
}
else if (importInfo is Newtonsoft.Json.Linq.JArray)
{
taskinfo = importInfo;
}
if ((txtStarindex == 0) && (txtendindex == 0))
_flightTaskManager.ImportTasks(tasksText);
{
_flightTaskManager.ImportTasks(taskinfo);
}
else
{
_endindex = txtendindex;
@ -246,7 +313,7 @@ namespace Plane.FormationCreator.ViewModels
_startindex = 1;
if (_endindex == 0)
_endindex = _startindex;
_flightTaskManager.ImportTasksindex(tasksText, _startindex, _endindex);
_flightTaskManager.ImportTasksindex(taskinfo, _startindex, _endindex);
}

View File

@ -521,9 +521,8 @@ namespace Plane.FormationCreator.ViewModels
if (dialog.ShowDialog() == true)
{
var tasksText = File.ReadAllText(dialog.FileName);
_flightTaskManager.ImportBlenderFlyToTask(tasksText);
_flightTaskManager.ImportC4DFlytoTask(tasksText);
//_flightTaskManager.ImportBlenderFlyToTask(tasksText);
}
}));
}
@ -926,9 +925,10 @@ public ICommand VerticlAlignmentCommand
if (_copterManager.Copters.Count > 0)
{
centlng = _copterManager.Copters[0].Longitude;
centlat = _copterManager.Copters[0].Latitude;
//centlng = _copterManager.Copters[0].Longitude;
//centlat = _copterManager.Copters[0].Latitude;
centlng = _flightTaskManager.OriginLng;
centlat = _flightTaskManager.OriginLat;
//虚拟飞机一起旋转
if ("FakeCopter" == _copterManager.Copters[0].GetType().Name)
{
@ -1517,8 +1517,11 @@ public ICommand VerticlAlignmentCommand
{
LEDInfo endLed = new LEDInfo();
endLed.LEDMode = 0;
endLed.Delay = BeginTime + (time + 1) * (EndTime - BeginTime) / AverageSum;
endLed.LEDRGB = EndRGB;
endLed.Delay = (EndTime - BeginTime) / AverageSum;
if (EndRGB == "0")
endLed.LEDRGB = copterInfo.LEDInfos[copterInfo.LEDInfos.Count - 2].LEDRGB;
else
endLed.LEDRGB = EndRGB;
copterInfo.AddLEDInfo(endLed);
}
}
@ -1585,9 +1588,21 @@ public ICommand VerticlAlignmentCommand
LEDInfo led = new LEDInfo();
led.LEDMode = 0;
led.Delay = curTime;
led.LEDRGB = StrokesRGB;
led.LEDRGB = ChangeRGB;
copterInfo.AddLEDInfo(led);
if (EndRGB != "")
{
LEDInfo endLed = new LEDInfo();
endLed.LEDMode = 0;
endLed.Delay = IntervalTime;
if (EndRGB == "0")
endLed.LEDRGB = copterInfo.LEDInfos[copterInfo.LEDInfos.Count - 2].LEDRGB;
else
endLed.LEDRGB = EndRGB;
copterInfo.AddLEDInfo(endLed);
}
curcount++;
}

View File

@ -103,15 +103,18 @@ namespace Plane.FormationCreator.ViewModels
private void AddOrMove3DCopter(ICopter copter)
{
var copternum1 = _copterManager.Copters.FirstOrDefault();
//var copternum1 = _copterManager.Copters.FirstOrDefault();
if (_flightTaskManager.OriginLat == 0 || _flightTaskManager.OriginLng == 0)
return;
//第一列到中间的距离
float midColDistance = (_flightTaskManager.ColumnCount - 1) * _flightTaskManager.ColumnDistance / 2;
if (observationLatLng == null)
{
observationLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D(
copternum1.Latitude,
copternum1.Longitude,
_flightTaskManager.OriginLat,
_flightTaskManager.OriginLng,
_flightTaskManager.Orientation + 90,
midColDistance);
observationLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D(

View File

@ -145,7 +145,8 @@
<TextBox Margin="2,5,5,5" Width="30" Text="{Binding CopterNum}"></TextBox>
<Button Content=" 对频 " Margin="5,5,0,5" Command="{Binding Path=WriteIdCommand}" />
<Button Content="闪灯" Margin="5" Command="{Binding CommDataAsync}"/>
<TextBox Width="80" Text="{Binding CopterColor}"/>
</StackPanel>
<StackPanel Orientation="Horizontal"

View File

@ -87,6 +87,9 @@
VerticalContentAlignment="Center"
Command="{Binding AddVirtualCopterCommand}"
CommandParameter="{Binding Text, ElementName=txtVirtualCopterCount}" />
<Button Content="导入飞机位置"
Margin="5,0,0,0"
Command="{Binding ImportCoptersLocationCommand}"/>
<Button Content="清除"
Margin="5,0,0,0"
Command="{Binding ClearCoptersCommand}" />

View File

@ -40,7 +40,7 @@ namespace Plane.FormationCreator.Views
lvwDrones.ScrollIntoView(lvwDrones.SelectedItem);
};
}
private CopterManager _copterManager = ServiceLocator.Current.GetInstance<CopterManager>();
private void SelectitemMessage(ICopter copter)
{

View File

@ -67,6 +67,7 @@ namespace Plane.FormationCreator.Views
{
if (Dispatcher.Invoke(RemoveLoadingErrorMessage))
{
delay = 2000;
}
await Task.Delay(delay);

View File

@ -39,20 +39,31 @@
</StackPanel>
<Separator />
<Grid DataContext="{Binding FlightTaskManager.SelectedTask.ModifyingSingleCopterInfo}"
>
<Grid DataContext="{Binding FlightTaskManager.SelectedTask.ModifyingSingleCopterInfo}">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBlock Margin="5" Text="起飞延时"/>
<TextBox Margin="5" Grid.Column="2"
Text="{Binding TakeOffWaitTime, UpdateSourceTrigger=PropertyChanged}"/>
<Button Content="应用所选" Margin="5" Grid.Column="3"
Command="{Binding SetSelTakeOffWaitCommand}"/>
<Separator Grid.Row="1" Grid.ColumnSpan="4"/>
<TextBlock Text="随机时间" Grid.Row="2"/>
<TextBox Margin="10,0" Grid.Row="2" Grid.Column="1" Text="{Binding TakeOffMinTime}"/>
<TextBox Margin="10,0" Grid.Row="2" Grid.Column="2" Text="{Binding TakeOffMaxTime}"/>
<Button Margin="10,0" Content="应用所选" Grid.Row="2" Grid.Column="3"
Command="{Binding SetRandomOffWaitDelayCommand}"/>
</Grid>
</StackPanel>
@ -311,8 +322,7 @@
<TextBox Margin="5,5,0,3" Width="30" Text="{Binding IntervalTime}"/>
<TextBlock Margin="5,7,0,0" Text="œ˜变换数量"/>
<TextBox Margin="5,5,0,3" Width="30" Text="{Binding SingleNum}"/>
<TextBlock Margin="5,7,0,0" Text="颜色"/>
<TextBox Margin="5,5,0,3" Width="60" Text="{Binding StrokesRGB}"/>
<Button Width="70" Content="灯光"
Command="{Binding SetStrokesLampCommamd}" HorizontalAlignment="Right"/>
</StackPanel>
@ -430,5 +440,6 @@
</StackPanel>
</StackPanel>
</TabItem>
</TabControl>
</UserControl>