Subversion Repositories Projects

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2287 - 1
using GMap.NET;
2
using GMap.NET.MapProviders;
3
using GMap.NET.WindowsPresentation;
4
using MKLiveView.GMapCustomMarkers;
5
using System;
6
using System.Collections.Generic;
7
using System.ComponentModel;
8
using System.Data;
9
using System.Diagnostics;
10
using System.IO;
11
using System.Linq;
12
using System.Linq.Expressions;
13
using System.Runtime.InteropServices;
14
using System.Text;
15
using System.Threading;
16
using System.Threading.Tasks;
17
using System.Windows;
18
using System.Windows.Controls;
19
using System.Windows.Data;
20
using System.Windows.Documents;
21
using System.Windows.Input;
22
using System.Windows.Interop;
23
using System.Windows.Media;
24
using System.Windows.Media.Animation;
25
using System.Windows.Media.Imaging;
26
using System.Windows.Navigation;
27
using System.Windows.Shapes;
28
using System.Windows.Threading;
2313 - 29
using System.Globalization;
2324 - 30
using System.Xml;
31
using System.Xml.Linq;
2287 - 32
 
33
namespace MKLiveView
34
{
35
    /// <summary>
36
    /// Interaktionslogik für MainWindow.xaml
37
    /// </summary>
38
    public partial class MainWindow : Window
39
    {
2304 - 40
        #region declarations
41
 
2287 - 42
        GMapMarker copter;
43
        GMapMarker home;
44
        PointLatLng start;
45
        PointLatLng end;
46
        PointLatLng pHome;
2328 - 47
        GMapRoute mRouteWP;
2342 - 48
        GMapMarker wpActiveMarker;
2328 - 49
        List<PointLatLng> wpList = new List<PointLatLng>();
2324 - 50
        #region NC-Errors
2287 - 51
        String[] NC_Error = new string[44]
52
        {
53
            "No Error",
2381 - 54
            "FC not compatible",
55
            "MK3Mag not compatible",
56
            "no FC communication",
57
            "no compass communication",
58
            "no GPS communication",
59
            "bad compass value",
60
            "RC Signal lost",
61
            "FC spi rx error",
62
            "ERR: no NC communication",
63
            "ERR: FC Nick Gyro",
64
            "ERR: FC Roll Gyro",
65
            "ERR: FC Yaw Gyro",
66
            "ERR: FC Nick ACC",
67
            "ERR: FC Roll ACC",
68
            "ERR: FC Z-ACC",
69
            "ERR: Pressure sensor",
70
            "ERR: FC I2C",
71
            "ERR: Bl Missing",
72
            "Mixer Error",
73
            "FC: Carefree Error",
74
            "ERR: GPS lost",
75
            "ERR: Magnet Error",
76
            "Motor restart",
77
            "BL Limitation",
78
            "Waypoint range",
79
            "ERR:No SD-Card",
80
            "ERR:SD Logging aborted",
81
            "ERR:Flying range!",
82
            "ERR:Max Altitude",
83
            "No GPS Fix",
84
            "compass not calibrated",
85
            "ERR:BL selftest",
86
            "no ext. compass",
87
            "compass sensor",
88
            "FAILSAFE pos.!",
89
            "ERR:Redundancy",
90
            "Redundancy test",
91
            "GPS Update rate",
92
            "ERR:Canbus",
93
            "ERR: 5V RC-Supply",
94
            "ERR:Power-Supply",
95
            "ACC not calibr.",
96
            "ERR:Parachute!"
2287 - 97
        };
2381 - 98
        String[] NC_Error_Link = new string[44]
99
        {
100
            "",
101
            "http://wiki.mikrokopter.de/ErrorCodes#A1_.22FC_not_compatible_.22",
102
            "http://wiki.mikrokopter.de/ErrorCodes#A2_.22MK3Mag_not_compatible_.22",
103
            "http://wiki.mikrokopter.de/ErrorCodes#A3_.22no_FC_communication_.22",
104
            "http://wiki.mikrokopter.de/ErrorCodes#A4_.22no_compass_communication_.22",
105
            "http://wiki.mikrokopter.de/ErrorCodes#A5_.22no_GPS_communication_.22",
106
            "http://wiki.mikrokopter.de/ErrorCodes#A6_.22bad_compass_value.22",
107
            "http://wiki.mikrokopter.de/ErrorCodes#A7_.22RC_Signal_lost_.22",
108
            "http://wiki.mikrokopter.de/ErrorCodes#A8_.22FC_spi_rx_error_.22",
109
            "http://wiki.mikrokopter.de/ErrorCodes#A9:_.22ERR:_no_NC_communication.22",
110
            "http://wiki.mikrokopter.de/ErrorCodes#A10_.22ERR:_FC_Nick_Gyro.22",
111
            "http://wiki.mikrokopter.de/ErrorCodes#A11_.22ERR:_FC_Roll_Gyro.22",
112
            "http://wiki.mikrokopter.de/ErrorCodes#A12_.22ERR:_FC_Yaw_Gyro.22",
113
            "http://wiki.mikrokopter.de/ErrorCodes#A13_.22ERR:_FC_Nick_ACC.22",
114
            "http://wiki.mikrokopter.de/ErrorCodes#A14_.22ERR:_FC_Roll_ACC.22",
115
            "http://wiki.mikrokopter.de/ErrorCodes#A15_.22ERR:_FC_Z-ACC.22",
116
            "http://wiki.mikrokopter.de/ErrorCodes#A16_.22ERR:_Pressure_sensor.22",
117
            "http://wiki.mikrokopter.de/ErrorCodes#A17_.22ERR:_FC_I2C.22",
118
            "http://wiki.mikrokopter.de/ErrorCodes#A18_.22ERR:_Bl_Missing.22",
119
            "http://wiki.mikrokopter.de/ErrorCodes#A19_.22Mixer_Error.22",
120
            "http://wiki.mikrokopter.de/ErrorCodes#A20_.22FC:_Carefree_Error.22",
121
            "http://wiki.mikrokopter.de/ErrorCodes#A21_.22ERR:_GPS_lost.22",
122
            "http://wiki.mikrokopter.de/ErrorCodes#A22_.22ERR:_Magnet_Error.22",
123
            "http://wiki.mikrokopter.de/ErrorCodes#A23_.22Motor_restart.22",
124
            "http://wiki.mikrokopter.de/ErrorCodes#A24_.22BL_Limitation.22",
125
            "http://wiki.mikrokopter.de/ErrorCodes#A25_.22Waypoint_range.22",
126
            "http://wiki.mikrokopter.de/ErrorCodes#A26_.22ERR:No_SD-Card.22",
127
            "http://wiki.mikrokopter.de/ErrorCodes#A27_.22ERR:SD_Logging_aborted.22",
128
            "http://wiki.mikrokopter.de/ErrorCodes#A28_.22ERR:Flying_range.21.22",
129
            "http://wiki.mikrokopter.de/ErrorCodes#A29_.22ERR:Max_Altitude.22",
130
            "http://wiki.mikrokopter.de/ErrorCodes#A30_.22No_GPS_Fix.22",
131
            "http://wiki.mikrokopter.de/ErrorCodes#A31_.22compass_not_calibrated.22",
132
            "http://wiki.mikrokopter.de/ErrorCodes#A32_.22ERR:BL_selftest.22",
133
            "http://wiki.mikrokopter.de/ErrorCodes#A33_.22no_ext._compass.22",
134
            "http://wiki.mikrokopter.de/ErrorCodes#A34_.22compass_sensor.22",
135
            "http://wiki.mikrokopter.de/ErrorCodes#A35_.22FAILSAFE_pos..21__.22",
136
            "http://wiki.mikrokopter.de/ErrorCodes#A36_.22ERR:Redundancy__.22",
137
            "http://wiki.mikrokopter.de/ErrorCodes#A37_.22Redundancy_test_.22",
138
            "http://wiki.mikrokopter.de/ErrorCodes#A38_.22GPS_Update_rate.22",
139
            "http://wiki.mikrokopter.de/ErrorCodes#A39_.22ERR:Canbus.22",
140
            "http://wiki.mikrokopter.de/ErrorCodes#A40_.22ERR:_5V_RC-Supply.22",
141
            "http://wiki.mikrokopter.de/ErrorCodes#A41_.22ERR:Power-Supply.22",
142
            "http://wiki.mikrokopter.de/ErrorCodes#A42_.22ACC_not_calibr..22",
143
            "http://wiki.mikrokopter.de/ErrorCodes#A43_.22ERR:Parachute.21.22"
144
        };
145
 
2324 - 146
        #endregion NC-Errors
2287 - 147
        [FlagsAttribute]
148
        enum NC_HWError0 : short
149
        {
150
            None = 0,
151
            SPI_RX = 1,
152
            COMPASS_RX = 2,
153
            FC_INCOMPATIBLE = 4,
154
            COMPASS_INCOMPATIBLE = 8,
155
            GPS_RX = 16,
156
            COMPASS_VALUE = 32
157
        };
158
        [FlagsAttribute]
159
        enum FC_HWError0 : short
160
        {
161
            None = 0,
162
            GYRO_NICK = 1,
163
            GYRO_ROLL = 2,
164
            GYRO_YAW = 4,
165
            ACC_NICK = 8,
166
            ACC_ROLL = 16,
167
            ACC_TOP = 32,
168
            PRESSURE = 64,
169
            CAREFREE = 128
170
        };
171
        [FlagsAttribute]
172
        enum FC_HWError1 : short
173
        {
174
            None = 0,
175
            I2C = 1,
176
            BL_MISSING = 2,
177
            SPI_RX = 4,
178
            PPM = 8,
179
            MIXER = 16,
180
            RC_VOLTAGE = 32,
181
            ACC_NOT_CAL = 64,
182
            RES3 = 128
183
        };
184
        public enum LogMsgType { Incoming, Outgoing, Normal, Warning, Error };
185
        // Various colors for logging info
186
        private Color[] LogMsgTypeColor = { Color.FromArgb(255, 43, 145, 175), Colors.Green, Colors.Black, Colors.Orange, Colors.Red };
187
 
188
        bool _bCBInit = true;
189
        bool _init = true;
190
        bool check_HWError = false;
191
 
192
        string filePath = Directory.GetCurrentDirectory();
193
        bool bReadContinously = false;
194
        bool _debugDataAutorefresh = true;
195
        bool _navCtrlDataAutorefresh = true;
196
        bool _blctrlDataAutorefresh = true;
197
        bool _OSDAutorefresh = true;
198
        bool _bErrorLog = false;
199
        bool _bConnErr = false;
200
        bool _bFollowCopter = false;
2324 - 201
        bool _bGPXLog = false;
2376 - 202
        bool _Simulate = false;
2287 - 203
 
204
        bool _bSaveWinStateNormal = true;
205
        bool _bSaveWinStateFull = true;
206
 
207
        double scaleNormalAll = 1;
208
        double scaleNormalTopBar = 1;
209
        double scaleNormalMotors = 1;
210
        double scaleNormalOSD = 1;
211
        double scaleNormalLOG = 1;
212
        double scaleNormalHorizon = 1;
213
 
214
        double scaleFullAll = 1;
215
        double scaleFullTopBar = 1;
216
        double scaleFullMotors = 1;
217
        double scaleFullOSD = 1;
218
        double scaleFullLOG = 1;
219
        double scaleFullHorizon = 1;
220
 
221
        int _iCtrlAct = 0;
222
        int iOSDPage = 0;
223
        int iOSDMax = 0;
224
        int _iLifeCounter = 0;
225
        int crcError = 0;
226
 
2291 - 227
        bool _bSatFix = false;
228
        Storyboard stbSatFixLostAnim;
229
        bool _bAnimSatFixActive = false;
230
        bool _bVoiceSatFixActive = false;
231
        bool _bVoiceSatFixPlay = false;
232
        int _iSatsLast = 0;
233
        int _iSatsJitter = 0;
234
 
235
        bool _bMagneticFieldOK = false;
236
        Storyboard stbMagneticFieldAnim;
237
        bool _bAnimMagneticFieldActive = false;
238
        bool _bVoiceMagneticFieldActive = false;
239
        bool _bVoiceMagneticFieldPlay = false;
240
        int _iMagneticFieldLast = 0;
241
        int _iMagneticFieldJitter = 0;
242
 
243
        bool _bRCLevelOK = false;
244
        Storyboard stbRCLevelAnim;
245
        bool _bAnimRCLevelActive = false;
246
        bool _bVoiceRCLevelActive = false;
247
        bool _bVoiceRCLevelPlay = false;
248
        int _iRCLevelLast = 0;
249
        int _iRCLevelJitter = 0;
250
 
2287 - 251
        int _iMotors = 4;
252
        int _LipoCells = 4;
253
 
254
        double _dLipoVMax = 16.88;
255
        double _dLipoVMin = 12;
256
        double _dThresholdVoltageWarn = 0;
257
        double _dThresholdVoltageCrit = 0;
258
        Storyboard stbVoltageCritAnim;
259
        bool _bCritAnimVoltActive = false;
260
        bool _bCritVoiceVoltActive = false;
2291 - 261
        bool _bWarnVoiceVoltActive = false;
2287 - 262
        bool _bVoiceVoltPlay = false;
263
        double _dVoltLast = 0;
264
        int _iVoltJitter = 0;
265
 
2291 - 266
        double _dThresholdDistanceWarn = 100;
267
        Storyboard stbDistanceWarnAnim;
268
        bool _bAnimDistanceActive = false;
269
        bool _bVoiceDistanceActive = false;
270
        bool _bVoiceDistancePlay = false;
271
        double _dDistanceLast = 0;
272
        int _iDistanceJitter = 0;
273
 
274
        double _dThresholdDistanceMax = 1000;
275
        int _iThresholdRC = 160;
276
        int _iThresholdMagField = 15;
277
 
2295 - 278
        bool _bAutoHome = false;
279
        bool _bFirstSatFix = false;
280
        int _iFirstSatFix = 0;
2291 - 281
 
2287 - 282
        double _dTopHeight = 36;
283
 
284
        int[] serChan = new int[12] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
285
        int[] serChan_sub = new int[12] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
286
        string[] serChanTitle = new string[12];
287
 
288
        string[] sAnalogLabel = new string[32];
289
        string[] sAnalogData = new string[32];
2324 - 290
        int[] iAnalogData = new int[32];
2287 - 291
 
292
        int[] iTimings = new int[] {100,150,200,250,300,350,400,450,500,550,600,650,700,750,800,850,900,950,1000,1100,1200,1300,1400,1500,1600,1700,1800,1900,2000 };
293
        int[] iMotors = new int[] {3,4,5,6,7,8,9,10,11,12 };
294
        string[] sLiPoCells = new string[] { "3s", "4s", "5s", "6s" };
295
        /// <summary>
296
        /// interval for sending debugdata (multiplied by 10ms)
297
        /// </summary>
298
        byte debugInterval = 10; //(=> 100ms)
299
        /// <summary>
300
        /// interval for sending BL-CTRL status (multiplied by 10ms)
301
        /// </summary>
302
        byte blctrlInterval = 75;
303
        /// <summary>
304
        /// interval for sending NAV-CTRL status (multiplied by 10ms)
305
        /// </summary>
306
        byte navctrlInterval = 80;
307
        /// <summary>
308
        /// interval for sending OSD page update (multiplied by 10ms)
309
        /// </summary>
310
        byte OSDInterval = 85;
311
        /// <summary>
312
        /// datatable for the debug data array - displayed on settings tabpage in datagridview
313
        /// </summary>
314
        DataTable dtAnalog = new DataTable();
315
        /// <summary>
316
        /// datatable for motordata (current,temp)
317
        /// </summary>
2315 - 318
        DataTable dtMotors = new DataTable();
2287 - 319
 
320
        DataTable dtWaypoints = new DataTable();
2313 - 321
        static volatile int _iWPCount = -1;
322
        static volatile int _iWPIndex = -1;
323
        int _iWPTimeout = 1000;
2287 - 324
        bool _bGetWP = false;
2328 - 325
        bool _bShowWPRoute = false;
2287 - 326
        static volatile bool _bGetWPCount = false;
2324 - 327
        DataTable dtGPX = new DataTable();
328
        DataRow drGPX;
329
        bool _bAirborne = false;
2355 - 330
        int _wpIndex = -1, _wpCount = 0, _wpEdit = -1;
2340 - 331
 
2287 - 332
        DispatcherTimer timer = new DispatcherTimer();
333
 
334
        /// <summary>
335
        /// stuff for enabeling touch zoom for the map
336
        /// </summary>
337
        Point pTouch1 = new Point(0,0), pTouch2 = new Point(0,0);
338
        int iFirstStylusID = -1;
339
        public string connectButtonText
340
        {
341
            get
342
            {
343
                return bReadContinously ? "stop polling data" + System.Environment.NewLine + "from copter" : "start polling data" + System.Environment.NewLine + "from copter";
344
            }
345
        }
346
 
347
        WinState winState = new WinState();
2304 - 348
        #endregion declarations
2287 - 349
        public MainWindow()
350
        {
351
            InitializeComponent();
352
            _initForm();
353
            _dataTablesInit();
354
            _setupMap();
355
            _init = false;
356
            timer.Tick += new EventHandler(timerEvent);
357
            timer.Interval = new TimeSpan(0, 0, 1);
358
            timer.Start();
359
        }
360
 
361
        #region init
362
        void _initForm()
363
        {
364
            _readIni();
365
            if (_bSaveWinStateNormal)
366
                _setScaleSliders(false);
367
            cBoxTimingsDebug.ItemsSource =
368
                cBoxTimingsNav.ItemsSource =
369
                cBoxTimingsBl.ItemsSource =
370
                cBoxTimingsOSD.ItemsSource =
371
                iTimings;
372
            cBoxLiPoCells.ItemsSource = sLiPoCells;
373
            cBoxLiPoCells.SelectedItem = _LipoCells.ToString() + "s";
374
            _LipoMinMax();
375
            sliderThresholdVoltageWarn.Value = _dThresholdVoltageWarn;
376
            sliderThresholdVoltageCrit.Value = _dThresholdVoltageCrit;
377
            checkBoxThresholdVoltageVoice.IsChecked = _bVoiceVoltPlay;
2291 - 378
            checkBoxSatfixLost.IsChecked = _bVoiceSatFixPlay;
379
            checkBoxMagneticField.IsChecked = _bVoiceMagneticFieldPlay;
380
            checkBoxThresholdDistanceVoice.IsChecked = _bVoiceDistancePlay;
381
            sliderThresholdDistanceWarn.Value = _dThresholdDistanceWarn;
382
            checkBoxRClevel.IsChecked = _bVoiceRCLevelPlay;
2287 - 383
 
2291 - 384
            sliderThresholdDistanceWarn.Maximum = _dThresholdDistanceMax;
385
 
2287 - 386
            cBoxMotors.ItemsSource = iMotors;
387
            cBoxMotors.SelectedItem = _iMotors;
388
 
389
            serialPortCtrl.PortClosed += serialPortCtrl_PortClosed;
390
            serialPortCtrl.PortOpened += serialPortCtrl_PortOpened;
391
            serialPortCtrl.DataReceived += processMessage;
392
 
393
            chkbAutoBL.IsChecked = _blctrlDataAutorefresh;
394
            chkbAutoDbg.IsChecked = _debugDataAutorefresh;
395
            chkbAutoNav.IsChecked = _navCtrlDataAutorefresh;
396
            chkbAutoOSD.IsChecked = _OSDAutorefresh;
397
 
398
            cBoxTimingsDebug.SelectedItem = debugInterval * 10;
399
            cBoxTimingsNav.SelectedItem = navctrlInterval * 10;
400
            cBoxTimingsBl.SelectedItem = blctrlInterval * 10;
401
            cBoxTimingsOSD.SelectedItem = OSDInterval * 10;
2295 - 402
            checkBoxAutoSetHP.IsChecked = _bAutoHome;
2287 - 403
            checkBoxFollowCopter.IsChecked = _bFollowCopter;
2324 - 404
            checkBoxGPXLog.IsChecked = _bGPXLog;
2328 - 405
            checkBoxShowWPRoute.IsChecked = _bShowWPRoute;
2287 - 406
 
2349 - 407
            _initSerialCtrl();
2287 - 408
        }
409
        /// <summary>
410
        /// initialize the datatables
411
        /// with columnnames etc
412
        /// </summary>
413
        void _dataTablesInit()
414
        {
2315 - 415
            dtMotors.Columns.Add("#");
2313 - 416
            if (Thread.CurrentThread.CurrentUICulture.Name == "de-DE")
2315 - 417
                dtMotors.Columns.Add("Strom");
2313 - 418
            else
2315 - 419
                dtMotors.Columns.Add("Current");
420
            dtMotors.Columns.Add("Temp");
421
            dgvMotors1.DataContext = dtMotors.DefaultView;
2287 - 422
            _initDTMotors();
423
 
424
            Setter setter = new Setter(ContentControl.PaddingProperty, new Thickness(5,0,5,0));
425
            Style style = new Style(typeof(System.Windows.Controls.Primitives.DataGridColumnHeader));
426
            style.Setters.Add(setter);
427
            setter = new Setter(ContentControl.BackgroundProperty, new SolidColorBrush(Colors.Transparent));
428
            style.Setters.Add(setter);
429
            setter = new Setter(ContentControl.ForegroundProperty, new SolidColorBrush(Colors.White));
430
            style.Setters.Add(setter);
2313 - 431
 
432
            dtWaypoints.Columns.Add("Index",typeof(int));
2315 - 433
            dtWaypoints.Columns.Add("Type", typeof(int));
2313 - 434
            dtWaypoints.Columns.Add("Name",typeof(string));
2315 - 435
            dtWaypoints.Columns.Add("Latitude",typeof(double));
436
            dtWaypoints.Columns.Add("Longitude",typeof(double));
2313 - 437
            dtWaypoints.Columns.Add("Altitude",typeof(string));
438
            dtWaypoints.Columns.Add("Heading",typeof(string));
439
            dtWaypoints.Columns.Add("Speed",typeof(string));
440
            dtWaypoints.Columns.Add("ClimbRate",typeof(string));
441
            dtWaypoints.Columns.Add("Radius",typeof(string));
442
            dtWaypoints.Columns.Add("HoldTime",typeof(string));
443
            dtWaypoints.Columns.Add("AutoTrigger",typeof(string));
444
            dtWaypoints.Columns.Add("CamAngle",typeof(string));
445
            dtWaypoints.Columns.Add("Event",typeof(string));
446
            dtWaypoints.Columns.Add("Out1Timer",typeof(string));
447
            dtWaypoints.Columns.Add("Status",typeof(string));
448
            dtWaypoints.PrimaryKey = new DataColumn[] { dtWaypoints.Columns["Index"] };
449
            dgvWP.ItemsSource = dtWaypoints.DefaultView;
2287 - 450
            dgvWP.ColumnHeaderStyle = new Style();
451
            dgvWP.ColumnHeaderStyle = style;
2313 - 452
 
2324 - 453
            dtGPX.Columns.Add("Index",typeof(int));
454
            dtGPX.Columns.Add("Latitude",typeof(double));
455
            dtGPX.Columns.Add("Longitude",typeof(double));
456
            dtGPX.Columns.Add("Elevation",typeof(int));
457
            dtGPX.Columns.Add("Time",typeof(string));
458
            dtGPX.PrimaryKey = new DataColumn[] { dtGPX.Columns["Index"] };
459
            drGPX = dtGPX.NewRow();
2313 - 460
 
2287 - 461
        }
462
        /// <summary>
2315 - 463
        /// initialize the datatable dtMotors for motor values
2313 - 464
        /// DataGridView dgvMotors1 is bound to dtMotors1
2287 - 465
        /// </summary>
466
        void _initDTMotors()
467
        {
468
            for (int i = 0; i < 12; i++)
469
            {
2315 - 470
                if (dtMotors.Rows.Count < 12)
471
                    dtMotors.Rows.Add((i + 1).ToString(), "NA", "NA");
2287 - 472
                else
473
                {
2315 - 474
                    dtMotors.Rows[i].SetField(1, "NA");
475
                    dtMotors.Rows[i].SetField(2, "NA");
2287 - 476
                }
477
            }
478
        }
479
 
480
        #endregion init
481
 
482
        #region events
483
        private void serialPortCtrl_PortOpened()
484
        {
485
            Dispatcher.Invoke(() => imageWiFi.Source = new BitmapImage(new Uri("Images/WiFi_G.png", UriKind.Relative)));
486
            _getVersion();
487
            Thread.Sleep(100);
488
            //_OSDMenue(0);
489
            //Thread.Sleep(200);
490
            //_sendSerialData();
491
            _readCont(true);
492
        }
493
        private void serialPortCtrl_PortClosed()
494
        {
495
            Dispatcher.Invoke(() => imageWiFi.Source = new BitmapImage(new Uri("Images/WiFi_W.png", UriKind.Relative)));
496
            _readCont(false);
497
        }
2324 - 498
        bool _bToggle = false;
2287 - 499
        void timerEvent(object sender, EventArgs e)
500
        {
501
            if (bReadContinously)
502
            {
503
                if (_debugDataAutorefresh) { _readDebugData(true); Thread.Sleep(10); }
504
 
505
                if (_blctrlDataAutorefresh) { _readBLCtrl(true); Thread.Sleep(10); }
506
 
507
                if (_navCtrlDataAutorefresh && _iCtrlAct == 2) { _readNavData(true); Thread.Sleep(10); }
508
                check_HWError = true;
509
                _getVersion();
510
                Thread.Sleep(10);
511
                if (_OSDAutorefresh)
512
                {
513
                    if (iOSDMax == 0 | cbOSD.Items.Count != iOSDMax)
514
                        _initOSDCB();
515
                    _OSDMenueAutoRefresh();
516
                }
517
                if (_iLifeCounter > 0)
518
                {
519
                    Dispatcher.Invoke(() => imageConn.Source = new BitmapImage(new Uri("Images/Data_G.png", UriKind.Relative)));
520
                  //  Dispatcher.Invoke((Action)(() => rctConnection.Fill = Brushes.LightGreen));
521
                    _iLifeCounter = 0;
522
                    _bConnErr = false;
2327 - 523
                    if(_bAirborne && _bGPXLog)
2324 - 524
                    {
525
                        drGPX[0] = dtGPX.Rows.Count;
526
                        dtGPX.Rows.Add(new object[] { drGPX[0], drGPX[1], drGPX[2], drGPX[3], drGPX[4] });
527
                    }
2327 - 528
                    Dispatcher.Invoke((Action)(() => tbSideBarGPXLog.Background = (_bAirborne && _bGPXLog && _bToggle) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));
529
                    Dispatcher.Invoke((Action)(() => tbSideBarGPXLog.Foreground = (_bAirborne && _bGPXLog) ? new SolidColorBrush(Colors.White) : new SolidColorBrush(Color.FromArgb(255, 211, 210, 210))));
530
                    Dispatcher.Invoke((Action)(() => tbSideBarGPXLog.BorderBrush = (_bAirborne && _bGPXLog) ? new SolidColorBrush(Colors.White) : new SolidColorBrush(Color.FromArgb(255, 211, 210, 210))));
2324 - 531
                    _bToggle = !_bToggle;
2287 - 532
                }
533
                else
534
                {
535
                    if (!_bConnErr)
536
                    {
537
                        Log(LogMsgType.Error, "No communication to NC/FC!");
538
                        Dispatcher.Invoke(() => imageConn.Source = new BitmapImage(new Uri("Images/Data_R.png", UriKind.Relative)));
539
                       // Dispatcher.Invoke((Action)(() => rctConnection.Fill = Brushes.Red));
540
                        _bConnErr = true;
541
                    }
542
                }
543
            }
544
        }
545
 
546
        private void labelData_MouseDown(object sender, MouseButtonEventArgs e)
547
        {
548
            GridData.Visibility = GridData.Visibility == Visibility.Collapsed ? Visibility.Visible : Visibility.Collapsed;
549
            GridSettings.Visibility = GridWP.Visibility = Visibility.Collapsed;
550
        }
551
        private void labelMotorData_MouseDown(object sender, MouseButtonEventArgs e)
552
        {
553
            GridMotors.Visibility = GridMotors.Visibility == Visibility.Hidden ? Visibility.Visible : Visibility.Hidden;
554
            if (GridMotors.IsVisible)
555
                _setMotorGridSize();
556
        }
557
        private void labelSettings_MouseDown(object sender, MouseButtonEventArgs e)
558
        {
559
            GridData.Visibility = GridWP.Visibility = Visibility.Collapsed;
560
            GridSettings.Visibility = GridSettings.Visibility == Visibility.Collapsed ? Visibility.Visible : Visibility.Collapsed;
561
        }
562
        private void labelLog_MouseDown(object sender, MouseButtonEventArgs e)
563
        {
564
            GridLog.Visibility = GridLog.Visibility == Visibility.Collapsed ? Visibility.Visible : Visibility.Collapsed;
565
        }
566
        private void labelOSD_MouseDown(object sender, MouseButtonEventArgs e)
567
        {
568
            GridOSD.Visibility = GridOSD.Visibility == Visibility.Hidden ? Visibility.Visible : Visibility.Hidden;
569
        }
570
        private void labelWaypoints_MouseDown(object sender, MouseButtonEventArgs e)
571
        {
572
            GridData.Visibility = GridSettings.Visibility = Visibility.Collapsed;
573
            GridWP.Visibility = GridWP.Visibility == Visibility.Collapsed ? Visibility.Visible : Visibility.Collapsed;
574
        }
575
 
576
        private void btnGetWP_Click(object sender, RoutedEventArgs e)
577
        {
578
            Thread t = new Thread(new ThreadStart(_getWP));
579
            t.Start();
580
        }
581
        private void btnSendWPList_Click(object sender, RoutedEventArgs e)
582
        {
2313 - 583
            Thread t = new Thread(new ThreadStart(_sendWPList));
584
            t.Start();
2287 - 585
        }
586
 
587
        private void btnConnectToCopter_Click(object sender, RoutedEventArgs e)
588
        {
589
            if (!serialPortCtrl.Port.IsOpen)
590
                serialPortCtrl.Connect(true);
591
            else
592
                _readCont(!bReadContinously);
593
        }
594
        private void btnSetHP_Click(object sender, RoutedEventArgs e)
595
        {
2347 - 596
            _setHomePos();
2287 - 597
        }
598
        private void btnClearHP_Click(object sender, RoutedEventArgs e)
599
        {
2347 - 600
            _clearHomePos();
2287 - 601
        }
602
        private void btnGotoHP_Click(object sender, RoutedEventArgs e)
603
        {
604
            if (home != null && MainMap.Markers.Contains(home))
605
                MainMap.Position = home.Position;
606
        }
2295 - 607
        private void checkBoxAutoSetHP_Click(object sender, RoutedEventArgs e)
608
        {
609
            _bAutoHome = (bool)checkBoxAutoSetHP.IsChecked;
610
        }
2287 - 611
        private void chkBoxSaveNormalState_Click(object sender, RoutedEventArgs e)
612
        {
613
            _bSaveWinStateNormal = (bool)chkBoxSaveNormalState.IsChecked;
614
        }
615
        private void chkBoxSaveFullScreenState_Click(object sender, RoutedEventArgs e)
616
        {
617
            _bSaveWinStateFull = (bool)chkBoxSaveFullScreenState.IsChecked;
618
        }
619
 
2291 - 620
        #region thresholds
2287 - 621
        private void sliderThresholdVoltageWarn_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
622
        {
623
            if(!_init)
624
                _dThresholdVoltageWarn = sliderThresholdVoltageWarn.Value;
625
        }
626
        private void sliderThresholdVoltageCrit_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
627
        {
628
            if(!_init)
629
                _dThresholdVoltageCrit = sliderThresholdVoltageCrit.Value;
630
        }
631
        private void checkBoxThresholdVoltageVoice_Click(object sender, RoutedEventArgs e)
632
        {
633
            _bVoiceVoltPlay = (bool)checkBoxThresholdVoltageVoice.IsChecked;
634
        }
2291 - 635
 
636
        private void sliderThresholdDistanceWarn_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
637
        {
638
            if(!_init)
639
                _dThresholdDistanceWarn = sliderThresholdDistanceWarn.Value;
640
        }
641
        private void checkBoxThresholdDistanceVoice_Click(object sender, RoutedEventArgs e)
642
        {
643
            _bVoiceDistancePlay = (bool)checkBoxThresholdDistanceVoice.IsChecked;
644
        }
645
 
646
        private void checkBoxSatfixLost_Click(object sender, RoutedEventArgs e)
647
        {
648
            _bVoiceSatFixPlay = (bool)checkBoxSatfixLost.IsChecked;
649
        }
650
        private void checkBoxMagneticField_Click(object sender, RoutedEventArgs e)
651
        {
652
            _bVoiceMagneticFieldPlay = (bool)checkBoxMagneticField.IsChecked;
653
        }
654
        private void checkBoxRClevel_Click(object sender, RoutedEventArgs e)
655
        {
656
            _bVoiceRCLevelPlay = (bool)checkBoxRClevel.IsChecked;
657
        }
658
        #endregion thresholds
659
 
2287 - 660
        private void buttonSwitchNC_Click(object sender, RoutedEventArgs e)
661
        {
662
            _switchToNC();
663
        }
664
 
665
        private void Window_Loaded(object sender, RoutedEventArgs e)
666
        {
667
            stbVoltageCritAnim = TryFindResource("VoltageCritAnim") as Storyboard;
2291 - 668
            stbSatFixLostAnim = TryFindResource("SatFixLostAnim") as Storyboard;
669
            stbMagneticFieldAnim = TryFindResource("MagneticFieldCritAnim") as Storyboard;
670
            stbDistanceWarnAnim = TryFindResource("DistanceCritAnim") as Storyboard;
671
            stbRCLevelAnim = TryFindResource("RCCritAnim") as Storyboard;
2287 - 672
            _setMotorGridSize();
673
        }
2310 - 674
        private void Window_Closing(object sender, CancelEventArgs e)
675
        {
676
            _writeIni();
2324 - 677
            if(_bGPXLog && dtGPX.Rows.Count > 0)
678
                _saveGPXLog();
2310 - 679
        }
2379 - 680
        private void Window_Closed(object sender, EventArgs e)
681
        {
682
            Application.Current.Shutdown();
683
        }
684
 
2287 - 685
        #endregion events
686
 
687
        #region GMap
688
 
689
        void _setupMap()
690
        {
691
            MainMap.Manager.Mode = AccessMode.ServerAndCache;
692
            MainMap.MapProvider = GMapProviders.BingHybridMap;
693
            MainMap.SetPositionByKeywords("Landshut");
694
            MainMap.MinZoom = 0;
695
            MainMap.MaxZoom = 24;
696
            MainMap.Zoom = 16;
697
            MainMap.ShowCenter = true;
698
            MainMap.ShowTileGridLines = false;
699
            sliderMapZoom.Value = 16;
700
            comboBoxMapType.ItemsSource = providerList;
701
            comboBoxMapType.DisplayMemberPath = "Name";
702
            comboBoxMapType.SelectedItem = MainMap.MapProvider;
703
 
704
            // acccess mode
705
            comboBoxMode.ItemsSource = Enum.GetValues(typeof(AccessMode));
706
            comboBoxMode.SelectedItem = MainMap.Manager.Mode;
707
 
708
        }
709
 
710
        /// <summary>
711
        /// selection of relevant map providers --> if You need more, You can change the line:
712
        ///     comboBoxMapType.ItemsSource = providerList; 
713
        /// to:
714
        ///     comboBoxMapType.ItemsSource = GMapProviders.List;
715
        /// in _setupMap()
716
        /// or add items here:
717
        /// </summary>
718
        List<GMap.NET.MapProviders.GMapProvider> providerList = new List<GMap.NET.MapProviders.GMapProvider>
719
        { GMap.NET.MapProviders.GMapProviders.OpenCycleMap, GMap.NET.MapProviders.GMapProviders.OpenCycleLandscapeMap, GMap.NET.MapProviders.GMapProviders.OpenCycleTransportMap,
720
        GMap.NET.MapProviders.GMapProviders.BingMap,GMap.NET.MapProviders.GMapProviders.BingSatelliteMap,GMap.NET.MapProviders.GMapProviders.BingHybridMap,
721
        GMap.NET.MapProviders.GMapProviders.GoogleMap,GMap.NET.MapProviders.GMapProviders.GoogleSatelliteMap,GMap.NET.MapProviders.GMapProviders.GoogleHybridMap,GMap.NET.MapProviders.GMapProviders.GoogleTerrainMap,
722
        GMap.NET.MapProviders.GMapProviders.OviMap,GMap.NET.MapProviders.GMapProviders.OviSatelliteMap,GMap.NET.MapProviders.GMapProviders.OviHybridMap,GMap.NET.MapProviders.GMapProviders.OviTerrainMap};
723
 
724
        private void MainMap_Loaded(object sender, RoutedEventArgs e)
725
        {
726
            MainMap.Manager.Mode = AccessMode.ServerAndCache;
727
            copter = new GMapMarker(MainMap.Position);
2318 - 728
 
729
            copter.Shape = new CustomMarkerCopter(this, copter, MainMap.Position.Lat.ToString("0.#######°") + System.Environment.NewLine + MainMap.Position.Lng.ToString("0.#######°"),"red");
730
            if (comboBoxCopterColor.SelectionBoxItem != null)
731
            {
732
                string s = comboBoxCopterColor.SelectionBoxItem.ToString();
2385 - 733
                ((CustomMarkerCopter)(copter.Shape)).setCopterColor(s);
2318 - 734
            }
2385 - 735
            Dispatcher.Invoke(() => {
736
                if (comboBoxCopterHeadingColor.SelectionBoxItem != null)
737
                {
738
                    string s = comboBoxCopterHeadingColor.SelectionBoxItem.ToString();
739
                    ((CustomMarkerCopter)(copter.Shape)).setHeadingColor(s);
740
                }
741
            });
742
            copter.Offset = new System.Windows.Point(-28, -28);
2287 - 743
            copter.ZIndex = int.MaxValue;
744
            MainMap.Markers.Add(copter);
745
            copter.Position = MainMap.Position;
746
        }
2347 - 747
        void _setHomePos()
2287 - 748
        {
749
            pHome = MainMap.Position;
750
            if (!MainMap.Markers.Contains(home))
751
            {
752
                home = new GMapMarker(MainMap.Position);
753
                home.Shape = new CustomMarkerHome(this, home, MainMap.Position.Lat.ToString("0.#######°") + System.Environment.NewLine + MainMap.Position.Lng.ToString("0.#######°"));
754
                home.Offset = new System.Windows.Point(-18, -18);
755
                // home.ZIndex = int.MaxValue;
756
                MainMap.Markers.Add(home);
757
            }
758
            home.Position = MainMap.Position;
759
            ((CustomMarkerHome)(home.Shape)).setText(MainMap.Position.Lat.ToString("0.#######°") + System.Environment.NewLine + MainMap.Position.Lng.ToString("0.#######°"));
760
        }
2347 - 761
        void _setActiveWP(int iIndex)
2287 - 762
        {
2347 - 763
            if (wpActiveMarker == null || !MainMap.Markers.Contains(wpActiveMarker))
764
            {
765
                Dispatcher.Invoke(() =>
766
                {
767
                    wpActiveMarker = new GMapMarker(wpList[iIndex]);
768
                    wpActiveMarker.Shape = new CustomMarkerWPActive(this, wpActiveMarker, "wpActive", 0);
769
                    wpActiveMarker.Offset = new Point(-17.5, -17.5);
770
                    MainMap.Markers.Add(wpActiveMarker);
771
                });
772
            }
773
            else
774
                Dispatcher.Invoke(() => wpActiveMarker.Position = wpList[iIndex]);
775
 
776
        }
777
        void _clearHomePos()
778
        {
2287 - 779
            MainMap.Markers.Remove(home);
780
        }
2335 - 781
        void _clearMapMarkers(Type markerType)
782
        {
783
            for (int k = 0; k < MainMap.Markers.Count;)
784
            {
785
                GMapMarker p = MainMap.Markers[k];
2340 - 786
                if (p.GetType() == markerType | (p.Shape != null && p.Shape.GetType() == markerType))
2335 - 787
                    MainMap.Markers.Remove(p);
788
                else
789
                    k++;
790
            }
2287 - 791
 
2335 - 792
        }
2369 - 793
 
794
        GMapMarker _findWPMarker(string name)
2368 - 795
        {
796
            for (int k = 0; k < MainMap.Markers.Count;)
797
            {
798
                GMapMarker p = MainMap.Markers[k];
799
                if (p.GetType() == typeof(CustomMarkerWP) | (p.Shape != null && p.Shape.GetType() == typeof(CustomMarkerWP)))
2369 - 800
                    if (((CustomMarkerWP)p.Shape).WPText == name)
801
                        return p;
2368 - 802
                    else
803
                        k++;
804
                else
805
                    k++;
806
            }
2369 - 807
            return null;
2368 - 808
        }
2369 - 809
        void _clearWPMarker(string name)
810
        {
811
            GMapMarker p = _findWPMarker(name);
812
            if(p != null)
813
                MainMap.Markers.Remove(p);
814
        }
2368 - 815
        void _renameWPMarker(string s1, string s2)
816
        {
2369 - 817
            GMapMarker p = _findWPMarker(s1);
818
            if (p != null)
819
                ((CustomMarkerWP)p.Shape).WPText = s2;
2368 - 820
        }
2372 - 821
        void _WPMarkerSetType(string text, int type)
822
        {
823
            GMapMarker p = _findWPMarker(text);
824
            if (p != null)
825
                ((CustomMarkerWP)p.Shape).WPType = type;
826
        }
2369 - 827
        void _repositionWPMarker(PointLatLng point, string name)
828
        {
829
            GMapMarker p = _findWPMarker(name);
830
            if (p != null)
831
                p.Position = point;
832
        }
833
 
2287 - 834
        // access mode
835
        private void comboBoxMode_DropDownClosed(object sender, EventArgs e)
836
        {
837
            MainMap.Manager.Mode = (AccessMode)comboBoxMode.SelectedItem;
838
            MainMap.ReloadMap();
839
        }
840
        // zoom up
841
        private void czuZoomUp_Click(object sender, RoutedEventArgs e)
842
        {
843
            MainMap.Zoom = ((int)MainMap.Zoom) + 1;
844
        }
845
 
846
        // zoom down
847
        private void czuZoomDown_Click(object sender, RoutedEventArgs e)
848
        {
849
            MainMap.Zoom = ((int)(MainMap.Zoom + 0.99)) - 1;
850
        }
851
 
852
        // prefetch
853
        private void buttonPrefetch_Click(object sender, RoutedEventArgs e)
854
        {
855
            RectLatLng area = MainMap.SelectedArea;
856
            if (!area.IsEmpty)
857
            {
858
                for (int i = (int)MainMap.Zoom; i <= MainMap.MaxZoom; i++)
859
                {
860
                    MessageBoxResult res = MessageBox.Show("Ready ripp at Zoom = " + i + " ?", "GMap.NET", MessageBoxButton.YesNoCancel);
861
 
862
                    if (res == MessageBoxResult.Yes)
863
                    {
864
                        TilePrefetcher obj = new TilePrefetcher();
865
                        obj.Owner = this;
866
                        obj.ShowCompleteMessage = true;
867
                        obj.Start(area, i, MainMap.MapProvider, 100);
868
                    }
869
                    else if (res == MessageBoxResult.No)
870
                    {
871
                        continue;
872
                    }
873
                    else if (res == MessageBoxResult.Cancel)
874
                    {
875
                        break;
876
                    }
877
                }
878
            }
879
            else
880
            {
881
                MessageBox.Show("Select map area holding ALT", "GMap.NET", MessageBoxButton.OK, MessageBoxImage.Exclamation);
882
            }
883
        }
884
 
885
        // goto by geocoder
886
        private void buttonGeoCoding_Click(object sender, RoutedEventArgs e)
887
        {
888
            _goto_byGeoCoder();
889
        }
890
        // goto by geocoder
891
        private void textBoxGeo_KeyUp(object sender, System.Windows.Input.KeyEventArgs e)
892
        {
893
            if (e.Key == System.Windows.Input.Key.Enter)
894
                _goto_byGeoCoder();
895
        }
896
        void _goto_byGeoCoder()
897
        {
898
            GeoCoderStatusCode status = MainMap.SetPositionByKeywords(textBoxGeo.Text);
899
            if (status != GeoCoderStatusCode.G_GEO_SUCCESS)
900
            {
901
                MessageBox.Show("Geocoder can't find: '" + textBoxGeo.Text + "', reason: " + status.ToString(), "GMap.NET", MessageBoxButton.OK, MessageBoxImage.Exclamation);
902
            }
903
        }
904
        private void buttonGeoLoc_Click(object sender, RoutedEventArgs e)
905
        {
906
            try
907
            {
908
                double lat = double.Parse(textBoxLat.Text, System.Globalization.CultureInfo.InvariantCulture);
909
                double lng = double.Parse(textBoxLng.Text, System.Globalization.CultureInfo.InvariantCulture);
910
 
911
                MainMap.Position = new PointLatLng(lat, lng);
912
            }
913
            catch (Exception ex)
914
            {
915
                MessageBox.Show("incorrect coordinate format: " + ex.Message);
916
            }
917
 
918
        }
919
 
920
        private void ReloadMap_Click(object sender, RoutedEventArgs e)
921
        {
922
            MainMap.ReloadMap();
923
        }
924
 
925
        private void MainMap_OnPositionChanged(PointLatLng point)
926
        {
927
            if (_bFollowCopter)
928
                _setCopterData(MainMap.Position);
929
        }
930
 
931
        private void MainMap_OnMapZoomChanged()
932
        {
933
            if (_bFollowCopter)
934
                _setCopterData(MainMap.Position);
935
            if((int)sliderMapZoom.Value != MainMap.Zoom)
936
                sliderMapZoom.Value = MainMap.Zoom;
937
        }
938
 
939
        void _setCopterData(PointLatLng p)
940
        {
941
            Dispatcher.Invoke(() =>
942
            {
943
                copter.Position = p;
944
                ((CustomMarkerCopter)(copter.Shape)).setText(p.Lat.ToString("0.#######°") + System.Environment.NewLine + p.Lng.ToString("0.#######°"));
945
                textBoxLat_currentPos.Text = p.Lat.ToString() + "°";
946
                textBoxLng_currentPos.Text = p.Lng.ToString() + "°";
947
            });
948
            if (home != null && MainMap.Markers.Contains(home))
949
            {
950
                Dispatcher.Invoke(() => ArtHor.rotateHome = GMapProviders.EmptyProvider.Projection.GetBearing(copter.Position, home.Position));
951
                double d = GMapProviders.EmptyProvider.Projection.GetDistance(home.Position, copter.Position);
952
                Dispatcher.Invoke(() => tbTopDistanceHP.Text = (d * 1000).ToString("0.0 m"));
2291 - 953
 
954
                if(d*1000 < _dThresholdDistanceWarn)
955
                {
956
                    _iDistanceJitter = 0; _bVoiceDistanceActive = false;
957
                    if (stbDistanceWarnAnim != null && _bAnimDistanceActive)
958
                    {
959
                        Dispatcher.Invoke(() => stbDistanceWarnAnim.Stop());
960
                        _bAnimDistanceActive = false;
961
                    }
962
                }
963
                else
964
                {
965
                    if (_iDistanceJitter < 20)
966
                    { _iDistanceJitter++; }
967
                    if (_iDistanceJitter == 20)
968
                    {
969
                        if (stbDistanceWarnAnim != null && !_bAnimDistanceActive)
970
                        {
971
                            Dispatcher.Invoke(() => stbDistanceWarnAnim.Begin());
972
                            _bAnimDistanceActive = true;
973
                        }
974
                        if (_bVoiceDistancePlay && !_bVoiceDistanceActive)
975
                        {
2398 - 976
                            ThreadPool.QueueUserWorkItem(new WaitCallback(_mediaPlayer), "Voice\\Distance.mp3");
977
                            //Thread t = new Thread(()=>_mediaPlayer("Voice\\Distance.mp3"));
978
                            //t.Start();
2291 - 979
                            _bVoiceDistanceActive = true;
980
                        }
981
                        _iDistanceJitter++;
982
                    }
983
                }
2287 - 984
            }
985
        }
986
 
987
        private void checkBoxFollowCopter_Click(object sender, RoutedEventArgs e)
988
        {
989
            _bFollowCopter = (bool)checkBoxFollowCopter.IsChecked;
990
        }
991
 
992
        private void sliderMapZoom_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
993
        {
994
            if (MainMap.Zoom != sliderMapZoom.Value)
995
                MainMap.Zoom = (int)sliderMapZoom.Value;
996
        }
997
        #region Touch zooming hackattack ;) 
998
        /// <summary>
999
        /// inspired by http://www.codeproject.com/Articles/692286/WPF-and-multi-touch
1000
        /// </summary>
1001
        bool bFirstAccess = true;
1002
        double dDistance = 0;
1003
        int iZoom;
1004
        private void MainMap_StylusDown(object sender, StylusDownEventArgs e)
1005
        {
1006
            var id = e.StylusDevice.Id;
1007
            e.StylusDevice.Capture(MainMap);
1008
            if (iFirstStylusID == -1)
1009
            {
1010
                iFirstStylusID = id;
1011
            }
1012
            else
1013
            {
1014
 
1015
                MainMap.CanDragMap = false;
1016
            }
1017
        }
1018
        private void MainMap_StylusUp(object sender, StylusEventArgs e)
1019
        {
1020
            MainMap.ReleaseStylusCapture();
1021
            iFirstStylusID = -1;
1022
            bFirstAccess = true;
1023
            MainMap.CanDragMap = true;
1024
            iZoom = 0;
1025
        }
1026
        private void MainMap_StylusMove(object sender, StylusEventArgs e)
1027
        {
1028
            var id = e.StylusDevice.Id;
1029
            var tp = e.GetPosition(MainMap);
1030
 
1031
            // This is the first Stylus point; just record its position. 
1032
            if (id == iFirstStylusID)
1033
            {
1034
                pTouch1.X = tp.X;
1035
                pTouch1.Y = tp.Y;
1036
            }
1037
            else
1038
            if (iFirstStylusID > -1)
1039
            {
1040
                pTouch2.X = tp.X;
1041
                pTouch2.Y = tp.Y;
1042
                double distance = Point.Subtract(pTouch1, pTouch2).Length;
1043
                if (!bFirstAccess)
1044
                {
1045
                    if (distance > dDistance)
1046
                        iZoom++;
1047
                    else
1048
                        if (distance < dDistance)
1049
                        iZoom--;
1050
                }
1051
                if (iZoom > 30)
1052
                {
1053
                    iZoom = 0;
1054
                    Dispatcher.Invoke(() => sliderMapZoom.Value += 1);
1055
                }
1056
                if (iZoom < -30)
1057
                {
1058
                    iZoom = 0;
1059
                    Dispatcher.Invoke(() => sliderMapZoom.Value -= 1);
1060
                }
1061
                dDistance = distance;
1062
                bFirstAccess = false;
1063
            }
1064
        }
1065
        #endregion Touch zooming hackattack ;)
1066
 
1067
        #endregion GMap
1068
 
1069
        #region settings
1070
        private void cBoxTimingsDebug_DropDownClosed(object sender, EventArgs e)
1071
        {
1072
            if(! _bCBInit && cBoxTimingsDebug.SelectedIndex > -1)
1073
                debugInterval = (byte)(Convert.ToInt16(cBoxTimingsDebug.SelectedItem) / 10);
1074
        }
1075
        private void cBoxTimingsNav_DropDownClosed(object sender, EventArgs e)
1076
        {
1077
            if(! _bCBInit && cBoxTimingsNav.SelectedIndex > -1)
1078
                navctrlInterval = (byte)(Convert.ToInt16(cBoxTimingsNav.SelectedItem) / 10);
1079
        }
1080
        private void cBoxTimingsBl_DropDownClosed(object sender, EventArgs e)
1081
        {
1082
            if (!_bCBInit && cBoxTimingsBl.SelectedIndex > -1)
1083
                blctrlInterval = (byte)(Convert.ToInt16(cBoxTimingsBl.SelectedItem) / 10);
1084
        }
1085
        private void cBoxTimingsOSD_DropDownClosed(object sender, EventArgs e)
1086
        {
1087
            if (!_bCBInit && cBoxTimingsOSD.SelectedIndex > -1)
1088
                OSDInterval = (byte)(Convert.ToInt16(cBoxTimingsOSD.SelectedItem) / 10);
1089
        }
1090
        private void chkbAutoDbg_Click(object sender, RoutedEventArgs e)
1091
        {
1092
            if (!_init) _debugDataAutorefresh = (bool)chkbAutoDbg.IsChecked;
1093
        }
1094
        private void chkbAutoNav_Click(object sender, RoutedEventArgs e)
1095
        {
1096
            if (!_init) _navCtrlDataAutorefresh = (bool)chkbAutoNav.IsChecked;
1097
        }
1098
        private void chkbAutoBL_Click(object sender, RoutedEventArgs e)
1099
        {
1100
            if (!_init) _blctrlDataAutorefresh = (bool)chkbAutoBL.IsChecked;
1101
        }
1102
        private void chkbAutoOSD_Click(object sender, RoutedEventArgs e)
1103
        {
1104
            if (!_init) _OSDAutorefresh = (bool)chkbAutoOSD.IsChecked;
1105
        }
1106
 
1107
        private void cBoxLiPoCells_DropDownClosed(object sender, EventArgs e)
1108
        {
1109
            if (cBoxLiPoCells.SelectedIndex > -1)
1110
            {
1111
                _LipoCells = cBoxLiPoCells.SelectedIndex + 3;
1112
                _LipoMinMax();
1113
            }
1114
        }
1115
        void _LipoMinMax()
1116
        {
1117
            _dLipoVMax = (double)(_LipoCells) * 4.22;
1118
            _dLipoVMin = (double)_LipoCells * 3;
1119
            pbTopVoltage.Maximum = _dLipoVMax;
1120
            pbTopVoltage.Minimum = _dLipoVMin;
1121
            sliderThresholdVoltageWarn.Maximum = _dLipoVMax;
1122
            sliderThresholdVoltageWarn.Minimum = _dLipoVMin;
1123
        }
1124
        private void cBoxMotors_DropDownClosed(object sender, EventArgs e)
1125
        {
1126
            if (cBoxMotors.SelectedIndex > -1)
1127
            {
1128
                _iMotors = cBoxMotors.SelectedIndex + 3;
1129
                Dispatcher.Invoke(() =>
1130
                {
1131
                    dgvMotors1.Height = (272 / 12.6) * (_iMotors + 1);  //272 / 12.6 --> Workaround, cause the headerheight = NaN...?
1132
                    GridMotors.Height = dgvMotors1.Height + 10;
1133
                });
1134
            }
1135
        }
1136
        void _setMotorGridSize()
1137
        {
1138
            if (dgvMotors1.Columns.Count > 2)
1139
            {
1140
                dgvMotors1.Columns[0].Width = 24;
1141
                dgvMotors1.Columns[1].Width = 50;
1142
                dgvMotors1.Columns[2].Width = 50;
1143
                dgvMotors1.Height = (272 / 12.6) * (_iMotors + 1);
1144
                GridMotors.Height = dgvMotors1.Height + 10;
1145
            }
1146
 
1147
        }
1148
        #endregion settings
1149
 
1150
        #region functions  
1151
 
1152
        #region logging      
1153
        /// <summary> Log data to the terminal window. </summary>
1154
        /// <param name="msgtype"> The type of message to be written. </param>
1155
        /// <param name="msg"> The string containing the message to be shown. </param>
1156
        private void Log(LogMsgType msgtype, string msg)
1157
        {
1158
            Dispatcher.Invoke(() =>
1159
            {
1160
               // rtfTerminal.CaretPosition = rtfTerminal.CaretPosition.DocumentEnd;
1161
               // rtfTerminal.Foreground = new SolidColorBrush(LogMsgTypeColor[(int)msgtype]);
1162
//                rtfTerminal.AppendText(msg + "\r");
1163
                TextRange tr = new TextRange(rtfTerminal.Document.ContentEnd,rtfTerminal.Document.ContentEnd);
1164
                tr.Text = msg;
1165
                tr.ApplyPropertyValue(TextElement.ForegroundProperty, new SolidColorBrush(LogMsgTypeColor[(int)msgtype]));
1166
                rtfTerminal.AppendText("\r");
1167
                rtfTerminal.ScrollToEnd();
1168
            });
1169
        }
2381 - 1170
        private void ErrorLog(LogMsgType msgtype, string msg , string linkURL, string linkName)
2287 - 1171
        {
2381 - 1172
 
2287 - 1173
            Dispatcher.Invoke(() =>
1174
            {
2381 - 1175
                Paragraph para = new Paragraph();
1176
                para.Margin = new Thickness(0); // remove indent between paragraphs
1177
 
1178
                Hyperlink link = new Hyperlink();
1179
                if (linkURL != "" && linkName != "")
1180
                {
1181
                    link.IsEnabled = true;
1182
                    link.Inlines.Add(linkName);
1183
                    link.NavigateUri = new Uri(linkURL);
1184
                    link.RequestNavigate += (sender, args) => Process.Start(args.Uri.ToString());
1185
                }
1186
                //msg = DateTime.Now.ToLongTimeString() + msg;
1187
                para.Foreground = new SolidColorBrush(LogMsgTypeColor[(int)msgtype]);
1188
                Run r = new Run("[" + DateTime.Now.ToLongTimeString() + "]: ");
1189
                r.Foreground = new SolidColorBrush(Colors.Black);
1190
                para.Inlines.Add(r);
1191
                para.Inlines.Add(msg);
1192
                para.Inlines.Add(link);
1193
                rtfError.Document.Blocks.Add(para);
1194
                //TextRange tr = new TextRange(rtfError.Document.ContentEnd, rtfError.Document.ContentEnd);
1195
                //tr.Text = msg + link;
1196
                //tr.ApplyPropertyValue(TextElement.ForegroundProperty, new SolidColorBrush(LogMsgTypeColor[(int)msgtype]));
1197
                //rtfError.AppendText("\r");
2287 - 1198
                rtfError.ScrollToEnd();
1199
 
2381 - 1200
                //_bErrorLog = true;
2287 - 1201
            });
1202
        }
1203
        /// <summary>
1204
        /// Clear the line in the  errorlog window 
1205
        /// containing the error string when error has ceased
1206
        /// </summary>
1207
        /// <param name="s">substring of errrormessage</param>
1208
        void _clearErrorLog(string s)
1209
        {
1210
            Dispatcher.Invoke((Action)(() =>
1211
            {
1212
                TextRange searchRange = new TextRange(rtfError.Document.ContentStart, rtfError.Document.ContentEnd);
1213
                TextRange foundRange = FindTextInRange(searchRange, s);
1214
 
1215
                int iStart = searchRange.Text.IndexOf(s, StringComparison.OrdinalIgnoreCase);
1216
 
1217
 
1218
                if (iStart > -1)
1219
                {
1220
                    int iLength = 0;
1221
                    int iEnd = searchRange.Text.IndexOf('\r', iStart);
1222
                    if (iEnd > 0)
1223
                    {
1224
                        iLength = iEnd + 1;
1225
                        int iHttp = searchRange.Text.IndexOf("http", iEnd);
1226
                        if (iHttp == iLength)
1227
                        {
1228
                            int iEnd2 = searchRange.Text.IndexOf('\r', iLength);
1229
                            if (iEnd2 > iLength)
1230
                            {
1231
                                iLength = iEnd2 + 1;
1232
                              //  TextRange result = new TextRange(rtfError.Document.ContentStart.GetPositionAtOffset(iStart), GetTextPositionAtOffset(rtfError.Document.ContentStart.GetPositionAtOffset(iStart), iLength));
1233
 
1234
                                rtfError.Selection.Select(rtfError.Document.ContentStart.GetPositionAtOffset(iStart), GetTextPositionAtOffset(rtfError.Document.ContentStart.GetPositionAtOffset(iStart), iLength));
1235
                                rtfError.Selection.Text = string.Empty;
1236
                                if (rtfError.Document.ContentEnd.GetTextRunLength(LogicalDirection.Backward) < 2) _bErrorLog = false;
1237
                            }
1238
 
1239
                        }
1240
                        else
1241
                        {
1242
                            rtfError.Selection.Select(rtfError.Document.ContentStart.GetPositionAtOffset(iStart), GetTextPositionAtOffset(rtfError.Document.ContentStart.GetPositionAtOffset(iStart), iLength));
1243
                            rtfError.Selection.Text = string.Empty;
1244
                            if (rtfError.Document.ContentEnd.GetTextRunLength(LogicalDirection.Backward) < 2) _bErrorLog = false;
1245
                        }
1246
                    }
1247
                }
1248
            }));
1249
 
1250
        }
1251
        public TextRange FindTextInRange(TextRange searchRange, string searchText)
1252
        {
1253
            int offset = searchRange.Text.IndexOf(searchText, StringComparison.OrdinalIgnoreCase);
1254
            if (offset < 0)
1255
                return null;  // Not found
1256
 
1257
            var start = GetTextPositionAtOffset(searchRange.Start, offset);
1258
            TextRange result = new TextRange(start, GetTextPositionAtOffset(start, searchText.Length));
1259
 
1260
            return result;
1261
        }
1262
        TextPointer GetTextPositionAtOffset(TextPointer position, int characterCount)
1263
        {
1264
            while (position != null)
1265
            {
1266
                if (position.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.Text)
1267
                {
1268
                    int count = position.GetTextRunLength(LogicalDirection.Forward);
1269
                    if (characterCount <= count)
1270
                    {
1271
                        return position.GetPositionAtOffset(characterCount);
1272
                    }
1273
 
1274
                    characterCount -= count;
1275
                }
1276
 
1277
                TextPointer nextContextPosition = position.GetNextContextPosition(LogicalDirection.Forward);
1278
                if (nextContextPosition == null)
1279
                    return position;
1280
 
1281
                position = nextContextPosition;
1282
            }
1283
 
1284
            return position;
1285
        }
1286
        #endregion logging
1287
 
1288
        #region processing received data
1289
 
1290
        private void processMessage(byte[] message)
1291
        {
1292
            if (message.Length > 0)
1293
            {
1294
                _iLifeCounter++;
1295
                //Log(LogMsgType.Incoming, BitConverter.ToString(message));
1296
                //Log(LogMsgType.Incoming, message.Length.ToString());
1297
                string s = new string(ASCIIEncoding.ASCII.GetChars(message, 0, message.Length));
1298
                char cmdID;
1299
                byte adr;
1300
                byte[] data;
1301
                byte[] tmp = null;
1302
                if (message[0] != '#')
1303
                {
1304
                    int iFound = -1;
1305
                    for (int i = 0; i < message.Length; i++)   //Sometimes the FC/NC sends strings without termination (like WP messages)
1306
                    {                                   //so this is a workaround to not spam the log box
1307
                        if (message[i] == 35)
1308
                        {
1309
                            iFound = i;
1310
                            break;
1311
                        }
1312
                    }
1313
                    if (iFound > 0)
1314
                    {
1315
                        s = new string(ASCIIEncoding.ASCII.GetChars(message, 0, iFound));
1316
                        tmp = new byte[message.Length - iFound];
1317
                        Buffer.BlockCopy(message, iFound, tmp, 0, message.Length - iFound);
1318
                    }
1319
                    s = s.Trim('\0', '\n', '\r');
1320
                    if (s.Length > 0)
1321
                        Log(LogMsgType.Normal, s);
1322
                    if (tmp != null)
1323
                    {
1324
                        s = new string(ASCIIEncoding.ASCII.GetChars(tmp, 0, tmp.Length));
1325
                        processMessage(tmp);
1326
                    }
1327
                }
1328
                //Debug.Print(s);
1329
                else
1330
                {
1331
                    FlightControllerMessage.ParseMessage(message, out cmdID, out adr, out data);
1332
 
1333
                    if (adr == 255) { crcError++; }
1334
                    else crcError = 0;
1335
                    Dispatcher.Invoke(() => tbCrc.Text = crcError.ToString());
1336
                    //display the active controller (FC / NC) 
1337
                    if (adr > 0 && adr < 3 && adr != _iCtrlAct) //adr < 3: temporary workaround cause when I've connected the FC alone it always switches between mk3mag & FC every second...???
1338
                    {
1339
                        _iCtrlAct = adr;
1340
                        switch (adr)
1341
                        {
1342
                            case 1:
1343
                                Dispatcher.Invoke(() => tbCtrl.Text = "FC");
2381 - 1344
                               // Dispatcher.Invoke(() => buttonSwitchNC.Visibility = Visibility.Visible);
1345
                               // Dispatcher.Invoke(() => labelSwitchToNavi.Visibility = Visibility.Visible);
2287 - 1346
                              //  _setFieldsNA(); //display fields NA for FC 
1347
                                break;
1348
                            case 2:
1349
                                Dispatcher.Invoke(() => tbCtrl.Text = "NC");
1350
                                //Dispatcher.Invoke(() => buttonSwitchNC.Visibility = Visibility.Hidden);
1351
                                //Dispatcher.Invoke(() => labelSwitchToNavi.Visibility = Visibility.Hidden);
1352
                                break;
1353
                            //case 3:
1354
                            //    lblCtrl.Invoke((Action)(() => lblCtrl.Text = "MK3MAG"));
1355
                            //    break;
1356
                            //case 4:
1357
                            //    lblCtrl.Invoke((Action)(() => lblCtrl.Text = "BL-CTRL"));
1358
                            //    break;
1359
                            default:
1360
                                Dispatcher.Invoke(() => tbCtrl.Text = "NA");
1361
                                break;
1362
                        }
1363
                       // _loadLabelNames();
1364
                    }
1365
                    // else
1366
                    //     Debug.Print("Address == 0?");
1367
 
1368
                    if (data != null && data.Length > 0)
1369
                    {
1370
                        s = new string(ASCIIEncoding.ASCII.GetChars(data, 1, data.Length - 1));
1371
                        s = s.Trim('\0', '\n');
1372
 
1373
                        switch (cmdID)
1374
                        {
1375
                            //case 'A': //Label names
1376
                            //    _processLabelNames(s);
1377
                            //    break;
1378
 
1379
                            case 'D': //Debug data
1380
                                _processDebugVals(adr, data);
1381
                                break;
1382
 
1383
                            case 'V': //Version
1384
                                _processVersion(adr, data);
1385
                                break;
1386
 
1387
                            case 'K'://BL-CTRL data
1388
                                _processBLCtrl(data);
1389
                                break;
1390
 
1391
                            case 'O': //NC Data
1392
                                _processNCData(data);
1393
                                break;
1394
 
2381 - 1395
                            //case 'E': //NC error-string
1396
                            //    ErrorLog(LogMsgType.Error, "NC Error: " + s);
1397
                            //    break;
2287 - 1398
 
1399
                            case 'L': //OSD Menue (called by pagenumber)
1400
                                _processOSDSingle(data);
1401
                                break;
1402
 
1403
                            case 'H': //OSD Menue (with autoupdate - called by Key)
1404
                                _processOSDAuto(data);
1405
                                break;
1406
 
1407
                            case 'X': //Waypoint data
1408
                                _processWPData(data);
1409
                                break;
1410
 
2313 - 1411
                            case 'W': //return new Waypoint items count after sending waypoint to copter
1412
                                _iWPCount = data[0];
1413
                                break;
2287 - 1414
                                //default:
1415
                                //    Log(LogMsgType.Incoming, "cmd: " + cmdID.ToString());
1416
                                //    Log(LogMsgType.Incoming, BitConverter.ToString(data));
1417
                                //    break;
1418
                        }
1419
                    }
1420
                    //else
1421
                    //{
1422
                    //    Log(LogMsgType.Incoming, "cmd: " + cmdID.ToString());
1423
                    //    Log(LogMsgType.Incoming, BitConverter.ToString(data));
1424
                    //}
1425
                }
1426
            }
1427
        }
1428
        /// <summary>
1429
        /// Analog label names 'A'
1430
        /// each label name is returned as a single string 
1431
        /// and added to string array sAnalogLabel[]
1432
        /// and the datatable dtAnalog
1433
        /// </summary>
1434
        /// <param name="s">the label name</param>
1435
        void _processLabelNames(string s)
1436
        {
1437
            //if (iLableIndex < 32)
1438
            //{
1439
            //    sAnalogLabel[iLableIndex] = s;
1440
            //    if (dtAnalog.Rows.Count < 32)
1441
            //        dtAnalog.Rows.Add(s, "");
1442
            //    else
1443
            //        dtAnalog.Rows[iLableIndex].SetField(0, s);
1444
 
1445
            //  //  _getAnalogLabels(iLableIndex + 1);
1446
            //}
1447
            //Debug.Print(s);
1448
        }
1449
        /// <summary>
1450
        /// Debug values 'D'
1451
        /// </summary>
1452
        /// <param name="adr">adress of the active controller (1-FC, 2-NC)</param>
1453
        /// <param name="data">the received byte array to process</param>
1454
        void _processDebugVals(byte adr, byte[] data)
1455
        {
1456
            if (data.Length == 66)
1457
            {
2324 - 1458
 
2287 - 1459
                double v;
1460
                int index = 0;
1461
                Int16 i16 = 0;
1462
                double dTemp = 0;
1463
                for (int i = 2; i < 66; i += 2)
1464
                {
1465
                    i16 = data[i + 1];
1466
                    i16 = (Int16)(i16 << 8);
1467
                    iAnalogData[index] = data[i] + i16;
1468
                    sAnalogData[index] = (data[i] + i16).ToString();
1469
                   // dtAnalog.Rows[index].SetField(1, sAnalogData[index]);
1470
 
1471
                    if (adr == 2) //NC
1472
                    {
1473
                        switch (index)
1474
                        {
1475
                            case 0: //pitch (German: nick)
1476
                                Dispatcher.Invoke(() => ArtHor.Pitch = ((double)iAnalogData[index] / (double)10));
1477
                                Dispatcher.Invoke((Action)(() => tbPitch.Text = ((double)iAnalogData[index] / (double)10).ToString("0.0°")));
1478
                                break;
1479
                            case 1: //roll
1480
                                Dispatcher.Invoke(() => ArtHor.Roll = ((double)iAnalogData[index] / (double)10));
1481
                                Dispatcher.Invoke((Action)(() => tbRoll.Text = ((double)iAnalogData[index] / (double)10).ToString("0.0°")));
1482
                                break;
1483
                            case 4: //altitude
1484
                                Dispatcher.Invoke(() => tbAlt.Text = ((double)iAnalogData[index] / (double)10).ToString("0.0 m"));
1485
                                Dispatcher.Invoke(() => tbTopHeight.Text = ((double)iAnalogData[index] / (double)10).ToString("0.0 m"));
2324 - 1486
                                Dispatcher.Invoke(() => { drGPX[3] = (double)iAnalogData[index] / (double)10; });
2287 - 1487
                                break;
1488
                            case 7: //Voltage
1489
                                v = (double)iAnalogData[index] / (double)10;
1490
                                Dispatcher.Invoke(() => tbVolt.Text = v.ToString("0.0 V"));
1491
                                Dispatcher.Invoke(() => tbTopVoltage.Text = v.ToString("0.0 V"));
1492
                                Dispatcher.Invoke(() => pbTopVoltage.Value = v);
1493
                                if (v - _dLipoVMin < 1 | v < _dThresholdVoltageWarn)
1494
                                {
1495
                                    if (v == _dVoltLast)
1496
                                        if(_iVoltJitter < 20) _iVoltJitter++;
1497
                                    else
1498
                                    {
1499
                                        _iVoltJitter = 0;
1500
                                        _dVoltLast = v;
1501
                                    }
1502
                                    if (_iVoltJitter == 20)
1503
                                    {
1504
                                        Dispatcher.Invoke(() => pbTopVoltage.Foreground = Brushes.Orange);
1505
 
1506
                                        if (v - _dLipoVMin < 1 | v < _dThresholdVoltageCrit)
1507
                                        {
1508
                                            Dispatcher.Invoke(() => pbTopVoltage.Foreground = Brushes.Red);
1509
                                            if (stbVoltageCritAnim != null && !_bCritAnimVoltActive)
1510
                                            {
1511
                                                Dispatcher.Invoke(() => stbVoltageCritAnim.Begin());
1512
                                                _bCritAnimVoltActive = true;
1513
                                            }
1514
                                            if (_bVoiceVoltPlay && !_bCritVoiceVoltActive)
1515
                                            {
2398 - 1516
                                                ThreadPool.QueueUserWorkItem(new WaitCallback(_mediaPlayer), "Voice\\CriticalBattery.mp3");
1517
                                                //Thread t = new Thread(() => _mediaPlayer("Voice\\CriticalBattery.mp3"));
1518
                                                //t.Start();
2287 - 1519
                                                _bCritVoiceVoltActive = true;
1520
                                            }
1521
                                        }
1522
                                        else
1523
                                        {
1524
                                            if (stbVoltageCritAnim != null && _bCritAnimVoltActive)
1525
                                            {
1526
                                                Dispatcher.Invoke(() => stbVoltageCritAnim.Stop());
1527
                                                _bCritAnimVoltActive = false;
1528
                                            }
1529
                                            _bCritVoiceVoltActive = false;
1530
 
2291 - 1531
                                            if (_bVoiceVoltPlay && !_bWarnVoiceVoltActive)
2287 - 1532
                                            {
2398 - 1533
                                                ThreadPool.QueueUserWorkItem(new WaitCallback(_mediaPlayer), "Voice\\LowBattery.mp3");
1534
                                                //Thread t = new Thread(() => _mediaPlayer("Voice\\LowBattery.mp3"));
1535
                                                //t.Start();
2291 - 1536
                                                _bWarnVoiceVoltActive = true;
2287 - 1537
                                            }
1538
                                        }
1539
                                    }
1540
                                }
1541
                                else
1542
                                {
1543
                                    Dispatcher.Invoke(() => pbTopVoltage.Foreground = new SolidColorBrush(Color.FromArgb(255, 107, 195, 123)));
1544
                                    if (stbVoltageCritAnim != null && _bCritAnimVoltActive)
1545
                                    {
1546
                                        Dispatcher.Invoke(() => stbVoltageCritAnim.Stop());
1547
                                        _bCritAnimVoltActive = false;
1548
                                    }
1549
                                    _bCritVoiceVoltActive = false;
2291 - 1550
                                    _bWarnVoiceVoltActive = false;
2287 - 1551
                                    _iVoltJitter = 0;
1552
                                }
1553
                                break;
1554
                            case 8: // Current
1555
                                Dispatcher.Invoke(() => tbCur.Text = ((double)iAnalogData[index] / (double)10).ToString("0.0 A"));
1556
                                Dispatcher.Invoke(() => tbTopCurrent.Text = ((double)iAnalogData[index] / (double)10).ToString("0.0 A"));
1557
                                break;
1558
                            case 10: //heading
2291 - 1559
                                Dispatcher.Invoke((Action)(() => tbHeading.Text = sAnalogData[index] + "°"));
2399 - 1560
                                if (!_Simulate) //use NavData for simulation
1561
                                {
1562
                                    Dispatcher.Invoke(() => ArtHor.rotate = iAnalogData[index]);
1563
                                    Dispatcher.Invoke(() => ((CustomMarkerCopter)(copter.Shape)).rotate = iAnalogData[index]);
1564
                                }
2287 - 1565
                                break;
1566
                            case 12: // SPI error
2291 - 1567
                                Dispatcher.Invoke((Action)(() => tbSPI.Text = sAnalogData[index]));
2287 - 1568
                                break;
1569
                            case 14: //i2c error
2291 - 1570
                                Dispatcher.Invoke((Action)(() => tbI2C.Text = sAnalogData[index]));
2287 - 1571
                                break;
1572
                            case 20: //Earthmagnet field
2291 - 1573
                                Dispatcher.Invoke((Action)(() => tbMagF.Text = sAnalogData[index] + "%"));
1574
                                Dispatcher.Invoke((Action)(() => tbTopEarthMag.Text = sAnalogData[index] + "%"));
1575
 
1576
                                if (Math.Abs(100 - iAnalogData[index]) < _iThresholdMagField)
1577
                                {
1578
                                    Dispatcher.Invoke(() => imageEarthMag.Source = new BitmapImage(new Uri("Images/EarthMag.png", UriKind.Relative)));
1579
                                    _iMagneticFieldJitter = 0; _bVoiceMagneticFieldActive = false;
1580
                                    if (stbMagneticFieldAnim != null && _bAnimMagneticFieldActive)
1581
                                    {
1582
                                        Dispatcher.Invoke(() => stbMagneticFieldAnim.Stop());
1583
                                        _bAnimMagneticFieldActive = false;
1584
                                    }
1585
                                }
1586
                                else
1587
                                {
1588
                                    Dispatcher.Invoke(() => imageEarthMag.Source = new BitmapImage(new Uri("Images/EarthMag_R.png", UriKind.Relative)));
1589
                                    if(_iMagneticFieldLast >= Math.Abs(100 - iAnalogData[index]))
1590
                                    {
1591
                                        if (_iMagneticFieldJitter < 20)
1592
                                            _iMagneticFieldJitter++;
1593
                                    }
1594
                                    else
1595
                                    {
1596
                                        _iMagneticFieldJitter = 0;
1597
                                        _iMagneticFieldLast = Math.Abs(100 - iAnalogData[index]);
1598
                                    }
1599
                                    if(_iMagneticFieldJitter == 20)
1600
                                    {
1601
                                        if (stbMagneticFieldAnim != null && !_bAnimMagneticFieldActive)
1602
                                        {
1603
                                            Dispatcher.Invoke(() => stbMagneticFieldAnim.Begin());
1604
                                            _bAnimMagneticFieldActive = true;
1605
                                        }
1606
                                        if (_bVoiceMagneticFieldPlay && !_bVoiceMagneticFieldActive)
1607
                                        {
2398 - 1608
                                            ThreadPool.QueueUserWorkItem(new WaitCallback(_mediaPlayer), "Voice\\MagneticField.mp3");
1609
                                            //Thread t = new Thread(() => _mediaPlayer("Voice\\MagneticField.mp3"));
1610
                                            //t.Start();
2291 - 1611
                                            _bVoiceMagneticFieldActive = true;
1612
                                        }
1613
                                    }
1614
                                }
2287 - 1615
                                break;
1616
                            case 21: //GroundSpeed
1617
                                     Dispatcher.Invoke((Action)(() => tbSpeed.Text = ((double)iAnalogData[index] / (double)100).ToString("0.00 m/s")));
2399 - 1618
                                    if (!_Simulate)
1619
                                        Dispatcher.Invoke((Action)(() => tbTopSpeed.Text = ((double)iAnalogData[index] / (double)100).ToString("0.00 m/s")));
2287 - 1620
                                break;
2291 - 1621
 
1622
                            ///**********   needs testing --> not sure what position this is  ***************
2287 - 1623
                            case 28: //Distance East from saved home position -> calculate distance with distance N + height
1624
                                    dTemp = Math.Pow((double)iAnalogData[index], 2) + Math.Pow((double)iAnalogData[index - 1], 2);
1625
                                    dTemp = Math.Sqrt(dTemp) / (double)10; //'flat' distance from HP with N/E
1626
                                                                           //  lblNCDist.Invoke((Action)(() => lblNCDist.Text = dTemp.ToString("0.00")));
1627
                                    dTemp = Math.Pow(dTemp, 2) + Math.Pow(((double)iAnalogData[4] / (double)10), 2); //adding 'height' into calculation
1628
                                    dTemp = Math.Sqrt(dTemp) / (double)10;
1629
                               //     Dispatcher.Invoke((Action)(() => tbTopDistanceHP.Text = dTemp.ToString("0.0 m")));
1630
                                    Dispatcher.Invoke((Action)(() => tbHP1.Text = dTemp.ToString("0.0 m")));
1631
                                break;
2291 - 1632
 
2287 - 1633
                            case 31: //Sats used
1634
                                     Dispatcher.Invoke((Action)(() => tbSats.Text = sAnalogData[index]));
1635
                                    // Dispatcher.Invoke((Action)(() => tbTopSats.Text = sAnalogData[index]));                                   
1636
                                break;
1637
                        }
1638
                    }
1639
                    index++;
1640
                }
1641
            }
1642
            else
1643
                Debug.Print("wrong data-length (66): " + data.Length.ToString());
1644
        }
1645
        /// <summary>
1646
        /// Version string 'V'
1647
        /// </summary>
1648
        /// <param name="adr">adress of the active controller (1-FC, 2-NC)</param>
1649
        /// <param name="data">the received byte array to process</param>
1650
        void _processVersion(byte adr, byte[] data)
1651
        {
1652
            if (data.Length == 12)
1653
            {
1654
                if (!check_HWError)
1655
                {
1656
                    string[] sVersionStruct = new string[10] { "SWMajor: ", "SWMinor: ", "ProtoMajor: ", "LabelTextCRC: ", "SWPatch: ", "HardwareError 1: ", "HardwareError 2: ", "HWMajor: ", "BL_Firmware: ", "Flags: " };
1657
                    string sVersion = "";
1658
                    //sbyte[] signed = Array.ConvertAll(data, b => unchecked((sbyte)b));
1659
                    Log(LogMsgType.Warning, (adr == 1 ? "FC-" : "NC-") + "Version: ");
1660
                    sVersion = "HW V" + (data[7] / 10).ToString() + "." + (data[7] % 10).ToString();
1661
                    Log(LogMsgType.Incoming, sVersion);
1662
                    sVersion = "SW V" + (data[0]).ToString() + "." + (data[1]).ToString() + ((char)(data[4] + 'a')).ToString();
1663
                    Log(LogMsgType.Incoming, sVersion);
1664
                    Log(LogMsgType.Incoming, "BL-Firmware: V" + (data[8] / 100).ToString() + "." + (data[8] % 100).ToString());
1665
                }
1666
                if (data[5] > 0) //error0 
1667
                {
1668
                    if (adr == 1)
2381 - 1669
                        ErrorLog(LogMsgType.Error, " FC - HW-Error " + data[5].ToString() + ": " + ((FC_HWError0)data[5]).ToString(),"","");
2287 - 1670
                    if (adr == 2)
2381 - 1671
                        ErrorLog(LogMsgType.Error, " NC - HW-Error " + data[5].ToString() + ": " + ((NC_HWError0)data[5]).ToString(),"","");
2287 - 1672
                }
1673
                if (data[6] > 0) //error1 
1674
                {
1675
                    if (adr == 1)
2381 - 1676
                        ErrorLog(LogMsgType.Error, " FC - HW-Error " + data[6].ToString() + ": " + ((FC_HWError1)data[6]).ToString(),"","");
2287 - 1677
                    if (adr == 2)
2381 - 1678
                        ErrorLog(LogMsgType.Error, " NC - Unknown HW-ERROR: " + data[6].ToString(),"",""); //@moment NC has only one error field
2287 - 1679
                }
2381 - 1680
                //if ((data[5] + data[6] == 0) && _bErrorLog)
1681
                //    _clearErrorLog(adr == 1 ? "FC - HW-Error" : "NC - HW-Error");
2287 - 1682
 
1683
            }
1684
            check_HWError = false;
1685
        }
1686
        /// <summary>
1687
        /// BL-Ctrl data 'K'
1688
        /// for FC you have to use a customized firmware
1689
        /// </summary>
1690
        /// <param name="data">the received byte array to process</param>
1691
        void _processBLCtrl(byte[] data)
1692
        {
1693
            if (data.Length % 6 == 0) //data.Length up to 96 (16 motors x 6 byte data) --> new datastruct in FC -> not standard!
1694
            {
1695
                bool bAvailable = false;
1696
                for (int i = 0; i < data.Length && data[i] < _iMotors; i += 6) // data[i] < _iMotors -- only show set number of motors (12 max @ moment)
1697
                {
1698
 
1699
                    if ((data[i + 4] & 128) == 128) //Status bit at pos 7 = 128 dec -- if true, motor is available
1700
                        bAvailable = true;
1701
                    else
1702
                        bAvailable = false;
1703
 
1704
                    if (data[i] < _iMotors)
1705
                    {
1706
                        if (bAvailable)
1707
                        {
2315 - 1708
                            dtMotors.Rows[data[i]].SetField(1, ((double)data[i + 1] / (double)10).ToString("0.0 A"));
1709
                            dtMotors.Rows[data[i]].SetField(2, data[i + 2].ToString("0 °C"));
2287 - 1710
                        }
1711
                        else
1712
                        {
2315 - 1713
                            dtMotors.Rows[data[i]].SetField(1, "NA");
1714
                            dtMotors.Rows[data[i]].SetField(2, "NA");
2287 - 1715
                        }
1716
                    }
1717
                    //if (data[i] > 3 && data[i] < 8)
1718
                    //{
1719
                    //    if (bAvailable)
1720
                    //    {
1721
                    //        dtMotors2.Rows[data[i] - 4].SetField(1, ((double)data[i + 1] / (double)10).ToString("0.0 A"));
1722
                    //        dtMotors2.Rows[data[i] - 4].SetField(2, data[i + 2].ToString("0 °C"));
1723
                    //    }
1724
                    //    else
1725
                    //    {
1726
                    //        dtMotors2.Rows[data[i] - 4].SetField(1, "NA");
1727
                    //        dtMotors2.Rows[data[i] - 4].SetField(2, "NA");
1728
                    //    }
1729
                    //}
1730
                }
1731
            }
1732
        }
1733
        /// <summary>
1734
        /// Navi-Ctrl data 'O'
1735
        /// GPS-Position, capacatiy, flying time...
1736
        /// </summary>
1737
        /// <param name="data">the received byte array to process</param>
1738
        void _processNCData(byte[] data)
1739
        {
1740
            int i_32, i_16, iVal;
1741
            double d;
1742
            i_32 = data[4];
1743
            iVal = i_32 << 24;
1744
            i_32 = data[3];
1745
            iVal += i_32 << 16;
1746
            i_32 = data[2];
1747
            iVal += i_32 << 8;
1748
            iVal += data[1];
1749
            d = (double)iVal / Math.Pow(10, 7);
2324 - 1750
            Dispatcher.Invoke(() => { drGPX[2] = d; });
1751
 
2287 - 1752
            PointLatLng p = new PointLatLng();
1753
 
1754
            p.Lng = d;
1755
          //  lblNCGPSLong.Invoke((Action)(() => lblNCGPSLong.Text = d.ToString("0.######°"))); //GPS-Position: Longitude in decimal degree
1756
            //lblNCGPSLong.Invoke((Action)(() => lblNCGPSLong.Text = _convertDegree(d))); //GPS-Position: Longitude in minutes, seconds
1757
 
1758
            i_32 = data[8];
1759
            iVal = i_32 << 24;
1760
            i_32 = data[7];
1761
            iVal += i_32 << 16;
1762
            i_32 = data[6];
1763
            iVal += i_32 << 8;
1764
            iVal += data[5];
1765
            d = (double)iVal / Math.Pow(10, 7);
2324 - 1766
            Dispatcher.Invoke(() => { drGPX[1] = d; });
1767
            Dispatcher.Invoke(() => { drGPX[4] = DateTime.UtcNow.ToString("u", System.Globalization.CultureInfo.InvariantCulture); }); //2011-01-14T01:59:01Z });
2287 - 1768
            p.Lat = d;
2399 - 1769
 
2291 - 1770
            if (data[50] > 4)//if more than 4 sats in use . otherwise the map would jump and scroll insane at beginning
1771
            {
1772
                _bSatFix = true; _iSatsJitter = 0; _bVoiceSatFixActive = false;
2295 - 1773
                if(_bAutoHome && !_bFirstSatFix)
1774
                {
1775
                    if (_iFirstSatFix < 3)
1776
                        _iFirstSatFix++;
1777
                    else
1778
                    {
1779
                        _bFirstSatFix = true;
2347 - 1780
                        Dispatcher.Invoke(() => _setHomePos());
2295 - 1781
                    }
1782
                }
2291 - 1783
                if (stbSatFixLostAnim != null && _bAnimSatFixActive)
1784
                {
1785
                    Dispatcher.Invoke(() => stbSatFixLostAnim.Stop());
1786
                    _bAnimSatFixActive = false;
1787
                }
1788
                if (!_bFollowCopter)
1789
                {
1790
                    _setCopterData(p);
1791
                    if (!MainMap.ViewArea.Contains(p))
1792
                        Dispatcher.Invoke(() => MainMap.Position = p);
2287 - 1793
 
2291 - 1794
                }
1795
                else
2287 - 1796
                    Dispatcher.Invoke(() => MainMap.Position = p);
1797
            }
1798
            else
2291 - 1799
            {
1800
                if(_bSatFix)
1801
                {
1802
                    if (data[50] == _iSatsLast)
1803
                    {
1804
                        if (_iSatsJitter < 20) _iSatsJitter++;
1805
                    }
1806
                    else
1807
                    {
1808
                        _iSatsJitter = 0;
1809
                        _iSatsLast = data[50];
1810
                    }
2287 - 1811
 
2291 - 1812
                    if (_iSatsJitter == 20)
1813
                    {
1814
                        if (stbSatFixLostAnim != null && !_bAnimSatFixActive)
1815
                        {
1816
                            Dispatcher.Invoke(() => stbSatFixLostAnim.Begin());
1817
                            _bAnimSatFixActive = true;
1818
                        }
1819
                        if (_bVoiceSatFixPlay && !_bVoiceSatFixActive)
1820
                        {
2398 - 1821
                            ThreadPool.QueueUserWorkItem(new WaitCallback(_mediaPlayer), "Voice\\SatFixLost.mp3");
1822
                            //Thread th = new Thread(() => _mediaPlayer("Voice\\SatFixLost.mp3"));
1823
                            //th.Start();
2291 - 1824
                            _bVoiceSatFixActive = true;
1825
                        }
1826
 
1827
                        _bSatFix = false;
1828
                    }
1829
                }
1830
            }
1831
 
2399 - 1832
            //Distance to next WP
2287 - 1833
            i_16 = data[28];
1834
            i_16 = (Int16)(i_16 << 8);
1835
            iVal = data[27] + i_16;
2399 - 1836
            Dispatcher.Invoke((Action)(() => tbWP.Text = ((double)iVal / (double)10).ToString("0.0 m")));
1837
            Dispatcher.Invoke((Action)(() => lblWPRouteDistanceWP.Content = ((double)iVal / (double)10).ToString("0.0 m")));
2287 - 1838
 
1839
            i_16 = data[45];
1840
            i_16 = (Int16)(i_16 << 8);
1841
            iVal = data[44] + i_16;
1842
        //    Dispatcher.Invoke((Action)(() => tbTopDistanceHP.Text = ((double)iVal / (double)10).ToString("0.0 m"))); //Distance to HP set by GPS on
1843
            Dispatcher.Invoke((Action)(() => tbHP.Text = ((double)iVal / (double)10).ToString("0.0 m"))); //Distance to HP set by GPS on
1844
 
1845
            Dispatcher.Invoke((Action)(() => tbWPIndex.Text = data[48].ToString())); //Waypoint index
2355 - 1846
            Dispatcher.Invoke((Action)(() => lblWPIndexNC.Content = data[48].ToString()));
2399 - 1847
            if(data[48] > 0 && _wpIndex != data[48] -1 && wpList.Count >= data[48] -1)
2342 - 1848
            {
2347 - 1849
                _setActiveWP(data[48]-1);
2355 - 1850
                if((data[67] & 2) == 2)
1851
                    Dispatcher.Invoke(() => {
1852
                        DataGridRow row;
1853
                        if (_wpIndex > -1)
1854
                        {
1855
                            row = (DataGridRow)dgvWP.ItemContainerGenerator.ContainerFromIndex(_wpIndex);
1856
                            row.Background = new SolidColorBrush(Colors.Transparent);
1857
                            row.BorderBrush = new SolidColorBrush(Colors.Transparent);
1858
                            row.BorderThickness = new Thickness(0);
1859
                        }
1860
                        _wpIndex = data[48] - 1;
1861
                        row = (DataGridRow)dgvWP.ItemContainerGenerator.ContainerFromIndex(_wpIndex);
2366 - 1862
                        row.Background = new SolidColorBrush(Color.FromArgb(80, 0, 255, 100));
1863
                        row.BorderBrush = new SolidColorBrush(Colors.SpringGreen);
2355 - 1864
                        row.BorderThickness = new Thickness(2);
1865
                        dgvWP.UpdateLayout();
1866
                    });
2347 - 1867
                _wpIndex = data[48]-1;
2342 - 1868
            }
2347 - 1869
            else
1870
            {
1871
                if ((data[48] == 0 || wpList.Count == 0) & MainMap.Markers.Contains(wpActiveMarker))
2355 - 1872
                {
2347 - 1873
                    Dispatcher.Invoke(() => MainMap.Markers.Remove(wpActiveMarker));
2355 - 1874
                    Dispatcher.Invoke(() =>
1875
                    {
1876
                        DataGridRow row;
2368 - 1877
                        if (_wpIndex > -1 && data[48] == 0 && wpList.Count > _wpIndex)
2355 - 1878
                        {
1879
                            row = (DataGridRow)dgvWP.ItemContainerGenerator.ContainerFromIndex(_wpIndex);
1880
                            row.Background = new SolidColorBrush(Colors.Transparent);
1881
                            row.BorderBrush = new SolidColorBrush(Colors.Transparent);
1882
                            row.BorderThickness = new Thickness(0);
1883
                            _wpIndex = -1;
1884
                        }
1885
                    });
1886
 
1887
                }
2347 - 1888
            }
2342 - 1889
 
2287 - 1890
            Dispatcher.Invoke((Action)(() => tbWPCount.Text = data[49].ToString())); //Waypoints count
2355 - 1891
            Dispatcher.Invoke((Action)(() => lblWPCountNC.Content = data[49].ToString())); //Waypoints count
2340 - 1892
            _wpCount = data[49];
2287 - 1893
            Dispatcher.Invoke((Action)(() => tbTopSats.Text = data[50].ToString())); //Satellites
1894
 
1895
            //--------------- Capacity used ------------------------
1896
            i_16 = data[81];
1897
            i_16 = (Int16)(i_16 << 8);
1898
            iVal = data[80] + i_16;
1899
            Dispatcher.Invoke((Action)(() => tbCapacity.Text = iVal.ToString() + " mAh"));
1900
            Dispatcher.Invoke((Action)(() => tbTopCapacity.Text = iVal.ToString() + " mAh"));
1901
 
2398 - 1902
            //--------------- Ground speed ------------------------
1903
            i_16 = data[59];
1904
            i_16 = (Int16)(i_16 << 8);
1905
            iVal = data[58] + i_16;
2399 - 1906
            Dispatcher.Invoke((Action)(() => tbNCGrSpeed.Text = ((double)(iVal)/100).ToString("0.00 m/s")));
1907
            if(_Simulate)
1908
                Dispatcher.Invoke((Action)(() => tbTopSpeed.Text = ((double)(iVal)/100).ToString("0.00 m/s")));
2398 - 1909
 
1910
            //--------------- Heading north ------------------------
1911
            i_16 = data[61];
1912
            i_16 = (Int16)(i_16 << 8);
1913
            iVal = data[60] + i_16;
1914
            Dispatcher.Invoke((Action)(() => tbHeadingNorth.Text = iVal.ToString() + " °"));
1915
 
1916
            //--------------- Heading compass ------------------------
1917
            i_16 = data[63];
1918
            i_16 = (Int16)(i_16 << 8);
1919
            iVal = data[62] + i_16;
1920
            Dispatcher.Invoke((Action)(() => tbHeadingCompass.Text = iVal.ToString() + " °"));
2399 - 1921
            if (_Simulate)
1922
            {
1923
                Dispatcher.Invoke(() => ArtHor.rotate = iVal);
1924
                Dispatcher.Invoke(() => ((CustomMarkerCopter)(copter.Shape)).rotate = iVal);
1925
            }
2287 - 1926
            //--------------- Flying time ------------------------
1927
            i_16 = data[56];
1928
            i_16 = (Int16)(i_16 << 8);
1929
            iVal = data[55] + i_16;
1930
            TimeSpan t = TimeSpan.FromSeconds(iVal);
1931
            string Text = t.Hours.ToString("D2") + ":" + t.Minutes.ToString("D2") + ":" + t.Seconds.ToString("D2");
1932
            Dispatcher.Invoke((Action)(() => tbFTime.Text = Text.ToString()));
1933
            Dispatcher.Invoke((Action)(() => tbTopFTime.Text = Text.ToString()));
1934
 
1935
            //--------------- RC quality ------------------------
1936
            Dispatcher.Invoke((Action)(() => tbRCQ.Text = data[66].ToString()));
1937
            Dispatcher.Invoke((Action)(() => tbTopRC.Text = data[66].ToString()));
1938
 
2291 - 1939
            if(data[66] > _iThresholdRC)
1940
            {
1941
                _iRCLevelJitter = 0; _bVoiceRCLevelActive = false;
1942
                if (stbRCLevelAnim != null && _bAnimRCLevelActive)
1943
                {
1944
                    Dispatcher.Invoke(() => stbRCLevelAnim.Stop());
1945
                    _bAnimRCLevelActive = false;
1946
                }
1947
            }
1948
            else
1949
            {
1950
                if (_iRCLevelJitter < 20) _iRCLevelJitter++;
1951
                if (_iRCLevelJitter == 20)
1952
                {
1953
                    if (stbRCLevelAnim != null && !_bAnimRCLevelActive)
1954
                    {
1955
                        Dispatcher.Invoke(() => stbRCLevelAnim.Begin());
1956
                        _bAnimRCLevelActive = true;
1957
                    }
1958
                    if (_bVoiceRCLevelPlay && !_bVoiceRCLevelActive)
1959
                    {
2398 - 1960
                        ThreadPool.QueueUserWorkItem(new WaitCallback(_mediaPlayer), "Voice\\MagneticField.mp3");
1961
                        //Thread th = new Thread(() => _mediaPlayer("Voice\\RCLevel.mp3"));
1962
                        //th.Start();
2291 - 1963
                        _bVoiceRCLevelActive = true;
1964
                    }
1965
                        _iRCLevelJitter++;
1966
                }
1967
            }
1968
 
2399 - 1969
            //Target hold time
1970
            Dispatcher.Invoke((Action)(() => lblWPHoldTime.Content = data[73].ToString()+ " s"));
1971
 
2287 - 1972
            //--------------- NC Error ------------------------
1973
            Dispatcher.Invoke((Action)(() => tbNCErr.Text = data[69].ToString()));  //NC Errornumber
1974
            if (data[69] > 0)
1975
                _readNCError();
1976
            if (data[69] > 0 & data[69] < 44)
2381 - 1977
                ErrorLog(LogMsgType.Error," NC Error [" + data[69].ToString() + "]: ",NC_Error_Link[data[69]], NC_Error[data[69]]);
1978
            //else
1979
            //    if (_bErrorLog) _clearErrorLog("NC Error");
2287 - 1980
 
2298 - 1981
            //-------------FC / NC Status Flags
1982
            Dispatcher.Invoke((Action)(() => FC1_1.Background = ((data[67] & 1) ==1) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS_MOTOR_RUN                             0x01
1983
            Dispatcher.Invoke((Action)(() => FC1_2.Background = ((data[67] & 2) ==2) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS_FLY                                   0x02
1984
            Dispatcher.Invoke((Action)(() => FC1_3.Background = ((data[67] & 4) ==4) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS_CALIBRATE                             0x04
1985
            Dispatcher.Invoke((Action)(() => FC1_4.Background = ((data[67] & 8) ==8) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS_START                                 0x08
1986
            Dispatcher.Invoke((Action)(() => FC1_5.Background = ((data[67] & 16) ==16) ? new SolidColorBrush(Colors.LightCoral) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS_EMERGENCY_LANDING                      0x10
1987
            Dispatcher.Invoke((Action)(() => FC1_6.Background = ((data[67] & 32) ==32) ? new SolidColorBrush(Colors.LightCoral) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS_LOWBAT                         0x20
1988
 
1989
            Dispatcher.Invoke((Action)(() => FC2_1.Background = ((data[74] & 1) ==1) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS2_CAREFREE                             0x01
1990
            Dispatcher.Invoke((Action)(() => FC2_2.Background = ((data[74] & 2) ==2) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS2_ALTITUDE_CONTROL                     0x02
1991
            Dispatcher.Invoke((Action)(() => FC2_3.Background = ((data[74] & 4) ==4) ? new SolidColorBrush(Colors.LightCoral) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS2_RC_FAILSAVE_ACTIVE                      0x04
1992
            Dispatcher.Invoke((Action)(() => FC2_4.Background = ((data[74] & 8) ==8) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS2_OUT1_ACTIVE                          0x08
1993
            Dispatcher.Invoke((Action)(() => FC2_5.Background = ((data[74] & 16) ==16) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS2_OUT2_ACTIVE                        0x10
1994
            Dispatcher.Invoke((Action)(() => FC2_6.Background = ((data[74] & 32) ==32) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS2_WAIT_FOR_TAKEOFF                   0x20   // Motor Running, but still on the ground
1995
            Dispatcher.Invoke((Action)(() => FC2_7.Background = ((data[74] & 64) ==64) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS2_AUTO_STARTING                              0x40
1996
            Dispatcher.Invoke((Action)(() => FC2_8.Background = ((data[74] & 128) ==128) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS2_AUTO_LANDING                             0x80
1997
 
1998
            Dispatcher.Invoke((Action)(() => NC1_2.Background = ((data[68] & 2) == 2) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// NC_FLAG_PH                                     0x02
1999
            Dispatcher.Invoke((Action)(() => NC1_3.Background = ((data[68] & 4) == 4) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// NC_FLAG_CH                                     0x04
2000
            Dispatcher.Invoke((Action)(() => NC1_4.Background = ((data[68] & 8) == 8) ? new SolidColorBrush(Colors.LightCoral) : new SolidColorBrush(Colors.Transparent)));// NC_FLAG_RANGE_LIMIT                               0x08
2001
            Dispatcher.Invoke((Action)(() => NC1_5.Background = ((data[68] & 16) == 16) ? new SolidColorBrush(Colors.LightCoral) : new SolidColorBrush(Colors.Transparent)));// NC_FLAG_NOSERIALLINK                            0x10
2002
            Dispatcher.Invoke((Action)(() => NC1_6.Background = ((data[68] & 32) == 32) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// NC_FLAG_TARGET_REACHED                               0x20
2003
            Dispatcher.Invoke((Action)(() => NC1_7.Background = ((data[68] & 64) == 64) ? new SolidColorBrush(Colors.DodgerBlue) : new SolidColorBrush(Colors.Transparent)));// NC_FLAG_MANUAL_CONTROL                          0x40
2004
            Dispatcher.Invoke((Action)(() => NC1_8.Background = ((data[68] & 128) == 128) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// NC_FLAG_GPS_OK                                     0x80
2299 - 2005
 
2006
            //Sidebar StatusSymbols
2007
            Dispatcher.Invoke((Action)(() => tbSideBarStatusMotors.Background = ((data[67] & 1) ==1) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS_MOTOR_RUN                             0x01
2008
            Dispatcher.Invoke((Action)(() => tbSideBarStatusMotors.Foreground = ((data[67] & 1) ==1) ? new SolidColorBrush(Colors.White) : new SolidColorBrush(Color.FromArgb(255,211,210,210))));// FC_STATUS_MOTOR_RUN                                0x01
2009
            Dispatcher.Invoke((Action)(() => tbSideBarStatusMotors.BorderBrush = ((data[67] & 1) ==1) ? new SolidColorBrush(Colors.White) : new SolidColorBrush(Color.FromArgb(255, 211, 210, 210))));// FC_STATUS_MOTOR_RUN                            0x01
2010
 
2011
            Dispatcher.Invoke((Action)(() => tbSideBarStatusCF.Background = ((data[74] & 1) == 1) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS2_CAREFREE                                0x01
2012
            Dispatcher.Invoke((Action)(() => tbSideBarStatusCF.Foreground = ((data[74] & 1) == 1) ? new SolidColorBrush(Colors.White) : new SolidColorBrush(Color.FromArgb(255, 211, 210, 210))));// FC_STATUS2_CAREFREE                                0x01
2013
            Dispatcher.Invoke((Action)(() => tbSideBarStatusCF.BorderBrush = ((data[74] & 1) ==1) ? new SolidColorBrush(Colors.White) : new SolidColorBrush(Color.FromArgb(255, 211, 210, 210))));// FC_STATUS2_CAREFREE                                0x01
2014
 
2015
            Dispatcher.Invoke((Action)(() => tbSideBarStatusEmergencyLanding.Background = ((data[67] & 16) == 16) ? new SolidColorBrush(Colors.LightCoral) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS_EMERGENCY_LANDING                   0x10
2304 - 2016
            Dispatcher.Invoke((Action)(() => tbSideBarStatusEmergencyLanding.Foreground = ((data[67] & 16) == 16) ? new SolidColorBrush(Colors.White) : new SolidColorBrush(Color.FromArgb(255, 211, 210, 210))));// FC_STATUS_EMERGENCY_LANDING                0x10
2017
            Dispatcher.Invoke((Action)(() => tbSideBarStatusEmergencyLanding.BorderBrush = ((data[67] & 16) == 16) ? new SolidColorBrush(Colors.White) : new SolidColorBrush(Color.FromArgb(255, 211, 210, 210))));// FC_STATUS_EMERGENCY_LANDING               0x10
2299 - 2018
 
2019
            Dispatcher.Invoke((Action)(() => tbSideBarStatusAC.Background = ((data[74] & 2) ==2) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS2_ALTITUDE_CONTROL                         0x02
2020
            Dispatcher.Invoke((Action)(() => tbSideBarStatusAC.Foreground = ((data[74] & 2) ==2) ? new SolidColorBrush(Colors.White) : new SolidColorBrush(Color.FromArgb(255, 211, 210, 210))));// FC_STATUS2_ALTITUDE_CONTROL                         0x02
2021
            Dispatcher.Invoke((Action)(() => tbSideBarStatusAC.BorderBrush = ((data[74] & 2) ==2) ? new SolidColorBrush(Colors.White) : new SolidColorBrush(Color.FromArgb(255, 211, 210, 210))));// FC_STATUS2_ALTITUDE_CONTROL                        0x02
2022
 
2023
            Dispatcher.Invoke((Action)(() => tbSideBarStatusPH.Text = ((data[68] & 4) == 4) ? "CH" : "PH"));// NC_FLAG_PH 0x02 / NC_FLAG_CH 0x04
2304 - 2024
            Dispatcher.Invoke((Action)(() => tbSideBarStatusPH.Background = (((data[68] & 2) == 2)|((data[68] & 4) == 4)) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// NC_FLAG_PH 0x02 / NC_FLAG_CH 0x04
2025
            Dispatcher.Invoke((Action)(() => tbSideBarStatusPH.Foreground = (((data[68] & 2) == 2)|((data[68] & 4) == 4)) ? new SolidColorBrush(Colors.White) : new SolidColorBrush(Color.FromArgb(255, 211, 210, 210))));// NC_FLAG_PH 0x02 / NC_FLAG_CH 0x04
2026
            Dispatcher.Invoke((Action)(() => tbSideBarStatusPH.BorderBrush = (((data[68] & 2) == 2)|((data[68] & 4) == 4)) ? new SolidColorBrush(Colors.White) : new SolidColorBrush(Color.FromArgb(255, 211, 210, 210))));// NC_FLAG_PH 0x02 / NC_FLAG_CH 0x04
2299 - 2027
 
2324 - 2028
            _bAirborne = (data[67] & 2) == 2 ? true : false;
2287 - 2029
        }
2030
        /// <summary>
2031
        /// Navi-Ctrl WP data struct 'X'
2032
        /// called by index
2033
        /// </summary>
2034
        /// <param name="data">the received byte array to process</param>
2035
        void _processWPData(byte[] data)
2036
        {
2313 - 2037
            _iWPCount = data[0];
2287 - 2038
            _bGetWPCount = false;
2039
            if (data.Length >= 28)
2040
            {
2041
                Dispatcher.Invoke(() => lblWPIndex.Content = data[1].ToString());
2042
                Dispatcher.Invoke(() => lblWPCount.Content = data[0].ToString());
2043
                if (_bGetWP)
2044
                {
2045
                    if (data[1] == 1)
2315 - 2046
                    {
2333 - 2047
                        Dispatcher.Invoke(() =>
2048
                        {
2356 - 2049
                            wpList.Clear();
2050
                            _clearMapMarkers(typeof(CustomMarkerWP));
2051
                            if (mRouteWP != null)
2052
                                MainMap.Markers.Remove(mRouteWP);
2053
                            if (wpActiveMarker != null)
2054
                                MainMap.Markers.Remove(wpActiveMarker);
2055
                            lblWPRouteDistance.Content = "0 m";
2056
                            dtWaypoints.Rows.Clear();
2368 - 2057
                            _wpEdit = -1;_wpIndex = -1;
2318 - 2058
                        });
2315 - 2059
                    }
2287 - 2060
                    DataRow dr = dtWaypoints.NewRow();
2061
                    dr = Waypoints.toDataRow(data, dr);
2313 - 2062
                    dtWaypoints.Rows.Add(dr);
2363 - 2063
                    _createWP(new PointLatLng((double)dr[3], (double)dr[4]), (string)dr[2], (int)dr[1]);
2313 - 2064
                    Dispatcher.Invoke(() => dgvWP.Items.Refresh());
2065
                    Dispatcher.Invoke(() => _iWPIndex = data[1]);
2287 - 2066
                    if (data[1] == data[0])
2067
                    {
2068
                        _bGetWP = false;
2368 - 2069
                        _routeUpdate();
2287 - 2070
                    }
2071
 
2072
                }
2073
            }
2074
            else
2075
            {
2076
                Dispatcher.Invoke(() => lblWPIndex.Content = 0);
2077
                Dispatcher.Invoke(() => lblWPCount.Content = 0);
2078
            }
2079
        }
2080
        /// <summary>
2081
        /// OSD Menue 'L'
2082
        /// single page called by pagenumber
2083
        /// no autoupdate
2084
        /// </summary>
2085
        /// <param name="data">the received byte array to process</param>
2086
        void _processOSDSingle(byte[] data)
2087
        {
2088
            if (data.Length == 84)
2089
            {
2090
                string sMessage = "";
2091
                iOSDPage = data[0];
2092
                iOSDMax = data[1];
2093
                if (cbOSD.Items.Count != iOSDMax) _initOSDCB();
2094
                sMessage = new string(ASCIIEncoding.ASCII.GetChars(data, 2, data.Length - 4));
2095
                OSD(LogMsgType.Incoming, sMessage.Substring(0, 20)+ "\r", true);
2096
                OSD(LogMsgType.Incoming, sMessage.Substring(20, 20)+ "\r", false);
2097
                OSD(LogMsgType.Incoming, sMessage.Substring(40, 20)+ "\r", false);
2098
                OSD(LogMsgType.Incoming, sMessage.Substring(60, 20), false);
2099
                Dispatcher.Invoke(() => { cbOSD.SelectedValue = iOSDPage; });
2100
              //  lblOSDPageNr.Invoke((Action)(() => lblOSDPageNr.Text = iOSDPage.ToString("[0]")));
2101
 
2102
            }
2103
            //else
2104
            //    OSD(LogMsgType.Incoming, "Wrong length: " + data.Length + " (should be 84)");
2105
 
2106
        }
2107
        /// <summary>
2108
        /// OSD Menue 'H'
2109
        /// called by keys (0x01,0x02,0x03,0x04)
2110
        /// autoupdate
2111
        /// </summary>
2112
        /// <param name="data">the received byte array to process</param>
2113
        void _processOSDAuto(byte[] data)
2114
        {
2115
            if (data.Length == 81)
2116
            {
2117
                string sMessage = "";
2118
                sMessage = new string(ASCIIEncoding.ASCII.GetChars(data, 0, data.Length - 1));
2119
                OSD(LogMsgType.Incoming, sMessage.Substring(0, 20)+ "\r", true);
2120
                OSD(LogMsgType.Incoming, sMessage.Substring(20, 20)+ "\r", false);
2121
                OSD(LogMsgType.Incoming, sMessage.Substring(40, 20)+ "\r", false);
2122
                OSD(LogMsgType.Incoming, sMessage.Substring(60, 20), false);
2123
 
2124
            }
2125
            //else
2126
            //    OSD(LogMsgType.Incoming, "Wrong length: " + data.Length + " (should be 81)");
2127
        }
2128
 
2129
        #endregion processing received data
2130
 
2131
        #region controller messages
2132
        /// <summary> send message to controller to request data
2133
        /// for detailed info see http://wiki.mikrokopter.de/en/SerialProtocol/
2134
        /// </summary>
2135
        /// <param name="CMDID"> the command ID </param>
2136
        /// <param name="address"> the address of the controller: 0-any, 1-FC, 2-NC </param>
2137
        private void _sendControllerMessage(char CMDID, byte address)
2138
        {
2139
            if (serialPortCtrl.Port.IsOpen)
2140
            {
2141
                Stream serialStream = serialPortCtrl.Port.BaseStream;
2142
                byte[] bytes = FlightControllerMessage.CreateMessage(CMDID, address);
2143
                serialStream.Write(bytes, 0, bytes.Length);
2144
 
2145
            }
2146
            else
2147
                Log(LogMsgType.Error, "NOT CONNECTED!");
2148
        }
2149
        /// <summary> send message to controller to request data
2150
        /// for detailed info see http://wiki.mikrokopter.de/en/SerialProtocol/
2151
        /// </summary>
2152
        /// <param name="CMDID"> the command ID </param>
2153
        /// <param name="address"> the address of the controller: 0-any, 1-FC, 2-NC </param>
2154
        /// <param name="data"> additional data for the request</param>
2155
        private void _sendControllerMessage(char CMDID, byte address, byte[] data)
2156
        {
2157
            if (serialPortCtrl.Port.IsOpen)
2158
            {
2159
                Stream serialStream = serialPortCtrl.Port.BaseStream;
2160
                byte[] bytes = FlightControllerMessage.CreateMessage(CMDID, address, data);
2161
                serialStream.Write(bytes, 0, bytes.Length);
2162
 
2163
            }
2164
            else
2165
                Log(LogMsgType.Error, "NOT CONNECTED!");
2166
        }
2167
 
2168
        /// <summary>
2169
        /// start/stop continous polling of controller values
2170
        /// </summary>
2171
        /// <param name="b">start/stop switch</param>
2172
        void _readCont(bool b)
2173
        {
2174
            bReadContinously = b;
2175
            if (bReadContinously)
2176
            {
2177
                if (_debugDataAutorefresh) { _readDebugData(true); Thread.Sleep(10); }
2178
                if (_blctrlDataAutorefresh) { _readBLCtrl(true); Thread.Sleep(10); }
2179
                if (_navCtrlDataAutorefresh && _iCtrlAct == 2) { _readNavData(true); Thread.Sleep(10); }
2180
                if (_OSDAutorefresh) { _OSDMenueAutoRefresh(); Thread.Sleep(10); }
2181
                // Dispatcher.Invoke((Action)(() => rctConnection.Fill = Brushes.LightGreen));
2182
                Dispatcher.Invoke(() => imageConn.Source = new BitmapImage(new Uri("Images/Data_G.png", UriKind.Relative)));
2183
            }
2184
            else
2185
            {
2186
                // Dispatcher.Invoke((Action)(() => rctConnection.Fill = Brushes.LightGray));
2187
                Dispatcher.Invoke(() => imageConn.Source = new BitmapImage(new Uri("Images/Data_W.png", UriKind.Relative)));
2188
                _bConnErr = false;
2189
            }
2190
            _iLifeCounter = 0;
2191
        }
2192
 
2193
        private void _getVersion()
2194
        {
2195
            _sendControllerMessage('v', 0);
2196
        }
2197
        /// <summary>
2198
        /// get FC version struct via NC
2199
        /// by sending '1' as data (not documented in wiki...)
2200
        /// returns HW error 255 (comment in uart1.c : tells the KopterTool that it is the FC-version)
2201
        /// </summary>
2202
        /// <param name="ctrl">controller number 1=FC</param> 
2203
        private void _getVersion(byte ctrl)
2204
        {
2205
            _sendControllerMessage('v', 0, new byte[1] { ctrl });
2206
        }
2207
        /// <summary>
2208
        /// Switch back to NC by sending the 'Magic Packet' 0x1B,0x1B,0x55,0xAA,0x00
2209
        /// </summary>
2210
        private void _switchToNC()
2211
        {
2212
            if (serialPortCtrl.Port.IsOpen)
2213
            {
2214
                Stream serialStream = serialPortCtrl.Port.BaseStream;
2215
                byte[] bytes = new byte[5] { 0x1B, 0x1B, 0x55, 0xAA, 0x00 };
2216
                serialStream.Write(bytes, 0, bytes.Length);
2217
 
2218
                Thread.Sleep(100);
2219
                _getVersion();
2220
                Thread.Sleep(100);
2221
               // _OSDMenue(0);
2222
            }
2223
            else
2224
                Log(LogMsgType.Error, "NOT CONNECTED!");
2225
        }
2226
        /// <summary>
2227
        /// switch to FC
2228
        /// </summary>
2229
        private void _switchToFC()
2230
        {
2231
            _sendControllerMessage('u', 2, new byte[1] { (byte)0 });
2232
            Thread.Sleep(100);
2233
            _getVersion();
2234
            Thread.Sleep(100);
2235
          //  _OSDMenue(0);
2236
        }
2237
        /// <summary>
2238
        /// send RESET signal to FC
2239
        /// </summary>
2240
        private void _resetCtrl()
2241
        {
2242
            _sendControllerMessage('R', 1);
2243
        }
2244
        /// <summary>
2245
        /// poll the debug data (4sec subscription)
2246
        /// </summary>
2247
        /// <param name="auto"> onetimequery(false) or autoupdate(true) with set timing interval </param>
2248
        private void _readDebugData(bool auto)
2249
        {
2250
            byte interval = auto ? debugInterval : (byte)0;
2251
            _sendControllerMessage('d', 0, new byte[1] { debugInterval });
2252
        }
2253
        /// <summary>
2254
        /// poll the BL-CTRL status via NC (4sec subscription)
2255
        /// </summary>
2256
        /// <param name="auto"> onetimequery(false) or autoupdate(true) with set timing interval </param>
2257
        private void _readBLCtrl(bool auto)
2258
        {
2259
            byte interval = auto ? blctrlInterval : (byte)0;
2260
            _sendControllerMessage('k', 0, new byte[1] { interval });
2261
        }
2262
        /// <summary>
2263
        /// poll the NC data struct (4sec subscription)
2264
        /// </summary>
2265
        /// <param name="auto"> onetimequery(false) or autoupdate(true) with set timing interval </param>
2266
        private void _readNavData(bool auto)
2267
        {
2268
            byte interval = auto ? navctrlInterval : (byte)0;
2269
            _sendControllerMessage('o', 2, new byte[1] { interval });
2270
        }
2271
        /// <summary>
2272
        /// get the errortext for pending NC error
2273
        /// </summary>
2274
        private void _readNCError()
2275
        {
2276
            _sendControllerMessage('e', 2);
2277
        }
2278
        /// <summary>
2279
        /// request the Waypoint at index
2280
        /// </summary>
2281
        /// <param name="index"></param>
2282
        void _getpWP(int index)
2283
        {
2284
            if (serialPortCtrl.Port.IsOpen)
2285
            {
2286
                Stream serialStream = serialPortCtrl.Port.BaseStream;
2287
                byte[] bytes = FlightControllerMessage.CreateMessage('x', 2, new byte[1] { (byte)index });
2288
                serialStream.Write(bytes, 0, bytes.Length);
2289
            }
2290
            else
2291
                Log(LogMsgType.Error, "NOT CONNECTED!");
2292
 
2293
        }
2294
        void _getWP()
2295
        {
2335 - 2296
            int iTimeout = 0;
2287 - 2297
            _bGetWPCount = true;
2315 - 2298
            _getpWP(1); //get the itemscount of wp
2335 - 2299
            while (_bGetWPCount & iTimeout < _iWPTimeout * 5)
2300
            {
2301
                Thread.Sleep(10);
2302
                iTimeout++;
2303
            }
2304
            if (_iWPCount > 0 & !_bGetWPCount)
2287 - 2305
                _getWPList();
2306
        }
2307
        void _getWPList()
2308
        {
2309
            _bGetWP = true;
2313 - 2310
            int iTimeout=0;
2311
            for (int j = 0; j < _iWPCount; j++)
2287 - 2312
            {
2313
                _getpWP(j + 1);
2313 - 2314
                iTimeout = 0;
2315
                while (_iWPIndex != j + 1 & iTimeout < _iWPTimeout * 5)
2316
                {
2317
                    Thread.Sleep(1);
2318
                    iTimeout++;
2319
                }
2287 - 2320
            }
2321
        }
2363 - 2322
        /// <summary>
2323
        /// Wrapper for _clearCopterWPList()
2324
        /// necessary, cause it is called by threadnew which does not like return values...
2325
        /// </summary>
2340 - 2326
        void clearCopterWPList()
2313 - 2327
        {
2340 - 2328
            _clearCopterWPList();
2329
        }
2363 - 2330
        /// <summary>
2331
        /// clear the WP list of the copter
2332
        /// by sending 'invalid' and index '0'
2333
        /// </summary>
2334
        /// <returns></returns>
2340 - 2335
        bool _clearCopterWPList()
2336
        {
2335 - 2337
            int iTimeout = 0;
2313 - 2338
            if (serialPortCtrl.Port.IsOpen)
2339
            {
2340
                byte[] bData = new byte[30];
2341
                for (int i = 0; i < 30; i++)
2342
                    bData[i] = 0;
2343
                Stream serialStream = serialPortCtrl.Port.BaseStream;
2344
                byte[] bytes = FlightControllerMessage.CreateMessage('w', 2, bData); //delete all WP on Copter by sending 'invalid'(==0) at index 0
2345
                serialStream.Write(bytes, 0, bytes.Length);
2287 - 2346
 
2313 - 2347
                _iWPCount = -1;
2340 - 2348
                while (_iWPCount == -1 & iTimeout < _iWPTimeout)
2335 - 2349
                {
2313 - 2350
                    Thread.Sleep(10);
2335 - 2351
                    iTimeout++;
2352
                }
2313 - 2353
                Dispatcher.Invoke(() => lblWPCount.Content = _iWPCount.ToString());
2335 - 2354
                if (_iWPCount > -1)
2340 - 2355
                    return true;
2356
                else
2357
                    Log(LogMsgType.Error, "Timeout while sending list!");
2358
            }
2359
            else
2360
                Log(LogMsgType.Error, "NOT CONNECTED!");
2361
 
2362
            return false;
2363
}
2364
        void _sendWPList()
2365
        {
2362 - 2366
            _sendWPList(0);
2367
        }
2368
        void _sendWPList(int iStart)
2369
        {
2340 - 2370
            int iTimeout = 0;
2371
            if (serialPortCtrl.Port.IsOpen)
2372
            {
2373
                if (_clearCopterWPList())
2313 - 2374
                {
2362 - 2375
                    int k = 1;
2376
                    for (int i = iStart; i < dtWaypoints.Rows.Count; i++)
2335 - 2377
                    {
2362 - 2378
                        k = iStart > 0 ? k : -1;
2376 - 2379
                        _sendWayPoint(dtWaypoints.Rows[i], k, 'w',false);
2313 - 2380
 
2335 - 2381
                        _iWPCount = -1;
2382
                        iTimeout = 0;
2383
                        while (_iWPCount == -1 & iTimeout < _iWPTimeout * 5)
2384
                        {
2385
                            Thread.Sleep(10);
2386
                            iTimeout++;
2387
                        }
2388
                        if (_iWPCount == -1)
2389
                        {
2390
                            Log(LogMsgType.Error, "Timeout while sending list!");
2391
                            break;
2392
                        }
2393
                        Dispatcher.Invoke(() => lblWPCount.Content = _iWPCount.ToString());
2362 - 2394
                        k++;
2335 - 2395
                    }
2313 - 2396
                }
2397
            }
2398
            else
2399
                Log(LogMsgType.Error, "NOT CONNECTED!");
2400
 
2401
        }
2376 - 2402
        bool _sendWayPoint(DataRow dr, int index, char command,bool bSim)
2340 - 2403
        {
2313 - 2404
 
2340 - 2405
            if (serialPortCtrl.Port.IsOpen)
2406
            {
2407
                byte[] bData = new byte[30];
2408
                for (int i = 0; i < 30; i++)
2409
                    bData[i] = 0;
2410
                Stream serialStream = serialPortCtrl.Port.BaseStream;
2411
                byte[] bytes;
2412
                int iVal;
2413
                double dVal;
2414
                NumberFormatInfo nfi = new NumberFormatInfo();
2415
                nfi.NumberDecimalSeparator = ",";
2416
 
2417
                //longitude
2418
                dVal = Convert.ToDouble(dr[4], nfi);
2419
                iVal = (int)(dVal * Math.Pow(10, 7));
2420
                bData[0] = (byte)(iVal & 0xff);
2421
                bData[1] = (byte)((iVal >> 8) & 0xff);
2422
                bData[2] = (byte)((iVal >> 16) & 0xff);
2423
                bData[3] = (byte)(iVal >> 24);
2424
                //latitude
2425
                dVal = Convert.ToDouble(dr[3], nfi);
2426
                iVal = (int)(dVal * Math.Pow(10, 7));
2427
                bData[4] = (byte)(iVal & 0xff);
2428
                bData[5] = (byte)((iVal >> 8) & 0xff);
2429
                bData[6] = (byte)((iVal >> 16) & 0xff);
2430
                bData[7] = (byte)(iVal >> 24);
2431
                //altitude
2432
                dVal = Convert.ToDouble(dr[5], nfi);
2433
                iVal = (int)(dVal * 10);
2434
                bData[8] = (byte)(iVal & 0xff);
2435
                bData[9] = (byte)((iVal >> 8) & 0xff);
2436
                bData[10] = (byte)((iVal >> 16) & 0xff);
2437
                bData[11] = (byte)(iVal >> 24);
2376 - 2438
                if(bSim)
2439
                    bData[12] = 3; //Status 'SIMULATE'
2340 - 2440
                //Status 'NEWDATA'
2376 - 2441
                else
2442
                    bData[12] = 1;
2340 - 2443
                //heading
2444
                iVal = Convert.ToInt16(dr[6]);
2445
                bData[13] = (byte)(iVal & 0xff);
2446
                bData[14] = (byte)((iVal >> 8) & 0xff);
2447
                //ToleranceRadius
2448
                bData[15] = Convert.ToByte(dr[9]);
2449
                //HoldTime
2450
                bData[16] = Convert.ToByte(dr[10]);
2451
                //Event_Flag
2452
                bData[17] = Convert.ToByte(dr[13]);
2453
                //Index
2379 - 2454
                bData[18] = index > -1 ? (byte)index : Convert.ToByte((int)dr[0]);
2340 - 2455
                //Type
2456
                bData[19] = Convert.ToByte(dr[1]);
2457
                //WP_EventChannelValue
2458
                bData[20] = Convert.ToByte(dr[14]);
2459
                //AltitudeRate
2460
                bData[21] = Convert.ToByte(dr[8]);
2461
                //Speed
2462
                bData[22] = Convert.ToByte(dr[7]);
2463
                //CamAngle
2464
                bData[23] = (byte)Convert.ToInt16(dr[12]);
2465
                //Name
2362 - 2466
                string s = index > 0 ? ((string)dr[2]).Substring(0, 1) + index.ToString() : (string)dr[2];
2467
                byte[] name = ASCIIEncoding.ASCII.GetBytes(s);
2340 - 2468
                bData[24] = name.Length > 0 ? name[0] : (byte)0;
2469
                bData[25] = name.Length > 1 ? name[1] : (byte)0;
2470
                bData[26] = name.Length > 2 ? name[2] : (byte)0;
2471
                bData[27] = name.Length > 3 ? name[3] : (byte)0;
2472
                //Autotrigger
2473
                bData[28] = Convert.ToByte(dr[11]);
2474
 
2356 - 2475
                bytes = FlightControllerMessage.CreateMessage(command, 2, bData);
2340 - 2476
                serialStream.Write(bytes, 0, bytes.Length);
2477
 
2478
                return true;
2479
            }
2480
 
2481
            return false;
2482
        }
2287 - 2483
        #region OSD-Menue
2484
 
2485
        /// <summary>
2486
        /// one time query of the OSD Menue with pagenumber
2487
        /// </summary>
2488
        /// <param name="iMenue">Menue page</param>
2489
        void _OSDMenue(int iMenue)
2490
        {
2491
            if (serialPortCtrl.Port.IsOpen)
2492
            {
2493
                if (iMenue > iOSDMax)
2494
                    iMenue = 0;
2495
                Stream serialStream = serialPortCtrl.Port.BaseStream;
2496
                byte[] bytes = FlightControllerMessage.CreateMessage('l', 0, new byte[1] { (byte)iMenue });
2497
                serialStream.Write(bytes, 0, bytes.Length);
2498
            }
2499
            else
2500
                Log(LogMsgType.Error, "NOT CONNECTED!");
2501
 
2502
        }
2503
        /// <summary>
2504
        /// call the OSDMenue and start autorefresh
2505
        ///  usually by sending a menuekey
2506
        /// a bit tricky - but by sending inverted value of 32 (32 = 0010 0000) you can start the OSD menue with autoupdate (abo) without switching the page with the keyvalues (0x1, 0x2)
2507
        /// therefore the value has to be negative (inverted) in order to distinguish from old (2 line) menuestyle
2508
        /// and must not have any bits of the menue keys 0x1 0x2 0x4 0x8 (0x10?) --> 0x20 = -33
2509
        /// </summary>
2510
        void _OSDMenueAutoRefresh()
2511
        {
2512
            _sendControllerMessage('h', 0, new byte[2] { unchecked((byte)(-33)), OSDInterval });
2513
        }
2514
        void _OSDMenueAutoRefresh(byte key)
2515
        {
2516
            _sendControllerMessage('h', 0, new byte[2] { unchecked((byte)~key), OSDInterval });
2517
        }
2518
        /// <summary>
2519
        /// initialize the OSD menue combobox
2520
        /// combox is filled by numbers from 0 to max pagenumber
2521
        /// </summary>
2522
        void _initOSDCB()
2523
        {
2524
            _bCBInit = true;
2525
            if (iOSDMax == 0)
2526
            {
2527
                _OSDMenue(0);
2528
                Thread.Sleep(10);
2529
            }
2530
            Dispatcher.Invoke((Action)(() => cbOSD.Items.Clear()));
2531
            for (int i = 0; i <= iOSDMax; i++)
2532
            {
2533
                Dispatcher.Invoke((Action)(() => cbOSD.Items.Add(i)));
2534
            }
2535
            Dispatcher.Invoke((Action)(() => cbOSD.SelectedItem = iOSDPage));
2536
            _bCBInit = false;
2537
        }
2538
        private void btnOSDForward_Click(object sender, RoutedEventArgs e)
2539
        {
2540
            iOSDPage++;
2541
            if (iOSDPage > iOSDMax)
2542
                iOSDPage = 0;
2543
 
2544
            _OSDMenue(iOSDPage);
2545
        }
2546
        private void btnOSDBackward_Click(object sender, RoutedEventArgs e)
2547
        {
2548
            iOSDPage--;
2549
            if (iOSDPage < 0)
2550
                iOSDPage = iOSDMax;
2551
 
2552
            _OSDMenue(iOSDPage);
2553
        }
2554
        private void btnOSDLeave_Click(object sender, RoutedEventArgs e)
2555
        {
2556
            _OSDMenueAutoRefresh(8);
2557
        }
2558
        private void btnOSDEnter_Click(object sender, RoutedEventArgs e)
2559
        {
2560
            _OSDMenueAutoRefresh(4);
2561
        }
2562
        private void cbOSD_DropDownClosing(object sender, EventArgs e)
2563
        {
2564
            if (!_bCBInit && cbOSD.SelectedIndex > -1)
2565
                _OSDMenue(cbOSD.SelectedIndex);
2566
        }
2567
        private void OSD(LogMsgType msgtype, string msg, bool bNew)
2568
        {
2569
            Dispatcher.Invoke(() =>
2570
            {
2571
                TextRange tr;
2572
                if (bNew)
2573
                {
2574
                    rtfOSD.SelectAll();
2575
                    rtfOSD.Selection.Text = string.Empty;
2576
                }
2577
                tr = new TextRange(rtfOSD.Document.ContentEnd, rtfOSD.Document.ContentEnd);
2578
                tr.Text = msg;
2579
                tr.ApplyPropertyValue(TextElement.ForegroundProperty, new SolidColorBrush(LogMsgTypeColor[(int)msgtype]));
2580
                //     rtfOSD.AppendText("\r");
2581
                rtfOSD.ScrollToEnd();
2582
 
2583
            });
2584
        }
2585
 
2586
        #endregion OSD-Menue
2587
 
2588
        #endregion controller messages
2589
 
2398 - 2590
        void _mediaPlayer(object file)
2295 - 2591
        {
2398 - 2592
            if (File.Exists((string)file))
2295 - 2593
            {
2594
                MediaPlayer.MediaPlayer mp = new MediaPlayer.MediaPlayer();
2398 - 2595
                mp.Open((string)file);
2295 - 2596
                mp.Play();
2597
            }
2598
        }
2310 - 2599
 
2362 - 2600
        #region ui
2310 - 2601
        /// <summary>
2602
        /// Switch between fullscreen and normal window mode
2603
        /// save & restore scaling settings
2604
        /// </summary>
2605
        /// <param name="sender"></param>
2606
        /// <param name="e"></param>
2287 - 2607
        private void imageFullscreen_MouseDown(object sender, MouseButtonEventArgs e)
2608
        {
2609
            if (winState.isMaximized)
2610
            {
2611
                winState.Restore(this);
2612
                imageFullscreen.Source = new BitmapImage(new Uri("Images/Fullscreen.png", UriKind.Relative));
2613
                if(_bSaveWinStateFull)
2614
                    _saveScaleSliders(true);
2615
                if(_bSaveWinStateNormal)
2616
                    _setScaleSliders(false);
2617
            }
2618
            else
2619
            {
2620
                winState.Maximize(this);
2621
                imageFullscreen.Source = new BitmapImage(new Uri("Images/RestoreScreen.png", UriKind.Relative));
2622
                if(_bSaveWinStateNormal)
2623
                    _saveScaleSliders(false);
2624
                if(_bSaveWinStateFull)
2625
                    _setScaleSliders(true);
2626
            }
2627
        }
2628
 
2629
        /// <summary>
2630
        /// reset the scaling of all UI elements to default
2631
        /// </summary>
2632
        /// <param name="sender"></param>
2633
        /// <param name="e"></param>
2634
        private void buttonUIScaleReset_Click(object sender, RoutedEventArgs e)
2635
        {
2636
            UIScaleHorizonSlider.Value =
2637
                UIScaleLOGSlider.Value =
2638
                UIScaleMotorsSlider.Value =
2639
                UIScaleOSDSlider.Value =
2640
                UIScaleSlider.Value =
2641
                UIScaleTopSlider.Value = 1;
2642
        }
2643
        /// <summary>
2644
        /// adjust the top postion of UI elements below the top bar to fit the bottom position of the bar when scaling the top bar
2645
        /// </summary>
2646
        /// <param name="sender"></param>
2647
        /// <param name="e"></param>
2648
        private void UIScaleTopSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
2649
        {
2650
            GridSettings.Margin = new Thickness(GridSettings.Margin.Left, 36 * UIScaleTopSlider.Value, GridSettings.Margin.Right, GridSettings.Margin.Bottom);
2651
            if (GridMotors != null)
2652
                GridMotors.Margin = new Thickness(GridMotors.Margin.Left, 36 * UIScaleTopSlider.Value, GridMotors.Margin.Right, GridMotors.Margin.Bottom);
2653
            if (GridSideBar != null)
2654
                GridSideBar.Margin = new Thickness(GridSideBar.Margin.Left, 36 * UIScaleTopSlider.Value, GridSideBar.Margin.Right, GridSideBar.Margin.Bottom);
2655
            if (GridOSD != null)
2656
                GridOSD.Margin = new Thickness(GridOSD.Margin.Left, 36 * UIScaleTopSlider.Value, GridOSD.Margin.Right, GridOSD.Margin.Bottom);
2657
            if (GridData != null)
2658
                GridData.Margin = new Thickness(GridData.Margin.Left, 36 * UIScaleTopSlider.Value, GridData.Margin.Right, GridData.Margin.Bottom);
2659
            if (GridWP != null)
2660
                GridWP.Margin = new Thickness(GridWP.Margin.Left, 36 * UIScaleTopSlider.Value, GridWP.Margin.Right, GridWP.Margin.Bottom);
2661
        }
2310 - 2662
        /// <summary>
2663
        /// restore the saved scalings for the fullscreen/normal window mode
2664
        /// </summary>
2665
        /// <param name="bFull">the mode the window is set to</param>
2287 - 2666
        void _setScaleSliders(bool bFull)
2667
        {
2668
            if(bFull)
2669
            {
2670
                UIScaleSlider.Value = scaleFullAll;
2671
                UIScaleTopSlider.Value = scaleFullTopBar;
2672
                UIScaleMotorsSlider.Value = scaleFullMotors;
2673
                UIScaleOSDSlider.Value = scaleFullOSD;
2674
                UIScaleLOGSlider.Value = scaleFullLOG;
2675
                UIScaleHorizonSlider.Value = scaleFullHorizon;
2676
            }
2677
            else
2678
            {
2679
                UIScaleSlider.Value = scaleNormalAll;
2680
                UIScaleTopSlider.Value = scaleNormalTopBar;
2681
                UIScaleMotorsSlider.Value = scaleNormalMotors;
2682
                UIScaleOSDSlider.Value = scaleNormalOSD;
2683
                UIScaleLOGSlider.Value = scaleNormalLOG;
2684
                UIScaleHorizonSlider.Value = scaleNormalHorizon;
2685
            }
2686
        }
2687
 
2310 - 2688
        /// <summary>
2689
        /// save the scalings for the actual window mode
2690
        /// </summary>
2691
        /// <param name="bFull">the actual window mode</param>
2287 - 2692
        void _saveScaleSliders(bool bFull)
2693
        {
2694
 
2695
            if (bFull)
2696
            {
2697
                scaleFullAll = UIScaleSlider.Value;
2698
                scaleFullTopBar = UIScaleTopSlider.Value;
2699
                scaleFullMotors = UIScaleMotorsSlider.Value;
2700
                scaleFullOSD = UIScaleOSDSlider.Value;
2701
                scaleFullLOG = UIScaleLOGSlider.Value;
2702
                scaleFullHorizon = UIScaleHorizonSlider.Value;
2703
            }
2704
            else
2705
            {
2706
                scaleNormalAll = UIScaleSlider.Value;
2707
                scaleNormalTopBar = UIScaleTopSlider.Value;
2708
                scaleNormalMotors = UIScaleMotorsSlider.Value;
2709
                scaleNormalOSD = UIScaleOSDSlider.Value;
2710
                scaleNormalLOG = UIScaleLOGSlider.Value;
2711
                scaleNormalHorizon = UIScaleHorizonSlider.Value;
2712
            }
2713
        }
2362 - 2714
        #endregion ui
2287 - 2715
 
2716
        /// <summary>
2717
        /// read settings from ini-file
2718
        /// </summary>
2719
        void _readIni()
2720
        {
2721
            if (!File.Exists(filePath + "\\MKLiveViewSettings.ini"))
2722
                _writeIni();
2723
            IniFile ini = new IniFile("MKLiveViewSettings.ini");
2724
            ini.path = filePath + "\\MKLiveViewSettings.ini";
2312 - 2725
            try
2726
            {
2287 - 2727
 
2312 - 2728
                string sVal = ini.IniReadValue("timings", "AutorefreshDebugData");
2729
                if (sVal != "") _debugDataAutorefresh = Convert.ToBoolean(sVal);
2730
                sVal = ini.IniReadValue("timings", "AutorefreshNavCtrlData");
2731
                if (sVal != "") _navCtrlDataAutorefresh = Convert.ToBoolean(sVal);
2732
                sVal = ini.IniReadValue("timings", "AutorefreshBLCtrlData");
2733
                if (sVal != "") _blctrlDataAutorefresh = Convert.ToBoolean(sVal);
2734
                sVal = ini.IniReadValue("timings", "AutorefreshOSDData");
2735
                if (sVal != "") _OSDAutorefresh = Convert.ToBoolean(sVal);
2287 - 2736
 
2312 - 2737
                sVal = ini.IniReadValue("timings", "IntervalDebugData");
2738
                if (sVal != "") debugInterval = (byte)Convert.ToInt16(sVal);
2739
                sVal = ini.IniReadValue("timings", "IntervalNavCtrlData");
2740
                if (sVal != "") navctrlInterval = (byte)Convert.ToInt16(sVal);
2741
                sVal = ini.IniReadValue("timings", "IntervalBLCtrlData");
2742
                if (sVal != "") blctrlInterval = (byte)Convert.ToInt16(sVal);
2743
                sVal = ini.IniReadValue("timings", "IntervalOSDData");
2744
                if (sVal != "") OSDInterval = (byte)Convert.ToInt16(sVal);
2287 - 2745
 
2312 - 2746
                sVal = ini.IniReadValue("topBar", "voltage");
2747
                if (sVal != "") chkBoxTopBarShowVoltage.IsChecked = Convert.ToBoolean(sVal);
2748
                sVal = ini.IniReadValue("topBar", "capacity");
2749
                if (sVal != "") chkBoxTopBarShowCapacity.IsChecked = Convert.ToBoolean(sVal);
2750
                sVal = ini.IniReadValue("topBar", "current");
2751
                if (sVal != "") chkBoxTopBarShowCurrent.IsChecked = Convert.ToBoolean(sVal);
2752
                sVal = ini.IniReadValue("topBar", "flightTime");
2753
                if (sVal != "") chkBoxTopBarShowFlightTime.IsChecked = Convert.ToBoolean(sVal);
2754
                sVal = ini.IniReadValue("topBar", "distanceHP");
2755
                if (sVal != "") chkBoxTopBarShowDistanceHP.IsChecked = Convert.ToBoolean(sVal);
2756
                sVal = ini.IniReadValue("topBar", "height");
2757
                if (sVal != "") chkBoxTopBarShowHeight.IsChecked = Convert.ToBoolean(sVal);
2758
                sVal = ini.IniReadValue("topBar", "speed");
2759
                if (sVal != "") chkBoxTopBarShowSpeed.IsChecked = Convert.ToBoolean(sVal);
2760
                sVal = ini.IniReadValue("topBar", "magneticField");
2761
                if (sVal != "") chkBoxTopBarShowMF.IsChecked = Convert.ToBoolean(sVal);
2762
                sVal = ini.IniReadValue("topBar", "satellites");
2763
                if (sVal != "") chkBoxTopBarShowSatellites.IsChecked = Convert.ToBoolean(sVal);
2764
                sVal = ini.IniReadValue("topBar", "rc");
2765
                if (sVal != "") chkBoxTopBarShowRC.IsChecked = Convert.ToBoolean(sVal);
2287 - 2766
 
2312 - 2767
                sVal = ini.IniReadValue("style", "saveFullScreen");
2768
                if (sVal != "") chkBoxSaveFullScreenState.IsChecked = Convert.ToBoolean(sVal);
2769
                sVal = ini.IniReadValue("style", "saveNormalState");
2770
                if (sVal != "") chkBoxSaveNormalState.IsChecked = Convert.ToBoolean(sVal);
2287 - 2771
 
2312 - 2772
                sVal = ini.IniReadValue("style", "scaleNormalAll");
2773
                if (sVal != "") scaleNormalAll = Convert.ToDouble(sVal);
2774
                sVal = ini.IniReadValue("style", "scaleNormalTopBar");
2775
                if (sVal != "") scaleNormalTopBar = Convert.ToDouble(sVal);
2776
                sVal = ini.IniReadValue("style", "scaleNormalMotors");
2777
                if (sVal != "") scaleNormalMotors = Convert.ToDouble(sVal);
2778
                sVal = ini.IniReadValue("style", "scaleNormalOSD");
2779
                if (sVal != "") scaleNormalOSD = Convert.ToDouble(sVal);
2780
                sVal = ini.IniReadValue("style", "scaleNormalLOG");
2781
                if (sVal != "") scaleNormalLOG = Convert.ToDouble(sVal);
2782
                sVal = ini.IniReadValue("style", "scaleNormalHorizon");
2783
                if (sVal != "") scaleNormalHorizon = Convert.ToDouble(sVal);
2287 - 2784
 
2312 - 2785
                sVal = ini.IniReadValue("style", "scaleFullAll");
2786
                if (sVal != "") scaleFullAll = Convert.ToDouble(sVal);
2787
                sVal = ini.IniReadValue("style", "scaleFullTopBar");
2788
                if (sVal != "") scaleFullTopBar = Convert.ToDouble(sVal);
2789
                sVal = ini.IniReadValue("style", "scaleFullMotors");
2790
                if (sVal != "") scaleFullMotors = Convert.ToDouble(sVal);
2791
                sVal = ini.IniReadValue("style", "scaleFullOSD");
2792
                if (sVal != "") scaleFullOSD = Convert.ToDouble(sVal);
2793
                sVal = ini.IniReadValue("style", "scaleFullLOG");
2794
                if (sVal != "") scaleFullLOG = Convert.ToDouble(sVal);
2795
                sVal = ini.IniReadValue("style", "scaleFullHorizon");
2796
                if (sVal != "") scaleFullHorizon = Convert.ToDouble(sVal);
2287 - 2797
 
2312 - 2798
                sVal = ini.IniReadValue("general", "LiPoCells");
2799
                _LipoCells = Convert.ToInt16(sVal);
2800
                sVal = ini.IniReadValue("general", "Motors");
2801
                if (sVal != "") _iMotors = Convert.ToInt16(sVal);
2287 - 2802
 
2312 - 2803
                sVal = ini.IniReadValue("map", "followMe");
2804
                if (sVal != "") _bFollowCopter = Convert.ToBoolean(sVal);
2805
                sVal = ini.IniReadValue("map", "AutoSetHome");
2806
                if (sVal != "") _bAutoHome = Convert.ToBoolean(sVal);
2324 - 2807
                sVal = ini.IniReadValue("map", "GPXLog");
2808
                if (sVal != "") _bGPXLog = Convert.ToBoolean(sVal);
2287 - 2809
 
2312 - 2810
                sVal = ini.IniReadValue("threshold", "VoltageWarning");
2811
                if(sVal != "") _dThresholdVoltageWarn = Convert.ToDouble(sVal);
2812
                sVal = ini.IniReadValue("threshold", "VoltageCritical");
2813
                if(sVal != "") _dThresholdVoltageCrit = Convert.ToDouble(sVal);
2814
                sVal = ini.IniReadValue("threshold", "VoiceVoltageEnable");
2815
                if(sVal != "") _bVoiceVoltPlay = Convert.ToBoolean(sVal);
2816
                sVal = ini.IniReadValue("threshold", "VoiceSatFixEnable");
2817
                if(sVal != "") _bVoiceSatFixPlay = Convert.ToBoolean(sVal);
2818
                sVal = ini.IniReadValue("threshold", "VoiceMagFieldEnable");
2819
                if(sVal != "") _bVoiceMagneticFieldPlay = Convert.ToBoolean(sVal);
2820
                sVal = ini.IniReadValue("threshold", "DistanceWarning");
2821
                if(sVal != "") _dThresholdDistanceWarn = Convert.ToDouble(sVal);
2822
                sVal = ini.IniReadValue("threshold", "VoiceDistanceWarnEnable");
2823
                if(sVal != "") _bVoiceDistancePlay = Convert.ToBoolean(sVal);
2824
                sVal = ini.IniReadValue("threshold", "VoiceRCLevelWarnEnable");
2825
                if(sVal != "") _bVoiceRCLevelPlay = Convert.ToBoolean(sVal);
2826
                sVal = ini.IniReadValue("threshold", "MaxDistance");
2827
                if(sVal != "") _dThresholdDistanceMax = Convert.ToDouble(sVal);
2828
                sVal = ini.IniReadValue("threshold", "RCThreshold");
2829
                if(sVal != "") _iThresholdRC = Convert.ToInt32(sVal);
2830
                sVal = ini.IniReadValue("threshold", "MagFieldThreshold");
2831
                if(sVal != "") _iThresholdMagField = Convert.ToInt32(sVal);
2321 - 2832
 
2833
                sVal = ini.IniReadValue("waypoints", "wpcolor");
2834
                if(sVal != "") comboBoxWPColor.SelectedIndex = Convert.ToInt32(sVal);
2835
                sVal = ini.IniReadValue("waypoints", "poicolor");
2836
                if(sVal != "") comboBoxPOIColor.SelectedIndex = Convert.ToInt32(sVal);
2837
                sVal = ini.IniReadValue("waypoints", "fscolor");
2838
                if(sVal != "") comboBoxFSColor.SelectedIndex = Convert.ToInt32(sVal);
2839
                sVal = ini.IniReadValue("waypoints", "coptercolor");
2840
                if(sVal != "") comboBoxCopterColor.SelectedIndex = Convert.ToInt32(sVal);
2385 - 2841
                sVal = ini.IniReadValue("waypoints", "copterheadingcolor");
2842
                if(sVal != "") comboBoxCopterHeadingColor.SelectedIndex = Convert.ToInt32(sVal);
2379 - 2843
                sVal = ini.IniReadValue("waypoints", "landingcolor");
2844
                if(sVal != "") comboBoxLandingColor.SelectedIndex = Convert.ToInt32(sVal);
2328 - 2845
                sVal = ini.IniReadValue("waypoints", "routecolor");
2846
                if(sVal != "") comboBoxRouteColor.SelectedIndex = Convert.ToInt32(sVal);
2847
                sVal = ini.IniReadValue("waypoints", "showWPRoute");
2848
                if(sVal != "") _bShowWPRoute = Convert.ToBoolean(sVal);
2349 - 2849
 
2850
                for (int i = 0; i < 12; i++)
2851
                {
2852
                    sVal = ini.IniReadValue("serial", "ch" + i.ToString() + "Val");
2853
                    if (sVal != "")
2854
                        serChan[i] = Convert.ToInt16(sVal);
2855
                    sVal = ini.IniReadValue("serial", "ch" + i.ToString() + "Title");
2856
                    if (sVal != "")
2857
                        serChanTitle[i] = sVal;
2858
                    for (int y = 0; i < 4 && y < 3; y++)
2859
                    {
2860
                        sVal = ini.IniReadValue("serial", "ch" + i.ToString() + "ValSub" + y.ToString());
2861
                        if (sVal != "")
2862
                            serChan_sub[(i * 3) + y] = Convert.ToInt16(sVal);
2863
                    }
2864
                }
2865
 
2312 - 2866
            }
2867
            catch (Exception e)
2868
            {
2287 - 2869
 
2312 - 2870
                MessageBox.Show("Error parsing ini-file!" + Environment.NewLine + e.Message,"Read ini-file" ,MessageBoxButton.OK,MessageBoxImage.Error);
2871
            }
2872
 
2287 - 2873
        }
2874
 
2875
        /// <summary>
2876
        /// save settings to ini-file
2877
        /// </summary>
2878
        void _writeIni()
2879
        {
2880
 
2881
            IniFile ini = new IniFile("MKLiveViewSettings.ini");
2882
            ini.path = filePath + "\\MKLiveViewSettings.ini";
2883
 
2312 - 2884
            try
2885
            {
2287 - 2886
 
2312 - 2887
                ini.IniWriteValue("timings", "AutorefreshDebugData", _debugDataAutorefresh ? "true" : "false");
2888
                ini.IniWriteValue("timings", "AutorefreshNavCtrlData", _navCtrlDataAutorefresh ? "true" : "false");
2889
                ini.IniWriteValue("timings", "AutorefreshBLCtrlData", _blctrlDataAutorefresh ? "true" : "false");
2890
                ini.IniWriteValue("timings", "AutorefreshOSDData", _OSDAutorefresh ? "true" : "false");
2287 - 2891
 
2312 - 2892
                ini.IniWriteValue("timings", "IntervalDebugData", debugInterval.ToString());
2893
                ini.IniWriteValue("timings", "IntervalNavCtrlData", navctrlInterval.ToString());
2894
                ini.IniWriteValue("timings", "IntervalBLCtrlData", blctrlInterval.ToString());
2895
                ini.IniWriteValue("timings", "IntervalOSDData", OSDInterval.ToString());
2287 - 2896
 
2312 - 2897
                ini.IniWriteValue("general", "LiPoCells", _LipoCells.ToString());
2898
                ini.IniWriteValue("general", "Motors", _iMotors.ToString());
2287 - 2899
 
2312 - 2900
                ini.IniWriteValue("map", "followMe", _bFollowCopter.ToString());
2901
                ini.IniWriteValue("map", "AutoSetHome", _bAutoHome.ToString());
2324 - 2902
                ini.IniWriteValue("map", "GPXLog", _bGPXLog.ToString());
2287 - 2903
 
2312 - 2904
                ini.IniWriteValue("topBar", "voltage", chkBoxTopBarShowVoltage.IsChecked.ToString());
2905
                ini.IniWriteValue("topBar", "capacity", chkBoxTopBarShowCapacity.IsChecked.ToString());
2906
                ini.IniWriteValue("topBar", "current", chkBoxTopBarShowCurrent.IsChecked.ToString());
2907
                ini.IniWriteValue("topBar", "flightTime", chkBoxTopBarShowFlightTime.IsChecked.ToString());
2908
                ini.IniWriteValue("topBar", "distanceHP", chkBoxTopBarShowDistanceHP.IsChecked.ToString());
2909
                ini.IniWriteValue("topBar", "height", chkBoxTopBarShowHeight.IsChecked.ToString());
2910
                ini.IniWriteValue("topBar", "speed", chkBoxTopBarShowSpeed.IsChecked.ToString());
2911
                ini.IniWriteValue("topBar", "magneticField", chkBoxTopBarShowMF.IsChecked.ToString());
2912
                ini.IniWriteValue("topBar", "satellites", chkBoxTopBarShowSatellites.IsChecked.ToString());
2913
                ini.IniWriteValue("topBar", "rc", chkBoxTopBarShowRC.IsChecked.ToString());
2287 - 2914
 
2312 - 2915
                ini.IniWriteValue("style", "saveFullScreen", chkBoxSaveFullScreenState.IsChecked.ToString());
2916
                ini.IniWriteValue("style", "saveNormalState", chkBoxSaveNormalState.IsChecked.ToString());
2287 - 2917
 
2312 - 2918
                ini.IniWriteValue("style", "scaleNormalAll", scaleNormalAll.ToString());
2919
                ini.IniWriteValue("style", "scaleNormalTopBar", scaleNormalTopBar.ToString());
2920
                ini.IniWriteValue("style", "scaleNormalMotors", scaleNormalMotors.ToString());
2921
                ini.IniWriteValue("style", "scaleNormalOSD", scaleNormalOSD.ToString());
2922
                ini.IniWriteValue("style", "scaleNormalLOG", scaleNormalLOG.ToString());
2923
                ini.IniWriteValue("style", "scaleNormalHorizon", scaleNormalHorizon.ToString());
2287 - 2924
 
2312 - 2925
                ini.IniWriteValue("style", "scaleFullAll", scaleFullAll.ToString());
2926
                ini.IniWriteValue("style", "scaleFullTopBar", scaleFullTopBar.ToString());
2927
                ini.IniWriteValue("style", "scaleFullMotors", scaleFullMotors.ToString());
2928
                ini.IniWriteValue("style", "scaleFullOSD", scaleFullOSD.ToString());
2929
                ini.IniWriteValue("style", "scaleFullLOG", scaleFullLOG.ToString());
2930
                ini.IniWriteValue("style", "scaleFullHorizon", scaleFullHorizon.ToString());
2287 - 2931
 
2312 - 2932
                ini.IniWriteValue("style", "horizon", chkBoxShowHorizon.IsChecked.ToString());
2933
 
2934
                ini.IniWriteValue("threshold", "VoltageWarning", _dThresholdVoltageWarn.ToString());
2935
                ini.IniWriteValue("threshold", "VoltageCritical", _dThresholdVoltageCrit.ToString());
2936
                ini.IniWriteValue("threshold", "VoiceVoltageEnable", _bVoiceVoltPlay.ToString());
2937
                ini.IniWriteValue("threshold", "VoiceSatFixEnable", _bVoiceSatFixPlay.ToString());
2938
                ini.IniWriteValue("threshold", "VoiceMagFieldEnable", _bVoiceMagneticFieldPlay.ToString());
2939
                ini.IniWriteValue("threshold", "VoiceDistanceWarnEnable", _bVoiceDistancePlay.ToString());
2940
                ini.IniWriteValue("threshold", "VoiceRCLevelWarnEnable", _bVoiceRCLevelPlay.ToString());
2941
                ini.IniWriteValue("threshold", "DistanceWarning", _dThresholdDistanceWarn.ToString());
2942
                ini.IniWriteValue("threshold", "MaxDistance", _dThresholdDistanceMax.ToString());
2943
                ini.IniWriteValue("threshold", "RCThreshold", _iThresholdRC.ToString());
2944
                ini.IniWriteValue("threshold", "MagFieldThreshold", _iThresholdMagField.ToString());
2321 - 2945
 
2946
                ini.IniWriteValue("waypoints", "wpcolor", comboBoxWPColor.SelectedIndex.ToString());
2947
                ini.IniWriteValue("waypoints", "poicolor", comboBoxPOIColor.SelectedIndex.ToString());
2948
                ini.IniWriteValue("waypoints", "fscolor", comboBoxFSColor.SelectedIndex.ToString());
2949
                ini.IniWriteValue("waypoints", "coptercolor", comboBoxCopterColor.SelectedIndex.ToString());
2385 - 2950
                ini.IniWriteValue("waypoints", "copterheadingcolor", comboBoxCopterHeadingColor.SelectedIndex.ToString());
2379 - 2951
                ini.IniWriteValue("waypoints", "landingcolor", comboBoxLandingColor.SelectedIndex.ToString());
2328 - 2952
                ini.IniWriteValue("waypoints", "routecolor", comboBoxRouteColor.SelectedIndex.ToString());
2953
                ini.IniWriteValue("waypoints", "showWPRoute", _bShowWPRoute.ToString());
2349 - 2954
 
2955
                for (int i = 0; i < 12; i++)
2956
                {
2957
                    ini.IniWriteValue("serial", "ch" + i.ToString() + "Val", serChan[i].ToString());
2958
                    ini.IniWriteValue("serial", "ch" + i.ToString() + "Title", serChanTitle[i]);
2959
                    for (int y = 0; i < 4 && y < 3; y++)
2960
                    {
2961
                        ini.IniWriteValue("serial", "ch" + i.ToString() + "ValSub" + y.ToString(), serChan_sub[(i * 3) + y].ToString());
2962
                    }
2963
                }
2964
 
2312 - 2965
            }
2966
            catch (Exception e)
2967
            {
2968
 
2969
                MessageBox.Show("Error writing ini-file!" + Environment.NewLine + "Please make sure that the programm is in a location where it is allowed to write" + Environment.NewLine + e.Message, "Write ini-file", MessageBoxButton.OK, MessageBoxImage.Error);
2970
            }
2287 - 2971
        }
2350 - 2972
 
2349 - 2973
        #region serial channels
2974
        /// <summary>
2975
        /// Sending the serial channel values
2976
        /// </summary>
2977
        void _sendSerialData()
2978
        {
2979
            byte[] serData = new byte[12];
2980
            for (int i = 0; i < 12; i++)
2981
            {
2982
                serData[i] = unchecked((byte)(serChan[i] - 127));
2983
            }
2984
            _sendControllerMessage('y', 1, serData);
2985
        }
2986
        /// <summary>
2987
        /// init the controls for displaying
2988
        /// and setting serial control channels
2989
        /// </summary>
2990
        void _initSerialCtrl()
2991
        {
2992
            SerChan1ScaleSlider.Value = serChan[0];
2993
            textBoxSerial1.Text = serChanTitle[0];
2994
            SerChan2ScaleSlider.Value = serChan[1];
2995
            textBoxSerial2.Text = serChanTitle[1];
2350 - 2996
            SerChan3ScaleSlider.Value = serChan[2];
2997
            textBoxSerial3.Text = serChanTitle[2];
2349 - 2998
            //SerChan4ScaleSlider.Value = serChan[3];
2999
            //textBoxSerial4.Text = serChanTitle[3];
3000
            //trckbarSerial5.Value = serChan[4];
3001
            //textBoxSerial5.Text = serChanTitle[4];
3002
            //trckbarSerial6.Value = serChan[5];
3003
            //textBoxSerial6.Text = serChanTitle[5];
3004
            //trckbarSerial7.Value = serChan[6];
3005
            //textBoxSerial7.Text = serChanTitle[6];
3006
            //trckbarSerial8.Value = serChan[7];
3007
            //textBoxSerial8.Text = serChanTitle[7];
2312 - 3008
 
2349 - 3009
            textBoxSerial1_val1.Text = serChan_sub[0].ToString();
3010
            textBoxSerial1_val2.Text = serChan_sub[1].ToString();
3011
            textBoxSerial1_val3.Text = serChan_sub[2].ToString();
3012
            textBoxSerial2_val1.Text = serChan_sub[3].ToString();
3013
            textBoxSerial2_val2.Text = serChan_sub[4].ToString();
3014
            textBoxSerial2_val3.Text = serChan_sub[5].ToString();
2350 - 3015
            textBoxSerial3_val1.Text = serChan_sub[6].ToString();
3016
            textBoxSerial3_val2.Text = serChan_sub[7].ToString();
3017
            textBoxSerial3_val3.Text = serChan_sub[8].ToString();
2349 - 3018
            //textBoxSerial4_val1.Text = serChan_sub[9].ToString();
3019
            //textBoxSerial4_val2.Text = serChan_sub[10].ToString();
3020
            //textBoxSerial4_val3.Text = serChan_sub[11].ToString();
3021
        }
3022
        private void SerChan1ScaleSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
3023
        {
3024
            if (!_init)
3025
            {
3026
                serChan[0] = (int)SerChan1ScaleSlider.Value;
3027
                _sendSerialData();
3028
            }
3029
        }
3030
        private void textBoxSerial1_TextChanged(object sender, TextChangedEventArgs e)
3031
        {
3032
            if (!_init)
3033
            {
3034
                serChanTitle[0] = textBoxSerial1.Text;
3035
            }
3036
        }
3037
        private void textBoxSerial1_val1_TextChanged(object sender, TextChangedEventArgs e)
3038
        {
3039
            if (textBoxSerial1_val1.Text.Length > 0 & !_init)
3040
            {
3041
                serChan_sub[0] = Convert.ToInt16(textBoxSerial1_val1.Text);
3042
            }
3043
        }
3044
        private void textBoxSerial1_val2_TextChanged(object sender, TextChangedEventArgs e)
3045
        {
3046
            if (textBoxSerial1_val2.Text.Length > 0 & !_init)
3047
            {
3048
                serChan_sub[1] = Convert.ToInt16(textBoxSerial1_val2.Text);
3049
            }
3050
        }
3051
        private void textBoxSerial1_val3_TextChanged(object sender, TextChangedEventArgs e)
3052
        {
3053
            if (textBoxSerial1_val3.Text.Length > 0 & !_init)
3054
            {
3055
                serChan_sub[2] = Convert.ToInt16(textBoxSerial1_val3.Text);
3056
            }
3057
        }
3058
        private void btnSer1_val1_Click(object sender, RoutedEventArgs e)
3059
        {
3060
            if (textBoxSerial1_val1.Text.Length > 0)
3061
            {
3062
                SerChan1ScaleSlider.Value = Convert.ToInt16(textBoxSerial1_val1.Text);
3063
            }
3064
        }
3065
        private void btnSer1_0_Click(object sender, RoutedEventArgs e)
3066
        {
3067
            SerChan1ScaleSlider.Value = 0;
3068
        }
3069
        private void btnSer1_127_Click(object sender, RoutedEventArgs e)
3070
        {
3071
            SerChan1ScaleSlider.Value = 127;
3072
        }
3073
        private void btnSer1_254_Click(object sender, RoutedEventArgs e)
3074
        {
3075
            SerChan1ScaleSlider.Value = 254;
3076
        }
3077
        private void btnSer1_val2_Click(object sender, RoutedEventArgs e)
3078
        {
3079
            if (textBoxSerial1_val2.Text.Length > 0)
3080
            {
3081
                SerChan1ScaleSlider.Value = Convert.ToInt16(textBoxSerial1_val2.Text);
3082
            }
3083
        }
3084
        private void btnSer1_val3_Click(object sender, RoutedEventArgs e)
3085
        {
3086
            if (textBoxSerial1_val3.Text.Length > 0)
3087
            {
3088
                SerChan1ScaleSlider.Value = Convert.ToInt16(textBoxSerial1_val3.Text);
3089
            }
3090
        }
3091
 
3092
        private void SerChan2ScaleSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
3093
        {
3094
            if (!_init)
3095
            {
3096
                serChan[1] = (int)SerChan2ScaleSlider.Value;
3097
                _sendSerialData();
3098
            }
3099
        }
3100
        private void textBoxSerial2_TextChanged(object sender, TextChangedEventArgs e)
3101
        {
3102
            if (!_init)
3103
            {
3104
                serChanTitle[1] = textBoxSerial2.Text;
3105
            }
3106
        }
3107
        private void textBoxSerial2_val1_TextChanged(object sender, TextChangedEventArgs e)
3108
        {
3109
            if (textBoxSerial2_val1.Text.Length > 0 & !_init)
3110
            {
3111
                serChan_sub[3] = Convert.ToInt16(textBoxSerial2_val1.Text);
3112
            }
3113
        }
3114
        private void textBoxSerial2_val2_TextChanged(object sender, TextChangedEventArgs e)
3115
        {
3116
            if (textBoxSerial2_val2.Text.Length > 0 & !_init)
3117
            {
3118
                serChan_sub[4] = Convert.ToInt16(textBoxSerial2_val2.Text);
3119
            }
3120
        }
3121
        private void textBoxSerial2_val3_TextChanged(object sender, TextChangedEventArgs e)
3122
        {
3123
            if (textBoxSerial2_val3.Text.Length > 0 & !_init)
3124
            {
3125
                serChan_sub[5] = Convert.ToInt16(textBoxSerial2_val3.Text);
3126
            }
3127
        }
3128
        private void btnSer2_0_Click(object sender, RoutedEventArgs e)
3129
        {
3130
            SerChan2ScaleSlider.Value = 0;
3131
        }
3132
        private void btnSer2_127_Click(object sender, RoutedEventArgs e)
3133
        {
3134
            SerChan2ScaleSlider.Value = 127;
3135
        }
3136
        private void btnSer2_254_Click(object sender, RoutedEventArgs e)
3137
        {
3138
            SerChan2ScaleSlider.Value = 254;
3139
        }
3140
        private void btnSer2_val1_Click(object sender, RoutedEventArgs e)
3141
        {
3142
            if (textBoxSerial2_val1.Text.Length > 0)
3143
            {
3144
                SerChan2ScaleSlider.Value = Convert.ToInt16(textBoxSerial2_val1.Text);
3145
            }
3146
        }
3147
        private void btnSer2_val2_Click(object sender, RoutedEventArgs e)
3148
        {
3149
            if (textBoxSerial2_val2.Text.Length > 0)
3150
            {
3151
                SerChan2ScaleSlider.Value = Convert.ToInt16(textBoxSerial2_val2.Text);
3152
            }
3153
        }
3154
        private void btnSer2_val3_Click(object sender, RoutedEventArgs e)
3155
        {
3156
            if (textBoxSerial2_val3.Text.Length > 0)
3157
            {
3158
                SerChan2ScaleSlider.Value = Convert.ToInt16(textBoxSerial2_val3.Text);
3159
            }
3160
        }
2350 - 3161
 
3162
        private void SerChan3ScaleSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
3163
        {
3164
            if (!_init)
3165
            {
3166
                serChan[2] = (int)SerChan3ScaleSlider.Value;
3167
                _sendSerialData();
3168
            }
3169
        }
3170
        private void textBoxSerial3_TextChanged(object sender, TextChangedEventArgs e)
3171
        {
3172
            if (!_init)
3173
            {
3174
                serChanTitle[2] = textBoxSerial3.Text;
3175
            }
3176
        }
3177
        private void textBoxSerial3_val1_TextChanged(object sender, TextChangedEventArgs e)
3178
        {
3179
            if (textBoxSerial3_val1.Text.Length > 0 & !_init)
3180
            {
3181
                serChan_sub[6] = Convert.ToInt16(textBoxSerial3_val1.Text);
3182
            }
3183
        }
3184
        private void textBoxSerial3_val2_TextChanged(object sender, TextChangedEventArgs e)
3185
        {
3186
            if (textBoxSerial3_val2.Text.Length > 0 & !_init)
3187
            {
3188
                serChan_sub[7] = Convert.ToInt16(textBoxSerial3_val2.Text);
3189
            }
3190
        }
3191
        private void textBoxSerial3_val3_TextChanged(object sender, TextChangedEventArgs e)
3192
        {
3193
            if (textBoxSerial3_val3.Text.Length > 0 & !_init)
3194
            {
3195
                serChan_sub[8] = Convert.ToInt16(textBoxSerial3_val3.Text);
3196
            }
3197
        }
3198
        private void btnSer3_0_Click(object sender, RoutedEventArgs e)
3199
        {
3200
            SerChan3ScaleSlider.Value = 0;
3201
        }
3202
        private void btnSer3_127_Click(object sender, RoutedEventArgs e)
3203
        {
3204
            SerChan3ScaleSlider.Value = 127;
3205
        }
3206
        private void btnSer3_254_Click(object sender, RoutedEventArgs e)
3207
        {
3208
            SerChan3ScaleSlider.Value = 254;
3209
        }
3210
        private void btnSer3_val1_Click(object sender, RoutedEventArgs e)
3211
        {
3212
            if (textBoxSerial3_val1.Text.Length > 0)
3213
            {
3214
                SerChan3ScaleSlider.Value = Convert.ToInt16(textBoxSerial3_val1.Text);
3215
            }
3216
        }
3217
        private void btnSer3_val2_Click(object sender, RoutedEventArgs e)
3218
        {
3219
            if (textBoxSerial3_val2.Text.Length > 0)
3220
            {
3221
                SerChan3ScaleSlider.Value = Convert.ToInt16(textBoxSerial3_val2.Text);
3222
            }
3223
        }
3224
        private void btnSer3_val3_Click(object sender, RoutedEventArgs e)
3225
        {
3226
            if (textBoxSerial3_val3.Text.Length > 0)
3227
            {
3228
                SerChan3ScaleSlider.Value = Convert.ToInt16(textBoxSerial3_val3.Text);
3229
            }
3230
        }
2349 - 3231
        /// <summary>
3232
        /// checks the input of a textbox
3233
        /// for valid data
3234
        /// in this case values 0-254
3235
        /// </summary>
3236
        /// <param name="sender"></param>
3237
        /// <param name="e"></param>
3238
        private void textBox_serial_KeyPress(object sender, KeyEventArgs e)
3239
        {
3240
            if ("1234567890,\b".IndexOf(e.Key.ToString()) < 0) //general check for valid chars(0-9) and backspace (\b)
3241
                e.Handled = true;
3242
            else
3243
            if ("\b".IndexOf(e.Key.ToString()) < 0)
3244
                if (Convert.ToInt16(((TextBox)sender).Text + e.Key) > 254) //if valid and not backspace, check for upper limit of the resulting number
3245
                    e.Handled = true;
3246
                else
3247
                {
3248
                    int i = -1;
3249
                    switch (((TextBox)sender).Name)
3250
                    {
3251
                        case "textBoxSerial1_val1":
3252
                            i = 0;
3253
                            break;
3254
                        case "textBoxSerial1_val2":
3255
                            i = 1;
3256
                            break;
3257
                        case "textBoxSerial1_val3":
3258
                            i = 2;
3259
                            break;
3260
                        case "textBoxSerial2_val1":
3261
                            i = 3;
3262
                            break;
3263
                        case "textBoxSerial2_val2":
3264
                            i = 4;
3265
                            break;
3266
                        case "textBoxSerial2_val3":
3267
                            i = 5;
3268
                            break;
3269
                        case "textBoxSerial3_val1":
3270
                            i = 6;
3271
                            break;
3272
                        case "textBoxSerial3_val2":
3273
                            i = 7;
3274
                            break;
3275
                        case "textBoxSerial3_val3":
3276
                            i = 8;
3277
                            break;
3278
                        case "textBoxSerial4_val1":
3279
                            i = 9;
3280
                            break;
3281
                        case "textBoxSerial4_val2":
3282
                            i = 10;
3283
                            break;
3284
                        case "textBoxSerial4_val3":
3285
                            i = 11;
3286
                            break;
3287
                    }
3288
                    if (i > -1)
3289
                        serChan_sub[i] = Convert.ToInt16(((TextBox)sender).Text + e.Key.ToString());
3290
                }
3291
        }
3292
 
3293
        #endregion serial channels
2315 - 3294
        #region WP
2312 - 3295
        void _readWPLFile()
3296
        {
3297
            Microsoft.Win32.OpenFileDialog fd = new Microsoft.Win32.OpenFileDialog();
3298
            fd.Filter = "Waypointlists | *.wpl";
3299
            fd.Multiselect = false;
3300
            if (fd.ShowDialog().Value)
3301
            {
3302
                string file = fd.SafeFileName;
3303
                IniFile ini = new IniFile(fd.SafeFileName);
3304
                ini.path = fd.FileName;
3305
 
3306
                try
3307
                {
3308
                    string sVal = ini.IniReadValue("General", "FileVersion");
3309
                    if (sVal == "")
3310
                        MessageBox.Show("The file has no version declared - can't go on...", "", MessageBoxButton.OK, MessageBoxImage.Information);
3311
                    else
3312
                    {
3313
                        if (Convert.ToInt16(sVal) < 3)
3314
                            MessageBox.Show("The file version is not supported - can't go on...", "", MessageBoxButton.OK, MessageBoxImage.Information);
3315
                        else
3316
                        {
3317
                            sVal = ini.IniReadValue("General", "NumberOfWaypoints");
3318
                            if (sVal == "")
3319
                                MessageBox.Show("The file has no number of waypoints declared - can't go on...", "", MessageBoxButton.OK, MessageBoxImage.Information);
3320
                            else
3321
                            {
3322
                                int wpnum = Convert.ToInt16(sVal);
3323
                                string wp;
3324
                                int i;
2313 - 3325
                                NumberFormatInfo nfi = new NumberFormatInfo();
3326
                                nfi.NumberDecimalSeparator = ".";
2312 - 3327
                                dtWaypoints.Rows.Clear();
2368 - 3328
                                _wpEdit = -1;_wpIndex = -1;
2327 - 3329
                                _clearMapMarkers(typeof(CustomMarkerWP));
2363 - 3330
                                _clearMapMarkers(typeof(CustomMarkerWPActive));
2328 - 3331
                                wpList.Clear();
3332
                                if (mRouteWP != null)
3333
                                    MainMap.Markers.Remove(mRouteWP);
2363 - 3334
                                //if (wpActiveMarker != null)
3335
                                //    MainMap.Markers.Remove(wpActiveMarker);
2328 - 3336
                                Dispatcher.Invoke(() => lblWPRouteDistance.Content = "0 m");
3337
 
2312 - 3338
                                for (int k = 1; k <= wpnum; k++)
3339
                                {
3340
                                    DataRow dr = dtWaypoints.NewRow();
3341
                                    dr.ItemArray = new object[16];
3342
                                    object[] o = new object[16];
3343
                                    i = 0;
3344
                                    wp = "Point" + k.ToString();
3345
                                    o[i] = k;
3346
                                    i++;
3347
                                    sVal = ini.IniReadValue(wp, "Type");
3348
                                    if (sVal != "")
2315 - 3349
                                        o[i] = Convert.ToInt16(sVal) - 1;
2312 - 3350
                                    i++;
3351
                                    sVal = ini.IniReadValue(wp, "Prefix");
3352
                                    if (sVal != "")
2350 - 3353
                                        o[i] = sVal + k.ToString();
3354
                                   //     o[i] = sVal == "0" ? "!" + k.ToString() : sVal + k.ToString();
2312 - 3355
                                    i++;
2313 - 3356
                                    sVal = ini.IniReadValue(wp, "Latitude");
2312 - 3357
                                    if (sVal != "")
2313 - 3358
                                        o[i] = Convert.ToDouble(sVal, nfi);
2312 - 3359
                                    i++;
2313 - 3360
                                    sVal = ini.IniReadValue(wp, "Longitude");
2312 - 3361
                                    if (sVal != "")
2313 - 3362
                                        o[i] = Convert.ToDouble(sVal, nfi);
2312 - 3363
                                    i++;
3364
                                    sVal = ini.IniReadValue(wp, "Altitude");
3365
                                    if (sVal != "")
2313 - 3366
                                        o[i] = Convert.ToDouble(sVal, nfi);
2312 - 3367
                                    i++;
3368
                                    sVal = ini.IniReadValue(wp, "Heading");
3369
                                    if (sVal != "")
3370
                                        o[i] = Convert.ToInt16(sVal);
3371
                                    i++;
3372
                                    sVal = ini.IniReadValue(wp, "Speed");
3373
                                    if (sVal != "")
2315 - 3374
                                        o[i] = Convert.ToInt16(sVal);
2312 - 3375
                                    i++;
3376
                                    sVal = ini.IniReadValue(wp, "ClimbRate");
3377
                                    if (sVal != "")
3378
                                        o[i] = Convert.ToInt16(sVal);
3379
                                    i++;
3380
                                    sVal = ini.IniReadValue(wp, "Radius");
3381
                                    if (sVal != "")
3382
                                        o[i] = Convert.ToInt16(sVal);
3383
                                    i++;
3384
                                    sVal = ini.IniReadValue(wp, "DelayTime");
3385
                                    if (sVal != "")
3386
                                        o[i] = Convert.ToInt16(sVal);
3387
                                    i++;
3388
                                    sVal = ini.IniReadValue(wp, "AutoTrigger");
3389
                                    if (sVal != "")
3390
                                        o[i] = Convert.ToInt16(sVal); ;
3391
                                    i++;
3392
                                    sVal = ini.IniReadValue(wp, "CAM-Nick");
3393
                                    if (sVal != "")
2313 - 3394
                                        o[i] = Convert.ToInt16(sVal);
2312 - 3395
                                    i++;
3396
                                    o[i] = 0;
3397
                                    i++;
3398
                                    sVal = ini.IniReadValue(wp, "WP_Event_Channel_Value");
3399
                                    if (sVal != "")
3400
                                        o[i] = Convert.ToInt16(sVal);
3401
                                    i++;
3402
                                    o[i] = "New";
3403
 
3404
                                    dr.ItemArray = o;
3405
                                    dtWaypoints.Rows.Add(dr);
2363 - 3406
                                    _createWP(new PointLatLng((double)o[3], (double)o[4]), (string)dr[2], (int)o[1]);
2315 - 3407
 
2312 - 3408
                                    Dispatcher.Invoke(() => lblWPIndex.Content = k.ToString());
3409
                                    Dispatcher.Invoke(() => lblWPCount.Content = k.ToString());
3410
                                    Dispatcher.Invoke(() => dgvWP.Items.Refresh());
3411
                                    Thread.Sleep(10);
3412
                                }
2359 - 3413
                                _routeUpdate();
2312 - 3414
                            }
3415
                        }
3416
                    }
3417
 
3418
                }
3419
                catch (Exception e)
3420
                {
3421
 
3422
                    MessageBox.Show("Error parsing wpl-file!" + Environment.NewLine + e.Message, "Read wpl-file", MessageBoxButton.OK, MessageBoxImage.Error);
3423
                }
3424
 
3425
            }
3426
        }
2350 - 3427
        void _saveWPLFile()
3428
        {
3429
            if (dtWaypoints.Rows.Count > 0)
3430
            {
3431
                Microsoft.Win32.SaveFileDialog fd = new Microsoft.Win32.SaveFileDialog();
3432
                fd.Filter = "Waypointlists | *.wpl";
3433
                fd.AddExtension = true;
3434
                if (fd.ShowDialog().Value)
3435
                {
3436
                    string file = fd.SafeFileName;
3437
                    IniFile ini = new IniFile(fd.SafeFileName);
3438
                    ini.path = fd.FileName;
3439
                    NumberFormatInfo nfi = new NumberFormatInfo();
3440
                    nfi.NumberDecimalSeparator = ".";
3441
 
3442
                    try
3443
                    {
3444
                        ini.IniWriteValue("General", "FileVersion", "3");
3445
                        ini.IniWriteValue("General", "NumberOfWaypoints", dtWaypoints.Rows.Count.ToString());
3446
                        ini.IniWriteValue("General", "Mapfile", "");
3447
                        for(int i = 1; i<=dtWaypoints.Rows.Count; i++)
3448
                        {
3449
                            ini.IniWriteValue("Point" + i.ToString(), "Latitude", ((double)(dtWaypoints.Rows[i-1][3])).ToString(nfi));
3450
                            ini.IniWriteValue("Point" + i.ToString(), "Longitude", ((double)(dtWaypoints.Rows[i - 1][4])).ToString(nfi));
3451
                            ini.IniWriteValue("Point" + i.ToString(), "Radius", dtWaypoints.Rows[i - 1][9].ToString());
3452
                            ini.IniWriteValue("Point" + i.ToString(), "Altitude", dtWaypoints.Rows[i - 1][5].ToString());
3453
                            ini.IniWriteValue("Point" + i.ToString(), "ClimbRate", dtWaypoints.Rows[i - 1][8].ToString());
3454
                            ini.IniWriteValue("Point" + i.ToString(), "DelayTime", dtWaypoints.Rows[i - 1][10].ToString());
3455
                            ini.IniWriteValue("Point" + i.ToString(), "WP_Event_Channel_Value", dtWaypoints.Rows[i - 1][14].ToString());
3456
                            ini.IniWriteValue("Point" + i.ToString(), "Heading", dtWaypoints.Rows[i - 1][6].ToString());
3457
                            ini.IniWriteValue("Point" + i.ToString(), "Speed", dtWaypoints.Rows[i - 1][7].ToString());
3458
                            ini.IniWriteValue("Point" + i.ToString(), "CAM-Nick", dtWaypoints.Rows[i - 1][12].ToString());
3459
                            ini.IniWriteValue("Point" + i.ToString(), "Type", ((int)dtWaypoints.Rows[i - 1][1]+1).ToString());
3460
                            ini.IniWriteValue("Point" + i.ToString(), "Prefix", dtWaypoints.Rows[i - 1][2].ToString().Substring(0, 1)); // == "!" ? "0" : dtWaypoints.Rows[i - 1][2].ToString().Substring(0, 1));
3461
                            ini.IniWriteValue("Point" + i.ToString(), "AutoTrigger", dtWaypoints.Rows[i - 1][11].ToString());
3462
                        }
3463
                        MessageBox.Show(dtWaypoints.Rows.Count.ToString() + " points saved to " + file, "Waypointlist saved", MessageBoxButton.OK, MessageBoxImage.Information);
3464
                    }
3465
                    catch { }
3466
                }
3467
            }
3468
            else
3469
                MessageBox.Show("Nothing to save...");
3470
        }
3471
        private void btnSaveWPLFile_Click(object sender, RoutedEventArgs e)
3472
        {
3473
            _saveWPLFile();
3474
        }
3475
        /// <summary>
3476
        /// set the selected color for the route
3477
        /// </summary>
3478
        /// <param name="color"></param>
3479
        /// <returns></returns>
2328 - 3480
        Brush _getBrush(string color)
3481
        {
3482
            switch (color)
3483
            {
3484
                case "red":
3485
                    return Brushes.Red;
3486
                case "green":
3487
                    return Brushes.Lime;
3488
                case "blue":
3489
                    return Brushes.Aqua;
3490
                case "pink":
3491
                    return Brushes.Magenta;
3492
                case "yellow":
3493
                    return Brushes.Yellow;
3494
                default:
3495
                    return Brushes.Magenta;
3496
            }
3497
        }
2359 - 3498
        void _routeUpdate()
3499
        {
3500
            Dispatcher.Invoke(() =>
3501
            {
3502
                if (comboBoxRouteColor.SelectionBoxItem != null)
3503
                {
3504
                    string s = comboBoxRouteColor.SelectionBoxItem.ToString();
3505
                    mRouteWP = new GMapRoute(wpList, _getBrush(s));
3506
                }
3507
                else
3508
                    mRouteWP = new GMapRoute(wpList, null);
3509
 
3510
                if (_bShowWPRoute)
2368 - 3511
                    MainMap.Markers.Add(mRouteWP);
2359 - 3512
            });
3513
 
3514
            MapRoute mr = new MapRoute(wpList, "WPList");
3515
            Dispatcher.Invoke(() => lblWPRouteDistance.Content = (mr.Distance * 1000).ToString("0 m"));
3516
        }
2363 - 3517
        GMapMarker _createWP(PointLatLng p, string name, int type)
3518
        {
3519
            GMapMarker wpMarker = new GMapMarker(p);
2385 - 3520
            Dispatcher.Invoke(()=>
3521
            {
3522
                wpMarker.Shape = new CustomMarkerWP(this, wpMarker, name, type);
3523
                wpMarker.Offset = new System.Windows.Point(-11.5, -11.5);
3524
                wpMarker.ZIndex = 100;
3525
                _setMarkerColor(wpMarker, type);
3526
                MainMap.Markers.Add(wpMarker);
3527
                if (type == 0 || type == 3)
3528
                    wpList.Add(p);
3529
            });
2363 - 3530
            return wpMarker;
3531
        }
2315 - 3532
        void _setMarkerColor(GMapMarker wpMarker,int iType)
3533
        {
2369 - 3534
            if(wpMarker != null)
2315 - 3535
            Dispatcher.Invoke(() =>
3536
            {
3537
                switch (iType)
3538
                {
3539
                    case 0:
3540
                        if (comboBoxWPColor.SelectionBoxItem != null)
3541
                        {
3542
                            string s = comboBoxWPColor.SelectionBoxItem.ToString();
3543
                            ((CustomMarkerWP)(wpMarker.Shape)).setColor(s);
3544
                        }
3545
                        else
2372 - 3546
                            ((CustomMarkerWP)(wpMarker.Shape)).setColor("green");
2315 - 3547
                        break;
3548
                    case 1:
3549
                        if (comboBoxPOIColor.SelectionBoxItem != null)
3550
                        {
3551
                            string s = comboBoxPOIColor.SelectionBoxItem.ToString();
3552
                            ((CustomMarkerWP)(wpMarker.Shape)).setColor(s);
3553
                        }
3554
                        else
2372 - 3555
                            ((CustomMarkerWP)(wpMarker.Shape)).setColor("pink");
2315 - 3556
                        break;
3557
                    case 2:
3558
                        if (comboBoxFSColor.SelectionBoxItem != null)
3559
                        {
3560
                            string s = comboBoxFSColor.SelectionBoxItem.ToString();
3561
                            ((CustomMarkerWP)(wpMarker.Shape)).setColor(s);
3562
                        }
3563
                        else
3564
                            ((CustomMarkerWP)(wpMarker.Shape)).setColor("red");
3565
                        break;
2372 - 3566
                    case 3:
3567
                        if (comboBoxLandingColor.SelectionBoxItem != null)
3568
                        {
3569
                            string s = comboBoxLandingColor.SelectionBoxItem.ToString();
3570
                            ((CustomMarkerWP)(wpMarker.Shape)).setColor(s);
3571
                        }
3572
                        else
3573
                            ((CustomMarkerWP)(wpMarker.Shape)).setColor("blue");
3574
                        break;
2315 - 3575
                    default:
3576
                        ((CustomMarkerWP)(wpMarker.Shape)).setColor("red");
3577
                        break;
3578
                }
3579
            });
2312 - 3580
 
2315 - 3581
        }
2372 - 3582
        void _MarkerColorSelection(object sender,int type)
3583
        {
2315 - 3584
            Dispatcher.Invoke(() =>
3585
            {
2372 - 3586
                if (((ComboBox)sender).SelectionBoxItem != null)
2315 - 3587
                {
3588
                    for (int k = 0; k < MainMap.Markers.Count; k++)
3589
                    {
3590
                        GMapMarker p = MainMap.Markers[k];
2372 - 3591
                        if (p.Shape != null && p.Shape.GetType() == typeof(CustomMarkerWP))
2315 - 3592
                        {
2372 - 3593
                            if (((CustomMarkerWP)p.Shape).WPType == type)
2315 - 3594
                            {
2372 - 3595
                                string s = ((ComboBox)sender).SelectionBoxItem.ToString();
2315 - 3596
                                ((CustomMarkerWP)(p.Shape)).setColor(s);
3597
                            }
3598
                        }
3599
                    }
3600
                }
3601
            });
2287 - 3602
        }
2379 - 3603
        private void comboBoxWPColor_DropDownClosed(object sender, EventArgs e)
2318 - 3604
        {
2376 - 3605
            _MarkerColorSelection(sender, 0);
3606
        }
3607
        private void comboBoxPOIColor_DropDownClosed(object sender, EventArgs e)
3608
        {
3609
            _MarkerColorSelection(sender, 1);
3610
        }
3611
        private void comboBoxFSColor_DropDownClosed(object sender, EventArgs e)
3612
        {
3613
            _MarkerColorSelection(sender, 2);
3614
        }
3615
        private void comboBoxLandingColor_DropDownClosed(object sender, EventArgs e)
3616
        {
3617
            _MarkerColorSelection(sender,3);
3618
        }
2385 - 3619
        private void comboBoxCopterColor_DropDownClosed(object sender, EventArgs e)
2376 - 3620
        {
2318 - 3621
            Dispatcher.Invoke(() => {
3622
                if (comboBoxCopterColor.SelectionBoxItem != null)
3623
                {
3624
                    string s = comboBoxCopterColor.SelectionBoxItem.ToString();
2385 - 3625
                    ((CustomMarkerCopter)(copter.Shape)).setCopterColor(s);
2318 - 3626
                }
3627
                else
2385 - 3628
                    ((CustomMarkerCopter)(copter.Shape)).setCopterColor("red");
2318 - 3629
            });
3630
        }
2385 - 3631
        private void comboBoxCopterHeadingColor_DropDownClosed(object sender, EventArgs e)
3632
        {
3633
            Dispatcher.Invoke(() => {
3634
                if (comboBoxCopterHeadingColor.SelectionBoxItem != null)
3635
                {
3636
                    string s = comboBoxCopterHeadingColor.SelectionBoxItem.ToString();
3637
                    ((CustomMarkerCopter)(copter.Shape)).setHeadingColor(s);
3638
                }
3639
                else
3640
                    ((CustomMarkerCopter)(copter.Shape)).setHeadingColor("red");
3641
            });
3642
        }
2328 - 3643
        private void comboBoxRouteColor_DropDownClosed(object sender, EventArgs e)
3644
        {
3645
            Dispatcher.Invoke(() =>
3646
            {
3647
                if (comboBoxRouteColor.SelectionBoxItem != null)
3648
                {
3649
                    string s = comboBoxRouteColor.SelectionBoxItem.ToString();
3650
                    MainMap.Markers.Remove(mRouteWP);
3651
                    mRouteWP = new GMapRoute(wpList, _getBrush(s));
3652
                    if (_bShowWPRoute)
3653
                        MainMap.Markers.Add(mRouteWP);
3654
                }
3655
            });
3656
        }
3657
        private void checkBoxShowWPRoute_Click(object sender, RoutedEventArgs e)
3658
        {
3659
            _bShowWPRoute = (bool)checkBoxShowWPRoute.IsChecked;
3660
            if (_bShowWPRoute)
3661
            {
3662
                if (mRouteWP != null)
3663
                    MainMap.Markers.Add(mRouteWP);
3664
            }
3665
            else
3666
            {
3667
                if (mRouteWP != null)
3668
                    MainMap.Markers.Remove(mRouteWP);
3669
            }
3670
        }
2315 - 3671
        private void btnLoadWPLFile_Click(object sender, RoutedEventArgs e)
2287 - 3672
        {
2315 - 3673
            _readWPLFile();
2287 - 3674
        }
2335 - 3675
        private void btnClearWPList_Click(object sender, RoutedEventArgs e)
3676
        {
3677
            _clearMapMarkers(typeof(CustomMarkerWP));
2347 - 3678
            _clearMapMarkers(typeof(CustomMarkerWPActive));
2335 - 3679
            wpList.Clear();
3680
            if (mRouteWP != null)
3681
                MainMap.Markers.Remove(mRouteWP);
2347 - 3682
            //if (wpActiveMarker != null)
3683
            //    MainMap.Markers.Remove(wpActiveMarker);
2335 - 3684
            dtWaypoints.Rows.Clear();
2356 - 3685
            _wpEdit = -1;
2368 - 3686
            _wpIndex = -1;
2335 - 3687
            Dispatcher.Invoke(() => dgvWP.Items.Refresh());
3688
            Dispatcher.Invoke(() => lblWPIndex.Content = 0);
3689
            Dispatcher.Invoke(() => lblWPCount.Content = 0);
3690
            Dispatcher.Invoke(() => lblWPRouteDistance.Content = "0 m");
3691
        }
2340 - 3692
        private void btnClearCopterList_Click(object sender, RoutedEventArgs e)
3693
        {
3694
            Thread t = new Thread(new ThreadStart(clearCopterWPList));
3695
            t.Start();
3696
        }
2355 - 3697
        private void btnSendActiveWP_Click(object sender, RoutedEventArgs e)
2340 - 3698
        {
3699
            if (dgvWP.SelectedIndex > -1 && dgvWP.SelectedIndex < dtWaypoints.Rows.Count)
3700
            {
2372 - 3701
                if (_wpCount > 0)
2376 - 3702
                    _sendWayPoint(dtWaypoints.Rows[dgvWP.SelectedIndex], -1, 's',false);
2372 - 3703
                else
2376 - 3704
                    _sendWayPoint(dtWaypoints.Rows[dgvWP.SelectedIndex], 1, 's',false);
2363 - 3705
 
2372 - 3706
                //int index = dgvWP.SelectedIndex;
3707
                //Thread t = new Thread(() => _sendWPList(index));
3708
                //t.Start();
2354 - 3709
 
3710
                Dispatcher.Invoke(() => {
3711
                    DataGridRow row;
2368 - 3712
                    if (_wpEdit > -1 && _wpEdit < dgvWP.ItemContainerGenerator.Items.Count)
2354 - 3713
                    {
2368 - 3714
                        row = (DataGridRow)dgvWP.ItemContainerGenerator.ContainerFromIndex(_wpEdit);
2354 - 3715
                        row.Background = new SolidColorBrush(Colors.Transparent);
3716
                        row.BorderBrush = new SolidColorBrush(Colors.Transparent);
3717
                        row.BorderThickness = new Thickness(0);
2376 - 3718
                        dgvWP.UpdateLayout();
2354 - 3719
                    }
2376 - 3720
                    //_wpEdit = dgvWP.SelectedIndex;
3721
                    //row = (DataGridRow)dgvWP.ItemContainerGenerator.ContainerFromIndex(_wpEdit);
3722
                    //row.Background = new SolidColorBrush(Color.FromArgb(80, 0, 255, 100));
3723
                    //row.BorderBrush = new SolidColorBrush(Colors.SpringGreen);
3724
                    //row.BorderThickness = new Thickness(2);
2354 - 3725
                });
2340 - 3726
            }
3727
        }
2385 - 3728
        private void btnEditWPSendToCopter_Click(object sender, RoutedEventArgs e)
3729
        {
3730
            if (dgvWP.SelectedIndex > -1 && dgvWP.SelectedIndex < dtWaypoints.Rows.Count)
3731
            {
3732
 
3733
                object[] o = new object[16];
3734
                o[0] = dgvWP.SelectedIndex + 1;
3735
                o[1] = cbWPEditType.SelectedIndex;
3736
                o[2] = tbWPEditPrefix.Text + (dgvWP.SelectedIndex + 1).ToString();
3737
                o[3] = Convert.ToDouble(tbWPEditLat.Text.Replace('.', ','));
3738
                o[4] = Convert.ToDouble(tbWPEditLon.Text.Replace('.', ','));
3739
                o[5] = tbWPEditAlt.Text;
3740
                switch (cbWPEditHeading.SelectedIndex)
3741
                {
3742
                    case 0:
3743
                        o[6] = "0";
3744
                        break;
3745
                    case 1:
3746
                        o[6] = "-" + tbWPEditHeading.Text;
3747
                        break;
3748
                    case 2:
3749
                        o[6] = tbWPEditHeading.Text;
3750
                        break;
3751
                }
3752
                switch (cbWPEditSpeed.SelectedIndex)
3753
                {
3754
                    case 0:
3755
                        o[7] = "0";
3756
                        break;
3757
                    case 1:
3758
                        o[7] = (System.Convert.ToDouble(tbWPEditSpeed.Text.Replace('.', ',')) * 10).ToString("0");
3759
                        break;
3760
                    case 2:
3761
                        o[7] = (256 - Convert.ToInt16(tbWPEditSpeed.Text)).ToString();
3762
                        break;
3763
                }
3764
                switch (cbWPEditClimbrate.SelectedIndex)
3765
                {
3766
                    case 0:
3767
                        o[8] = "255";
3768
                        break;
3769
                    case 1:
3770
                        o[8] = (System.Convert.ToDouble(tbWPEditClimbrate.Text.Replace('.', ',')) * 10).ToString("0");
3771
                        break;
3772
                }
3773
                o[9] = tbWPEditRadius.Text;
3774
                o[10] = tbWPEditHoldtime.Text;
3775
                o[11] = tbWPEditAutoTrigger.Text;
3776
                switch (cbWPEditCamAngle.SelectedIndex)
3777
                {
3778
                    case 0:
3779
                        o[12] = "0";
3780
                        break;
3781
                    case 1:
3782
                        o[12] = "255";
3783
                        break;
3784
                    case 2:
3785
                        o[12] = tbWPEditCamAngle.Text;
3786
                        break;
3787
                }
3788
                o[13] = 0;
3789
                o[14] = tbWPEditOut1.Text;
3790
                DataRow dr = dtWaypoints.NewRow();
3791
                dr.ItemArray = o;
3792
 
3793
                if (_wpCount > 0)
3794
                    _sendWayPoint(dr, -1, 'w', false);
3795
                else
3796
                    _sendWayPoint(dr, 1, 'w', false);
2399 - 3797
 
3798
                if(_wpIndex > -1 && _wpIndex < dtWaypoints.Rows.Count)
3799
                    _sendWayPoint(dtWaypoints.Rows[_wpIndex], _wpIndex + 1, 's', false);
2385 - 3800
            }
3801
        }
2376 - 3802
        private void btnWPSimulateStart_Click(object sender, RoutedEventArgs e)
3803
        {
3804
            _Simulate = !_Simulate;
3805
            if (dtWaypoints.Rows.Count > 0)
3806
            {
3807
                DataRow dr = dtWaypoints.Rows[0];
3808
                dr[13] = _Simulate ? 3 : 0;
2379 - 3809
                _sendWayPoint(dr, 0, 's', true);
2381 - 3810
                rectSimulate.Visibility = lblSimu.Visibility = _Simulate ? Visibility.Visible : Visibility.Hidden;
2376 - 3811
            }
3812
        }
2355 - 3813
        private void dgvWP_MouseUp(object sender, MouseButtonEventArgs e)
3814
        {
2359 - 3815
            _dgvWPselectEditRow();
3816
        }
3817
        private void dgvWP_MouseDoubleClick(object sender, MouseButtonEventArgs e)
3818
        {
3819
        }
3820
        void _dgvWPselectEditRow()
3821
        {
2355 - 3822
            if (dgvWP.SelectedIndex > -1 && dgvWP.SelectedIndex < dtWaypoints.Rows.Count)
3823
            {
2368 - 3824
               Dispatcher.Invoke(() => {
2355 - 3825
                    DataGridRow row;
2368 - 3826
                    if (_wpEdit > -1 && _wpEdit < dgvWP.ItemContainerGenerator.Items.Count)
2355 - 3827
                    {
3828
                        row = (DataGridRow)dgvWP.ItemContainerGenerator.ContainerFromIndex(_wpEdit);
3829
                        row.Background = new SolidColorBrush(Colors.Transparent);
3830
                        row.BorderBrush = new SolidColorBrush(Colors.Transparent);
3831
                        row.BorderThickness = new Thickness(0);
3832
                    }
3833
                    _wpEdit = dgvWP.SelectedIndex;
3834
                    row = (DataGridRow)dgvWP.ItemContainerGenerator.ContainerFromIndex(_wpEdit);
3835
                    row.Background = new SolidColorBrush(Color.FromArgb(80, 0, 100, 255));
3836
                    row.BorderBrush = new SolidColorBrush(Colors.Aqua);
3837
                    row.BorderThickness = new Thickness(2);
3838
                    dgvWP.UpdateLayout();
2340 - 3839
 
2355 - 3840
                    _setWPEditFields(_wpEdit);
3841
                });
3842
            }
3843
        }
3844
        void _setWPEditFields(int index)
3845
        {
3846
            int iVal;
3847
            cbWPEditType.SelectedIndex = (int)dtWaypoints.Rows[index][1];
3848
            tbWPEditPrefix.Text = dtWaypoints.Rows[index][2].ToString().Substring(0,1);
3849
            tbWPEditLat.Text = dtWaypoints.Rows[index][3].ToString();
3850
            tbWPEditLon.Text = dtWaypoints.Rows[index][4].ToString();
3851
            tbWPEditAlt.Text = dtWaypoints.Rows[index][5].ToString();
3852
            iVal = Convert.ToInt16(dtWaypoints.Rows[index][6]);
3853
            if (iVal == 0)
3854
            {
3855
                cbWPEditHeading.SelectedIndex = 0;
3856
                tbWPEditHeading.Text = " - - -";
3857
                tbWPEditHeading.IsReadOnly = true;
3858
            }
3859
            if (iVal > 0 && iVal < 360)
3860
            {
3861
                cbWPEditHeading.SelectedIndex = 2;
3862
                tbWPEditHeading.Text = iVal.ToString();
3863
                tbWPEditHeading.IsReadOnly = false;
3864
            }
3865
            if (iVal < 0)
3866
            {
3867
                cbWPEditHeading.SelectedIndex = 1;
3868
                tbWPEditHeading.Text = (Math.Abs(iVal).ToString());
3869
                tbWPEditHeading.IsReadOnly = false;
3870
            }
3871
            iVal = Convert.ToInt16(dtWaypoints.Rows[index][7]);
3872
            if (iVal == 0)
3873
            {
3874
                cbWPEditSpeed.SelectedIndex = 0;
3875
                tbWPEditSpeed.Text = "MAX";
3876
                tbWPEditSpeed.IsReadOnly = true;
3877
            }
3878
            if (iVal > 0 && iVal < 248)
3879
            {
3880
                cbWPEditSpeed.SelectedIndex = 1;
3881
                tbWPEditSpeed.Text = ((double)iVal * 0.1).ToString();
3882
                tbWPEditSpeed.IsReadOnly = false;
3883
            }
3884
            if (iVal > 247)
3885
            {
3886
                cbWPEditSpeed.SelectedIndex = 256 - iVal + 1;
3887
                tbWPEditSpeed.Text = "";
3888
                tbWPEditSpeed.IsReadOnly = true;
3889
            }
3890
            iVal = Convert.ToInt16(dtWaypoints.Rows[index][8]);
3891
            if (iVal == 255)
3892
            {
3893
                cbWPEditClimbrate.SelectedIndex = 0;
3894
                tbWPEditClimbrate.Text = "AUTO";
3895
                tbWPEditClimbrate.IsReadOnly = true;
3896
            }
3897
            else
3898
            {
3899
                cbWPEditClimbrate.SelectedIndex = 1;
3900
                tbWPEditClimbrate.Text = (System.Convert.ToDouble(iVal) / 10).ToString("0.0");
3901
                tbWPEditClimbrate.IsReadOnly = false;
3902
            }
3903
            iVal = Convert.ToInt16(dtWaypoints.Rows[index][9]);
3904
            tbWPEditRadius.Text = iVal.ToString();
3905
            iVal = Convert.ToInt16(dtWaypoints.Rows[index][10]);
3906
            tbWPEditHoldtime.Text = iVal.ToString();
3907
            iVal = Convert.ToInt16(dtWaypoints.Rows[index][11]);
3908
            tbWPEditAutoTrigger.Text = iVal.ToString();
3909
            iVal = Convert.ToInt16(dtWaypoints.Rows[index][12]);
3910
            if (iVal == 0)
3911
            {
3912
                cbWPEditCamAngle.SelectedIndex = 0;
3913
                tbWPEditCamAngle.Text = " - - - ";
3914
                tbWPEditCamAngle.IsReadOnly = true;
3915
            }
3916
            if (iVal < 0 | iVal == 255)
3917
            {
3918
                cbWPEditCamAngle.SelectedIndex = 1;
3919
                tbWPEditCamAngle.Text = "AUTO";
3920
                tbWPEditCamAngle.IsReadOnly = true;
3921
            }
3922
            if (iVal > 0 & iVal < 255)
3923
            {
3924
                cbWPEditCamAngle.SelectedIndex = 2;
3925
                tbWPEditCamAngle.Text = iVal.ToString();
3926
                tbWPEditCamAngle.IsReadOnly = false;
3927
            }
3928
            iVal = Convert.ToInt16(dtWaypoints.Rows[index][14]);
3929
            tbWPEditOut1.Text = iVal.ToString();
3930
 
3931
        }
3932
 
2361 - 3933
        private void btnEditWPSave_Click(object sender, RoutedEventArgs e)
3934
        {
2363 - 3935
            if(dgvWP.SelectedIndex > -1 && dgvWP.SelectedIndex < dtWaypoints.Rows.Count)
3936
            {
2369 - 3937
                string oldName = (string)dtWaypoints.Rows[dgvWP.SelectedIndex][2];
2372 - 3938
                int oldType = (int)dtWaypoints.Rows[dgvWP.SelectedIndex][1];
3939
                PointLatLng pOld = new PointLatLng((double)dtWaypoints.Rows[dgvWP.SelectedIndex][3], (double)dtWaypoints.Rows[dgvWP.SelectedIndex][4]);
3940
                int i = wpList.IndexOf(pOld);
2363 - 3941
                dtWaypoints.Rows[dgvWP.SelectedIndex][1] = cbWPEditType.SelectedIndex;
3942
                dtWaypoints.Rows[dgvWP.SelectedIndex][2] = tbWPEditPrefix.Text + (dgvWP.SelectedIndex + 1).ToString();
3943
                dtWaypoints.Rows[dgvWP.SelectedIndex][3] = Convert.ToDouble(tbWPEditLat.Text.Replace('.', ','));
3944
                dtWaypoints.Rows[dgvWP.SelectedIndex][4] = Convert.ToDouble(tbWPEditLon.Text.Replace('.', ','));
2372 - 3945
                if (i > -1)
3946
                {
3947
                    if((int)dtWaypoints.Rows[dgvWP.SelectedIndex][1] == 0 || (int)dtWaypoints.Rows[dgvWP.SelectedIndex][1] == 3)
3948
                        wpList[i] = (new PointLatLng((double)dtWaypoints.Rows[dgvWP.SelectedIndex][3], (double)dtWaypoints.Rows[dgvWP.SelectedIndex][4]));
3949
                    else
3950
                        wpList.Remove(pOld);
3951
                }
3952
                else
3953
                {
3954
                    if ((int)dtWaypoints.Rows[dgvWP.SelectedIndex][1] == 0 || (int)dtWaypoints.Rows[dgvWP.SelectedIndex][1] == 3)
3955
                    {
3956
                        int found = 0;
3957
                        for (int k = 0; k < dgvWP.SelectedIndex; k++)
3958
                            if ((int)dtWaypoints.Rows[k][1] == 0)
3959
                                found++;
3960
                        wpList.Insert(found, new PointLatLng((double)dtWaypoints.Rows[dgvWP.SelectedIndex][3], (double)dtWaypoints.Rows[dgvWP.SelectedIndex][4]));
3961
                    }
3962
                }
2363 - 3963
                dtWaypoints.Rows[dgvWP.SelectedIndex][5] = tbWPEditAlt.Text;
3964
                switch (cbWPEditHeading.SelectedIndex)
3965
                {
3966
                    case 0:
3967
                        dtWaypoints.Rows[dgvWP.SelectedIndex][6] = "0";
3968
                        break;
3969
                    case 1:
3970
                        dtWaypoints.Rows[dgvWP.SelectedIndex][6] = "-" + tbWPEditHeading.Text;
3971
                        break;
3972
                    case 2:
3973
                        dtWaypoints.Rows[dgvWP.SelectedIndex][6] = tbWPEditHeading.Text;
3974
                        break;
3975
                }
3976
                switch (cbWPEditSpeed.SelectedIndex)
3977
                {
3978
                    case 0:
3979
                        dtWaypoints.Rows[dgvWP.SelectedIndex][7] = "0";
3980
                        break;
3981
                    case 1:
3982
                        dtWaypoints.Rows[dgvWP.SelectedIndex][7] = (System.Convert.ToDouble(tbWPEditSpeed.Text.Replace('.', ',')) * 10).ToString("0");
3983
                        break;
3984
                    case 2:
3985
                        dtWaypoints.Rows[dgvWP.SelectedIndex][7] = (256 - Convert.ToInt16(tbWPEditSpeed.Text)).ToString();
3986
                        break;
3987
                }
3988
                switch (cbWPEditClimbrate.SelectedIndex)
3989
                {
3990
                    case 0:
3991
                        dtWaypoints.Rows[dgvWP.SelectedIndex][8] = "255";
3992
                        break;
3993
                    case 1:
3994
                        dtWaypoints.Rows[dgvWP.SelectedIndex][8] = (System.Convert.ToDouble(tbWPEditClimbrate.Text.Replace('.',',')) * 10).ToString("0");
3995
                        break;
3996
                }
3997
                dtWaypoints.Rows[dgvWP.SelectedIndex][9] = tbWPEditRadius.Text;
3998
                dtWaypoints.Rows[dgvWP.SelectedIndex][10] = tbWPEditHoldtime.Text;
3999
                dtWaypoints.Rows[dgvWP.SelectedIndex][11] = tbWPEditAutoTrigger.Text;
4000
                switch (cbWPEditCamAngle.SelectedIndex)
4001
                {
4002
                    case 0:
4003
                        dtWaypoints.Rows[dgvWP.SelectedIndex][12] = "0";
4004
                        break;
4005
                    case 1:
4006
                        dtWaypoints.Rows[dgvWP.SelectedIndex][12] = "255";
4007
                        break;
4008
                    case 2:
4009
                        dtWaypoints.Rows[dgvWP.SelectedIndex][12] = tbWPEditCamAngle.Text;
4010
                        break;
4011
                }
4012
                dtWaypoints.Rows[dgvWP.SelectedIndex][14] = tbWPEditOut1.Text;
2361 - 4013
 
2369 - 4014
                // _clearMapMarkers(typeof(CustomMarkerWP));
4015
                _repositionWPMarker(new PointLatLng((double)dtWaypoints.Rows[dgvWP.SelectedIndex][3], (double)dtWaypoints.Rows[dgvWP.SelectedIndex][4]),oldName);
4016
                _renameWPMarker(oldName, (string)dtWaypoints.Rows[dgvWP.SelectedIndex][2]);
2363 - 4017
                _clearMapMarkers(typeof(CustomMarkerWPActive));
2369 - 4018
                _setMarkerColor(_findWPMarker((string)dtWaypoints.Rows[dgvWP.SelectedIndex][2]), (int)dtWaypoints.Rows[dgvWP.SelectedIndex][1]);
2372 - 4019
                _WPMarkerSetType((string)dtWaypoints.Rows[dgvWP.SelectedIndex][2], (int)dtWaypoints.Rows[dgvWP.SelectedIndex][1]);
2369 - 4020
               // wpList.Clear();
2363 - 4021
                if (mRouteWP != null)
4022
                    MainMap.Markers.Remove(mRouteWP);
4023
 
2369 - 4024
                //for (int k = 0; k < dtWaypoints.Rows.Count; k++)
4025
                //{
4026
                //    _createWP(new PointLatLng((double)dtWaypoints.Rows[k][3], (double)dtWaypoints.Rows[k][4]), (string)dtWaypoints.Rows[k][2], (int)dtWaypoints.Rows[k][1]);
4027
                //}
2363 - 4028
                _routeUpdate();
4029
                dgvWP.Items.Refresh();
4030
 
4031
            }
4032
 
2361 - 4033
        }
4034
        private void btnEditWPDel_Click(object sender, RoutedEventArgs e)
4035
        {
2368 - 4036
            if (dgvWP.SelectedIndex > -1 && dgvWP.SelectedIndex < dtWaypoints.Rows.Count)
4037
            {
4038
                int index = dgvWP.SelectedIndex;
4039
                Dispatcher.Invoke(() => {
4040
                    DataGridRow row;
4041
                    if (_wpEdit > -1 && _wpEdit < dgvWP.ItemContainerGenerator.Items.Count)
4042
                    {
4043
                        row = (DataGridRow)dgvWP.ItemContainerGenerator.ContainerFromIndex(_wpEdit);
4044
                        row.Background = new SolidColorBrush(Colors.Transparent);
4045
                        row.BorderBrush = new SolidColorBrush(Colors.Transparent);
4046
                        row.BorderThickness = new Thickness(0);
4047
                    }
2372 - 4048
                    if ((int)dtWaypoints.Rows[index][1] == 0 || (int)dtWaypoints.Rows[index][1] == 3)
2368 - 4049
                        wpList.Remove(new PointLatLng((double)dtWaypoints.Rows[index][3], (double)dtWaypoints.Rows[index][4]));
4050
                    _clearWPMarker((string)dtWaypoints.Rows[index][2]);
2369 - 4051
                    if (wpActiveMarker != null)
4052
                        MainMap.Markers.Remove(wpActiveMarker);
2368 - 4053
                    dtWaypoints.Rows[index].Delete();
4054
                    _wpIndex = -1;
4055
                    _wpEdit = -1;
4056
                    for (int i = index; i < dtWaypoints.Rows.Count; i++) //change the index of points behind deleted point + rename to new index
4057
                    {
4058
                        dtWaypoints.Rows[i][0] = i + 1;
4059
                        string s1 = (string)dtWaypoints.Rows[i][2]; //old name of WP (Prefix + index)
4060
                        string s2 = s1.Substring(0, 1) + (i + 1).ToString(); //new name of WP
4061
                        _renameWPMarker(s1, s2);
4062
                        dtWaypoints.Rows[i][2] = s2;
4063
                    }
4064
                    lblWPCount.Content = dtWaypoints.Rows.Count;
4065
                    if (mRouteWP != null)
4066
                        MainMap.Markers.Remove(mRouteWP);
4067
                    _routeUpdate();
2361 - 4068
 
2368 - 4069
                    dgvWP.UpdateLayout();
4070
                });
4071
            }
2361 - 4072
        }
2366 - 4073
        private void tbWPEdit_TouchDown(object sender, TouchEventArgs e)
4074
        {
4075
            _wpWEdit(sender);
4076
        }
2361 - 4077
        private void tbWPEdit_KeyDown(object sender, KeyEventArgs e)
4078
        {
2366 - 4079
            _wpWEdit(sender);
4080
        }
2369 - 4081
        private void tbWPEdit_MouseDown(object sender, MouseButtonEventArgs e)
4082
        {
4083
            _wpWEdit(sender);
4084
        }
2366 - 4085
        void _wpWEdit(object sender)
4086
        {
2369 - 4087
           // if (!((TextBox)sender).IsReadOnly)
2361 - 4088
            {
4089
                KeyPad.Keypad k = new KeyPad.Keypad(this);
4090
 
2363 - 4091
                switch (((TextBox)sender).Name)
4092
                {
4093
                    case "tbWPEditLat":
4094
                        k.Title = "Latitude";
4095
                        k.LENGTH = 17;
4096
                        k.MAX = 359.9;
4097
                        break;
4098
                    case "tbWPEditLon":
4099
                        k.Title = "Longitude";
4100
                        k.LENGTH = 17;
4101
                        k.MAX = 359.9;
4102
                        break;
4103
                    case "tbWPEditAlt":
4104
                        k.Title = "Altitude";
4105
                        k.LENGTH = 3;
4106
                        k.MAX = 254;
4107
                        k.disableDecimal();
4108
                        break;
4109
                    case "tbWPEditHeading":
4110
                        k.Title = "Heading";
4111
                        k.LENGTH = 3;
4112
                        k.MAX = 359;
4113
                        k.MIN = 1;
4114
                        k.disableDecimal();
4115
                        break;
4116
                    case "tbWPEditSpeed":
4117
                        k.Title = "Speed";
4118
                        k.LENGTH = 4;
4119
                        k.MAX = 24.7;
4120
                        k.MIN = 0.1;
4121
                        break;
4122
                    case "tbWPEditClimbrate":
4123
                        k.Title = "Climbrate";
4124
                        k.LENGTH = 4;
4125
                        k.MAX = 25.4;
4126
                        k.MIN = 0.1;
4127
                        break;
4128
                    case "tbWPEditRadius":
4129
                        k.Title = "Radius";
4130
                        k.LENGTH = 3;
4131
                        k.MAX = 254;
4132
                        k.disableDecimal();
4133
                        break;
4134
                    case "tbWPEditHoldtime":
4135
                        k.Title = "Holdtime";
4136
                        k.LENGTH = 3;
4137
                        k.MAX = 254;
4138
                        break;
4139
                    case "tbWPEditAutoTrigger":
4140
                        k.Title = "Autotrigger";
4141
                        k.LENGTH = 3;
4142
                        k.MAX = 254;
4143
                        k.disableDecimal();
4144
                        break;
4145
                    case "tbWPEditCamAngle":
4146
                        k.Title = "Camera angle";
4147
                        k.LENGTH = 3;
4148
                        k.MAX = 254;
4149
                        k.MIN = 1;
4150
                        k.disableDecimal();
4151
                        break;
4152
                    case "tbWPEditOut1":
4153
                        k.Title = "OUT1 timer interval";
4154
                        k.LENGTH = 3;
4155
                        k.MAX = 254;
4156
                        k.disableDecimal();
4157
                        break;
4158
                }
4159
                k.Result = ((TextBox)sender).Text;
2366 - 4160
                if (k.ShowDialog() == true && k.Result.Length > 0)
2363 - 4161
                    ((TextBox)sender).Text = k.Result;
2361 - 4162
            }
2366 - 4163
 
2361 - 4164
        }
4165
        private void btnWPAddCurrentPos_Click(object sender, RoutedEventArgs e)
2356 - 4166
        {
2359 - 4167
            object[] o = new object[16];
2356 - 4168
 
2359 - 4169
            o[0] = dgvWP.ItemContainerGenerator.Items.Count+1;
4170
            o[1] = 0;
4171
           //     cbWPEditType.SelectedIndex = 0;
4172
          //  tbWPEditPrefix.Text = "P";
4173
            o[2] = "P" + o[0].ToString();
4174
         //   tbWPEditLat.Text = copter.Position.Lat.ToString();
4175
            o[3] = copter.Position.Lat;
4176
          //  tbWPEditLon.Text = copter.Position.Lng.ToString();
4177
            o[4] = copter.Position.Lng;            
4178
         //   tbWPEditAlt.Text = ((double)iAnalogData[4] / (double)10).ToString();
4179
            o[5] = iAnalogData[4].ToString();
2356 - 4180
 
2359 - 4181
        //    cbWPEditHeading.SelectedIndex = 2;
4182
            o[6] = tbWPEditHeading.Text = iAnalogData[10].ToString();
4183
        //    tbWPEditHeading.IsReadOnly = false;
2356 - 4184
 
2359 - 4185
       //     cbWPEditSpeed.SelectedIndex = 1;
4186
       //     tbWPEditSpeed.Text = "5.0";
4187
       //     tbWPEditSpeed.IsReadOnly = false;
2372 - 4188
            o[7] = "10";
2356 - 4189
 
2359 - 4190
      //      cbWPEditClimbrate.SelectedIndex = 1;
4191
     //       tbWPEditClimbrate.Text = "5.0";
4192
     //       tbWPEditClimbrate.IsReadOnly = false;
2372 - 4193
            o[8] = "10";
2356 - 4194
 
2359 - 4195
     //       tbWPEditRadius.Text = "10";
2372 - 4196
            o[9] = "5";
2359 - 4197
     //       tbWPEditHoldtime.Text = "5";
4198
            o[10] = "5";
4199
      //      tbWPEditAutoTrigger.Text = "0";
4200
            o[11] = "0";
4201
     //       cbWPEditCamAngle.SelectedIndex = 1;
4202
     //       tbWPEditCamAngle.Text = "AUTO";
4203
     //       tbWPEditCamAngle.IsReadOnly = true;
4204
            o[12] = "255";
2356 - 4205
 
2359 - 4206
            o[13] = "0";
4207
           //     tbWPEditOut1.Text = "0";
4208
            o[14] = "0";
4209
            o[15] = "0";
4210
 
4211
            dtWaypoints.Rows.Add(o);
2368 - 4212
            _createWP(new PointLatLng((double)o[3], (double)o[4]), (string)o[2], (int)o[1]);
2359 - 4213
            Dispatcher.Invoke(() => lblWPCount.Content = o[0].ToString());
4214
            if (mRouteWP != null)
4215
                MainMap.Markers.Remove(mRouteWP);
4216
            _routeUpdate();
4217
            Dispatcher.Invoke(() => {
4218
                dgvWP.Items.Refresh();
4219
                dgvWP.SelectedIndex = (int)o[0] -1;
4220
                dgvWP.UpdateLayout();
4221
                _dgvWPselectEditRow();
4222
                });
2356 - 4223
        }
4224
 
2315 - 4225
        #endregion WP
2324 - 4226
        #region GPX
4227
        private void checkBoxGPXLog_Click(object sender, RoutedEventArgs e)
4228
        {
4229
            _bGPXLog = (bool)checkBoxGPXLog.IsChecked;
4230
        }
4231
        void _gpxAdd(double lat,double lon, int elevation)
4232
        {
4233
            DataRow dr = dtGPX.NewRow();
4234
            dr[0] = dtGPX.Rows.Count - 1;
4235
            dr[1] = lat;
4236
            dr[2] = lon;
4237
            dr[3] = elevation;
4238
            dr[4] = DateTime.UtcNow.ToString("s", System.Globalization.CultureInfo.InvariantCulture); //2011-01-14T01:59:01Z
4239
            dtGPX.Rows.Add(dr);
4240
        }
4241
        void _saveGPXLog()
4242
        {
4243
            if (!Directory.Exists("GPXLog"))
4244
                Directory.CreateDirectory("GPXLog");
4245
            string SaveFileName = "GPXLog\\" + DateTime.Now.ToString("yyyyMMdd_HHmm") + ".gpx";
4246
            XmlTextWriter myXmlTextWriter = null;
4247
            myXmlTextWriter = new XmlTextWriter(SaveFileName, null);
4248
            NumberFormatInfo nfi = new NumberFormatInfo();
4249
            nfi.NumberDecimalSeparator = ".";
2315 - 4250
 
2324 - 4251
            try
4252
            {
4253
                myXmlTextWriter.Formatting = Formatting.Indented;
4254
 
4255
                myXmlTextWriter.WriteStartDocument();
4256
 
4257
                myXmlTextWriter.WriteStartElement("gpx");
4258
 
4259
                myXmlTextWriter.WriteAttributeString("version", "1.0");
4260
                myXmlTextWriter.WriteAttributeString("creator", "MKLiveView v1.0");
4261
                myXmlTextWriter.WriteAttributeString("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
4262
                myXmlTextWriter.WriteAttributeString("xmlns", "http://www.topografix.com/GPX/1/1");
4263
                myXmlTextWriter.WriteAttributeString("xsi:schemaLocation", "http://www.topografix.com/GPX/1/1/gpx.xsd");
4264
 
4265
                myXmlTextWriter.WriteElementString("time", DateTime.UtcNow.ToString("u", System.Globalization.CultureInfo.InvariantCulture));
4266
 
4267
                myXmlTextWriter.WriteStartElement("trk");
4268
                myXmlTextWriter.WriteStartElement("trkseg");
4269
                for(int i = 0; i< dtGPX.Rows.Count;i++)
4270
                {
4271
                    myXmlTextWriter.WriteStartElement("trkpt");
4272
                    myXmlTextWriter.WriteAttributeString("lat", dtGPX.Rows[i][1].ToString() != "" ? ((double)dtGPX.Rows[i][1]).ToString(nfi) : "");
4273
                    myXmlTextWriter.WriteAttributeString("lon", dtGPX.Rows[i][2].ToString() != "" ? ((double)dtGPX.Rows[i][2]).ToString(nfi) : "");
4274
                    myXmlTextWriter.WriteElementString("ele", dtGPX.Rows[i][3].ToString());
4275
                    myXmlTextWriter.WriteElementString("time", dtGPX.Rows[i][4].ToString());
4276
                    myXmlTextWriter.WriteEndElement();
4277
                }
4278
                myXmlTextWriter.WriteEndElement();
4279
                myXmlTextWriter.WriteEndElement();
4280
                myXmlTextWriter.WriteEndElement();
4281
            }
4282
            catch (Exception e)
4283
            {
4284
                Console.WriteLine("Exception: {0}", e.ToString());
4285
            }
4286
            finally
4287
            {
4288
                if (myXmlTextWriter != null)
4289
                {
4290
                    myXmlTextWriter.Close();
4291
                }
4292
            }
4293
        }
2356 - 4294
 
2385 - 4295
 
2324 - 4296
        private void btnLoadGPXLog_Click(object sender, RoutedEventArgs e)
4297
        {
4298
            _loadGPXLog();
4299
        }
2327 - 4300
        private void btnClearRoute_Click(object sender, RoutedEventArgs e)
4301
        {
4302
            _clearMapMarkers(typeof(GMapRoute));
4303
        }
2324 - 4304
        void _loadGPXLog()
4305
        {
4306
 
4307
            Microsoft.Win32.OpenFileDialog fd = new Microsoft.Win32.OpenFileDialog();
4308
            fd.Filter = "GPX-Logfile | *.gpx";
4309
            fd.Multiselect = false;
4310
            if (fd.ShowDialog().Value)
4311
            {
4312
                string file = fd.FileName;
4313
                try
4314
                {
4315
                    XDocument gpxDoc = XDocument.Load(file);
4316
                    XNamespace gpx = XNamespace.Get("http://www.topografix.com/GPX/1/1");
4317
 
4318
                    NumberFormatInfo nfi = new NumberFormatInfo();
4319
                    nfi.NumberDecimalSeparator = ".";
4320
 
4321
                    var tracks = from track in gpxDoc.Descendants(gpx + "trk")
4322
                                 select new
4323
                                 {
4324
                                     Name = track.Element(gpx + "name") != null ? track.Element(gpx + "name").Value : null,
4325
                                     Segs = (
4326
                                         from trackpoint in track.Descendants(gpx + "trkpt")
4327
                                         select new
4328
                                         {
4329
                                             Latitude = trackpoint.Attribute("lat").Value,
4330
                                             Longitude = trackpoint.Attribute("lon").Value,
4331
                                             Elevation = trackpoint.Element(gpx + "ele") != null ?
4332
                                             trackpoint.Element(gpx + "ele").Value : null,
4333
                                             Time = trackpoint.Element(gpx + "time") != null ?
4334
                                             trackpoint.Element(gpx + "time").Value : null
4335
                                         }
4336
                                     )
4337
                                 };
4338
 
4339
                    List<PointLatLng> wpl = new List<PointLatLng>();
4340
                    foreach(var trk in tracks)
4341
                    {
4342
                        foreach(var trkseg in trk.Segs)
4343
                        {
4344
                            if(trkseg.Latitude != "" && trkseg.Longitude !="")
4345
                            wpl.Add(new PointLatLng(Convert.ToDouble(trkseg.Latitude, nfi), Convert.ToDouble(trkseg.Longitude, nfi)));
4346
                        }
4347
 
4348
                    }
4349
                    if(wpl.Count() > 0)
4350
                    {
2327 - 4351
                        _clearMapMarkers(typeof(GMapRoute));
2324 - 4352
                        MapRoute mr = new MapRoute(wpl, "flying");
2328 - 4353
                        Dispatcher.Invoke(() =>
4354
                        {
4355
                            GMapRoute mRoute;
4356
                            if (comboBoxRouteColor.SelectionBoxItem != null)
4357
                            {
4358
                                string s = comboBoxRouteColor.SelectionBoxItem.ToString();
2366 - 4359
                                mRoute = new GMapRoute(wpl, _getBrush(s));
2328 - 4360
                            }
4361
                            else
2366 - 4362
                                mRoute = new GMapRoute(wpl, null);
2324 - 4363
 
2328 - 4364
                            MainMap.Markers.Add(mRoute);
4365
                        });
2324 - 4366
                    }
4367
 
4368
                }
4369
                catch (Exception e)
4370
                {
4371
                    Console.WriteLine("Exception: {0}", e.ToString());
4372
                }
4373
            }
4374
        }
4375
        #endregion GPX
2315 - 4376
        #endregion functions
2287 - 4377
    }
2315 - 4378
     /// <summary>
4379
    /// formats the wp datatable values for display in datagrid - this is bound in the datagrid as a converter
4380
    /// </summary>
2313 - 4381
    public class waypointsConverter : IValueConverter
4382
    {
4383
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
4384
        {
4385
            if (value != null)
4386
            {
4387
                switch ((string)parameter)
4388
                {
4389
                    case "Latitude":
4390
                        return value.ToString() + " °";
4391
                    case "Longitude":
4392
                        return value.ToString() + " °";
4393
                    case "Radius":
4394
                        return value.ToString() + " m";
4395
                    case "Altitude":
4396
                        return value.ToString() + " m";
4397
                    case "ClimbRate":
4398
                        return value.ToString() == "255" ? "Auto" : (System.Convert.ToDouble(value) / 10).ToString("0.0 m/s");
4399
                    case "DelayTime":
4400
                        return value.ToString() + " s";
4401
                    case "Heading":
4402
                        return Waypoints.Heading(System.Convert.ToInt32(value));
4403
                    case "Speed":
4404
                        return Waypoints.WPSpeed(System.Convert.ToInt16(value));
4405
                    case "CamAngle":
4406
                        return Waypoints.CAMAngle(System.Convert.ToInt16(value));
4407
                    case "Type":
4408
                        return ((Waypoints.pointType)(System.Convert.ToInt16(value))).ToString();
4409
                    case "AutoTrigger":
4410
                        return value.ToString() == "0" ? "- - -" : value.ToString() + " m";
4411
                    case "Status":
2355 - 4412
                        return (Waypoints.status)(System.Convert.ToInt16(value));
2313 - 4413
                }
4414
 
4415
                return value.ToString();
4416
            }
4417
            else return value;
4418
        }
4419
 
4420
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
4421
        {
4422
            throw new NotImplementedException();
4423
        }
4424
    }
4425
 
2287 - 4426
    public class IniFile
4427
    {
4428
        public string path;
4429
 
4430
        [DllImport("kernel32")]
4431
        private static extern long WritePrivateProfileString(string section,
4432
          string key, string val, string filePath);
4433
 
4434
        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
4435
        static extern uint GetPrivateProfileSectionNames(IntPtr lpszReturnBuffer,
4436
               uint nSize, string lpFileName);
4437
 
4438
        [DllImport("kernel32")]
4439
        private static extern int GetPrivateProfileString(string section,
4440
          string key, string def, StringBuilder retVal,
4441
          int size, string filePath);
4442
 
4443
        public IniFile(string INIPath)
4444
        {
4445
            path = INIPath;
4446
        }
4447
 
4448
        public void IniWriteValue(string Section, string Key, string Value)
4449
        {
4450
            WritePrivateProfileString(Section, Key, Value, this.path);
4451
        }
4452
 
4453
        public string IniReadValue(string Section, string Key)
4454
        {
4455
            StringBuilder temp = new StringBuilder(255);
4456
            int i = GetPrivateProfileString(Section, Key, "", temp, 255, this.path);
4457
            return temp.ToString();
4458
        }
4459
        //Ini_sections auslesen in String-Array
4460
        public string[] IniSectionNames()
4461
        {
4462
 
4463
            //  uint MAX_BUFFER = 32767;
4464
            uint MAX_BUFFER = 8388608;
4465
            IntPtr pReturnedString = Marshal.AllocCoTaskMem((int)MAX_BUFFER);
4466
            uint bytesReturned = GetPrivateProfileSectionNames(pReturnedString, MAX_BUFFER, this.path);
4467
            if (bytesReturned == 0)
4468
            {
4469
                Marshal.FreeCoTaskMem(pReturnedString);
4470
                return null;
4471
            }
4472
            string local = Marshal.PtrToStringAuto(pReturnedString, (int)bytesReturned).ToString();
4473
            Marshal.FreeCoTaskMem(pReturnedString);
4474
            //use of Substring below removes terminating null for split
4475
            return local.Substring(0, local.Length - 1).Split('\0');
4476
 
4477
 
4478
        }
4479
    }
4480
 
4481
    /// <summary>
4482
    /// Selected Win AI Function Calls
4483
    /// </summary>
4484
    public class WinApi
4485
    {
4486
        [DllImport("user32.dll", EntryPoint = "GetSystemMetrics")]
4487
        public static extern int GetSystemMetrics(int which);
4488
        [DllImport("user32.dll")]
4489
        public static extern void
4490
                SetWindowPos(IntPtr hwnd, IntPtr hwndInsertAfter,
4491
                             int X, int Y, int width, int height, uint flags);
4492
 
4493
        private const int SM_CXSCREEN = 0;
4494
        private const int SM_CYSCREEN = 1;
4495
        private static IntPtr HWND_TOP = IntPtr.Zero;
4496
        private const int SWP_SHOWWINDOW = 64; // 0x0040
4497
 
4498
        public static int ScreenX
4499
        {
4500
            get { return GetSystemMetrics(SM_CXSCREEN); }
4501
        }
4502
 
4503
        public static int ScreenY
4504
        {
4505
            get { return GetSystemMetrics(SM_CYSCREEN); }
4506
        }
4507
 
4508
        public static void SetWinFullScreen(IntPtr hwnd)
4509
        {
4510
            SetWindowPos(hwnd, HWND_TOP, -8, -7, ScreenX+15, ScreenY+14, SWP_SHOWWINDOW);
4511
        }
4512
    }
4513
    /// <summary>
4514
    /// Class used to preserve / restore state of the window
4515
    /// </summary>
4516
    public class WinState
4517
    {
4518
        private WindowState winState;
4519
        private WindowStyle brdStyle;
4520
        private bool topMost;
4521
        private Rect restore;
4522
        private bool IsMaximized = false;
4523
 
4524
        public bool isMaximized
4525
        {
4526
            get { return IsMaximized; }
4527
        }
4528
        public void Maximize(Window targetForm)
4529
        {
4530
            if (!IsMaximized)
4531
            {
4532
                IsMaximized = true;
4533
                Save(targetForm);
4534
                targetForm.WindowState = WindowState.Maximized;
4535
                targetForm.WindowStyle = WindowStyle.None;
4536
                targetForm.Topmost = true;
4537
                WinApi.SetWinFullScreen(new WindowInteropHelper(targetForm).Handle);
4538
            }
4539
        }
4540
 
4541
        public void Save(Window targetForm)
4542
        {
4543
            winState = targetForm.WindowState;
4544
            brdStyle = targetForm.WindowStyle;
4545
            topMost = targetForm.Topmost;
4546
            restore = targetForm.RestoreBounds;
4547
        }
4548
        public void Restore(Window targetForm)
4549
        {
4550
            targetForm.WindowState = winState;
4551
            targetForm.WindowStyle = brdStyle;
4552
            targetForm.Topmost = topMost;
4553
 
4554
            targetForm.Left = restore.Left;
4555
            targetForm.Top = restore.Top;
4556
            targetForm.Height = restore.Height;
4557
            targetForm.Width = restore.Width;
4558
            IsMaximized = false;
4559
        }
4560
    }
4561
 
4562
}