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
                        {
2295 - 976
                            Thread t = new Thread(()=>_mediaPlayer("Voice\\Distance.mp3"));
977
                            t.Start();
2291 - 978
                            _bVoiceDistanceActive = true;
979
                        }
980
                        _iDistanceJitter++;
981
                    }
982
                }
2287 - 983
            }
984
        }
985
 
986
        private void checkBoxFollowCopter_Click(object sender, RoutedEventArgs e)
987
        {
988
            _bFollowCopter = (bool)checkBoxFollowCopter.IsChecked;
989
        }
990
 
991
        private void sliderMapZoom_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
992
        {
993
            if (MainMap.Zoom != sliderMapZoom.Value)
994
                MainMap.Zoom = (int)sliderMapZoom.Value;
995
        }
996
        #region Touch zooming hackattack ;) 
997
        /// <summary>
998
        /// inspired by http://www.codeproject.com/Articles/692286/WPF-and-multi-touch
999
        /// </summary>
1000
        bool bFirstAccess = true;
1001
        double dDistance = 0;
1002
        int iZoom;
1003
        private void MainMap_StylusDown(object sender, StylusDownEventArgs e)
1004
        {
1005
            var id = e.StylusDevice.Id;
1006
            e.StylusDevice.Capture(MainMap);
1007
            if (iFirstStylusID == -1)
1008
            {
1009
                iFirstStylusID = id;
1010
            }
1011
            else
1012
            {
1013
 
1014
                MainMap.CanDragMap = false;
1015
            }
1016
        }
1017
        private void MainMap_StylusUp(object sender, StylusEventArgs e)
1018
        {
1019
            MainMap.ReleaseStylusCapture();
1020
            iFirstStylusID = -1;
1021
            bFirstAccess = true;
1022
            MainMap.CanDragMap = true;
1023
            iZoom = 0;
1024
        }
1025
        private void MainMap_StylusMove(object sender, StylusEventArgs e)
1026
        {
1027
            var id = e.StylusDevice.Id;
1028
            var tp = e.GetPosition(MainMap);
1029
 
1030
            // This is the first Stylus point; just record its position. 
1031
            if (id == iFirstStylusID)
1032
            {
1033
                pTouch1.X = tp.X;
1034
                pTouch1.Y = tp.Y;
1035
            }
1036
            else
1037
            if (iFirstStylusID > -1)
1038
            {
1039
                pTouch2.X = tp.X;
1040
                pTouch2.Y = tp.Y;
1041
                double distance = Point.Subtract(pTouch1, pTouch2).Length;
1042
                if (!bFirstAccess)
1043
                {
1044
                    if (distance > dDistance)
1045
                        iZoom++;
1046
                    else
1047
                        if (distance < dDistance)
1048
                        iZoom--;
1049
                }
1050
                if (iZoom > 30)
1051
                {
1052
                    iZoom = 0;
1053
                    Dispatcher.Invoke(() => sliderMapZoom.Value += 1);
1054
                }
1055
                if (iZoom < -30)
1056
                {
1057
                    iZoom = 0;
1058
                    Dispatcher.Invoke(() => sliderMapZoom.Value -= 1);
1059
                }
1060
                dDistance = distance;
1061
                bFirstAccess = false;
1062
            }
1063
        }
1064
        #endregion Touch zooming hackattack ;)
1065
 
1066
        #endregion GMap
1067
 
1068
        #region settings
1069
        private void cBoxTimingsDebug_DropDownClosed(object sender, EventArgs e)
1070
        {
1071
            if(! _bCBInit && cBoxTimingsDebug.SelectedIndex > -1)
1072
                debugInterval = (byte)(Convert.ToInt16(cBoxTimingsDebug.SelectedItem) / 10);
1073
        }
1074
        private void cBoxTimingsNav_DropDownClosed(object sender, EventArgs e)
1075
        {
1076
            if(! _bCBInit && cBoxTimingsNav.SelectedIndex > -1)
1077
                navctrlInterval = (byte)(Convert.ToInt16(cBoxTimingsNav.SelectedItem) / 10);
1078
        }
1079
        private void cBoxTimingsBl_DropDownClosed(object sender, EventArgs e)
1080
        {
1081
            if (!_bCBInit && cBoxTimingsBl.SelectedIndex > -1)
1082
                blctrlInterval = (byte)(Convert.ToInt16(cBoxTimingsBl.SelectedItem) / 10);
1083
        }
1084
        private void cBoxTimingsOSD_DropDownClosed(object sender, EventArgs e)
1085
        {
1086
            if (!_bCBInit && cBoxTimingsOSD.SelectedIndex > -1)
1087
                OSDInterval = (byte)(Convert.ToInt16(cBoxTimingsOSD.SelectedItem) / 10);
1088
        }
1089
        private void chkbAutoDbg_Click(object sender, RoutedEventArgs e)
1090
        {
1091
            if (!_init) _debugDataAutorefresh = (bool)chkbAutoDbg.IsChecked;
1092
        }
1093
        private void chkbAutoNav_Click(object sender, RoutedEventArgs e)
1094
        {
1095
            if (!_init) _navCtrlDataAutorefresh = (bool)chkbAutoNav.IsChecked;
1096
        }
1097
        private void chkbAutoBL_Click(object sender, RoutedEventArgs e)
1098
        {
1099
            if (!_init) _blctrlDataAutorefresh = (bool)chkbAutoBL.IsChecked;
1100
        }
1101
        private void chkbAutoOSD_Click(object sender, RoutedEventArgs e)
1102
        {
1103
            if (!_init) _OSDAutorefresh = (bool)chkbAutoOSD.IsChecked;
1104
        }
1105
 
1106
        private void cBoxLiPoCells_DropDownClosed(object sender, EventArgs e)
1107
        {
1108
            if (cBoxLiPoCells.SelectedIndex > -1)
1109
            {
1110
                _LipoCells = cBoxLiPoCells.SelectedIndex + 3;
1111
                _LipoMinMax();
1112
            }
1113
        }
1114
        void _LipoMinMax()
1115
        {
1116
            _dLipoVMax = (double)(_LipoCells) * 4.22;
1117
            _dLipoVMin = (double)_LipoCells * 3;
1118
            pbTopVoltage.Maximum = _dLipoVMax;
1119
            pbTopVoltage.Minimum = _dLipoVMin;
1120
            sliderThresholdVoltageWarn.Maximum = _dLipoVMax;
1121
            sliderThresholdVoltageWarn.Minimum = _dLipoVMin;
1122
        }
1123
        private void cBoxMotors_DropDownClosed(object sender, EventArgs e)
1124
        {
1125
            if (cBoxMotors.SelectedIndex > -1)
1126
            {
1127
                _iMotors = cBoxMotors.SelectedIndex + 3;
1128
                Dispatcher.Invoke(() =>
1129
                {
1130
                    dgvMotors1.Height = (272 / 12.6) * (_iMotors + 1);  //272 / 12.6 --> Workaround, cause the headerheight = NaN...?
1131
                    GridMotors.Height = dgvMotors1.Height + 10;
1132
                });
1133
            }
1134
        }
1135
        void _setMotorGridSize()
1136
        {
1137
            if (dgvMotors1.Columns.Count > 2)
1138
            {
1139
                dgvMotors1.Columns[0].Width = 24;
1140
                dgvMotors1.Columns[1].Width = 50;
1141
                dgvMotors1.Columns[2].Width = 50;
1142
                dgvMotors1.Height = (272 / 12.6) * (_iMotors + 1);
1143
                GridMotors.Height = dgvMotors1.Height + 10;
1144
            }
1145
 
1146
        }
1147
        #endregion settings
1148
 
1149
        #region functions  
1150
 
1151
        #region logging      
1152
        /// <summary> Log data to the terminal window. </summary>
1153
        /// <param name="msgtype"> The type of message to be written. </param>
1154
        /// <param name="msg"> The string containing the message to be shown. </param>
1155
        private void Log(LogMsgType msgtype, string msg)
1156
        {
1157
            Dispatcher.Invoke(() =>
1158
            {
1159
               // rtfTerminal.CaretPosition = rtfTerminal.CaretPosition.DocumentEnd;
1160
               // rtfTerminal.Foreground = new SolidColorBrush(LogMsgTypeColor[(int)msgtype]);
1161
//                rtfTerminal.AppendText(msg + "\r");
1162
                TextRange tr = new TextRange(rtfTerminal.Document.ContentEnd,rtfTerminal.Document.ContentEnd);
1163
                tr.Text = msg;
1164
                tr.ApplyPropertyValue(TextElement.ForegroundProperty, new SolidColorBrush(LogMsgTypeColor[(int)msgtype]));
1165
                rtfTerminal.AppendText("\r");
1166
                rtfTerminal.ScrollToEnd();
1167
            });
1168
        }
2381 - 1169
        private void ErrorLog(LogMsgType msgtype, string msg , string linkURL, string linkName)
2287 - 1170
        {
2381 - 1171
 
2287 - 1172
            Dispatcher.Invoke(() =>
1173
            {
2381 - 1174
                Paragraph para = new Paragraph();
1175
                para.Margin = new Thickness(0); // remove indent between paragraphs
1176
 
1177
                Hyperlink link = new Hyperlink();
1178
                if (linkURL != "" && linkName != "")
1179
                {
1180
                    link.IsEnabled = true;
1181
                    link.Inlines.Add(linkName);
1182
                    link.NavigateUri = new Uri(linkURL);
1183
                    link.RequestNavigate += (sender, args) => Process.Start(args.Uri.ToString());
1184
                }
1185
                //msg = DateTime.Now.ToLongTimeString() + msg;
1186
                para.Foreground = new SolidColorBrush(LogMsgTypeColor[(int)msgtype]);
1187
                Run r = new Run("[" + DateTime.Now.ToLongTimeString() + "]: ");
1188
                r.Foreground = new SolidColorBrush(Colors.Black);
1189
                para.Inlines.Add(r);
1190
                para.Inlines.Add(msg);
1191
                para.Inlines.Add(link);
1192
                rtfError.Document.Blocks.Add(para);
1193
                //TextRange tr = new TextRange(rtfError.Document.ContentEnd, rtfError.Document.ContentEnd);
1194
                //tr.Text = msg + link;
1195
                //tr.ApplyPropertyValue(TextElement.ForegroundProperty, new SolidColorBrush(LogMsgTypeColor[(int)msgtype]));
1196
                //rtfError.AppendText("\r");
2287 - 1197
                rtfError.ScrollToEnd();
1198
 
2381 - 1199
                //_bErrorLog = true;
2287 - 1200
            });
1201
        }
1202
        /// <summary>
1203
        /// Clear the line in the  errorlog window 
1204
        /// containing the error string when error has ceased
1205
        /// </summary>
1206
        /// <param name="s">substring of errrormessage</param>
1207
        void _clearErrorLog(string s)
1208
        {
1209
            Dispatcher.Invoke((Action)(() =>
1210
            {
1211
                TextRange searchRange = new TextRange(rtfError.Document.ContentStart, rtfError.Document.ContentEnd);
1212
                TextRange foundRange = FindTextInRange(searchRange, s);
1213
 
1214
                int iStart = searchRange.Text.IndexOf(s, StringComparison.OrdinalIgnoreCase);
1215
 
1216
 
1217
                if (iStart > -1)
1218
                {
1219
                    int iLength = 0;
1220
                    int iEnd = searchRange.Text.IndexOf('\r', iStart);
1221
                    if (iEnd > 0)
1222
                    {
1223
                        iLength = iEnd + 1;
1224
                        int iHttp = searchRange.Text.IndexOf("http", iEnd);
1225
                        if (iHttp == iLength)
1226
                        {
1227
                            int iEnd2 = searchRange.Text.IndexOf('\r', iLength);
1228
                            if (iEnd2 > iLength)
1229
                            {
1230
                                iLength = iEnd2 + 1;
1231
                              //  TextRange result = new TextRange(rtfError.Document.ContentStart.GetPositionAtOffset(iStart), GetTextPositionAtOffset(rtfError.Document.ContentStart.GetPositionAtOffset(iStart), iLength));
1232
 
1233
                                rtfError.Selection.Select(rtfError.Document.ContentStart.GetPositionAtOffset(iStart), GetTextPositionAtOffset(rtfError.Document.ContentStart.GetPositionAtOffset(iStart), iLength));
1234
                                rtfError.Selection.Text = string.Empty;
1235
                                if (rtfError.Document.ContentEnd.GetTextRunLength(LogicalDirection.Backward) < 2) _bErrorLog = false;
1236
                            }
1237
 
1238
                        }
1239
                        else
1240
                        {
1241
                            rtfError.Selection.Select(rtfError.Document.ContentStart.GetPositionAtOffset(iStart), GetTextPositionAtOffset(rtfError.Document.ContentStart.GetPositionAtOffset(iStart), iLength));
1242
                            rtfError.Selection.Text = string.Empty;
1243
                            if (rtfError.Document.ContentEnd.GetTextRunLength(LogicalDirection.Backward) < 2) _bErrorLog = false;
1244
                        }
1245
                    }
1246
                }
1247
            }));
1248
 
1249
        }
1250
        public TextRange FindTextInRange(TextRange searchRange, string searchText)
1251
        {
1252
            int offset = searchRange.Text.IndexOf(searchText, StringComparison.OrdinalIgnoreCase);
1253
            if (offset < 0)
1254
                return null;  // Not found
1255
 
1256
            var start = GetTextPositionAtOffset(searchRange.Start, offset);
1257
            TextRange result = new TextRange(start, GetTextPositionAtOffset(start, searchText.Length));
1258
 
1259
            return result;
1260
        }
1261
        TextPointer GetTextPositionAtOffset(TextPointer position, int characterCount)
1262
        {
1263
            while (position != null)
1264
            {
1265
                if (position.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.Text)
1266
                {
1267
                    int count = position.GetTextRunLength(LogicalDirection.Forward);
1268
                    if (characterCount <= count)
1269
                    {
1270
                        return position.GetPositionAtOffset(characterCount);
1271
                    }
1272
 
1273
                    characterCount -= count;
1274
                }
1275
 
1276
                TextPointer nextContextPosition = position.GetNextContextPosition(LogicalDirection.Forward);
1277
                if (nextContextPosition == null)
1278
                    return position;
1279
 
1280
                position = nextContextPosition;
1281
            }
1282
 
1283
            return position;
1284
        }
1285
        #endregion logging
1286
 
1287
        #region processing received data
1288
 
1289
        private void processMessage(byte[] message)
1290
        {
1291
            if (message.Length > 0)
1292
            {
1293
                _iLifeCounter++;
1294
                //Log(LogMsgType.Incoming, BitConverter.ToString(message));
1295
                //Log(LogMsgType.Incoming, message.Length.ToString());
1296
                string s = new string(ASCIIEncoding.ASCII.GetChars(message, 0, message.Length));
1297
                char cmdID;
1298
                byte adr;
1299
                byte[] data;
1300
                byte[] tmp = null;
1301
                if (message[0] != '#')
1302
                {
1303
                    int iFound = -1;
1304
                    for (int i = 0; i < message.Length; i++)   //Sometimes the FC/NC sends strings without termination (like WP messages)
1305
                    {                                   //so this is a workaround to not spam the log box
1306
                        if (message[i] == 35)
1307
                        {
1308
                            iFound = i;
1309
                            break;
1310
                        }
1311
                    }
1312
                    if (iFound > 0)
1313
                    {
1314
                        s = new string(ASCIIEncoding.ASCII.GetChars(message, 0, iFound));
1315
                        tmp = new byte[message.Length - iFound];
1316
                        Buffer.BlockCopy(message, iFound, tmp, 0, message.Length - iFound);
1317
                    }
1318
                    s = s.Trim('\0', '\n', '\r');
1319
                    if (s.Length > 0)
1320
                        Log(LogMsgType.Normal, s);
1321
                    if (tmp != null)
1322
                    {
1323
                        s = new string(ASCIIEncoding.ASCII.GetChars(tmp, 0, tmp.Length));
1324
                        processMessage(tmp);
1325
                    }
1326
                }
1327
                //Debug.Print(s);
1328
                else
1329
                {
1330
                    FlightControllerMessage.ParseMessage(message, out cmdID, out adr, out data);
1331
 
1332
                    if (adr == 255) { crcError++; }
1333
                    else crcError = 0;
1334
                    Dispatcher.Invoke(() => tbCrc.Text = crcError.ToString());
1335
                    //display the active controller (FC / NC) 
1336
                    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...???
1337
                    {
1338
                        _iCtrlAct = adr;
1339
                        switch (adr)
1340
                        {
1341
                            case 1:
1342
                                Dispatcher.Invoke(() => tbCtrl.Text = "FC");
2381 - 1343
                               // Dispatcher.Invoke(() => buttonSwitchNC.Visibility = Visibility.Visible);
1344
                               // Dispatcher.Invoke(() => labelSwitchToNavi.Visibility = Visibility.Visible);
2287 - 1345
                              //  _setFieldsNA(); //display fields NA for FC 
1346
                                break;
1347
                            case 2:
1348
                                Dispatcher.Invoke(() => tbCtrl.Text = "NC");
1349
                                //Dispatcher.Invoke(() => buttonSwitchNC.Visibility = Visibility.Hidden);
1350
                                //Dispatcher.Invoke(() => labelSwitchToNavi.Visibility = Visibility.Hidden);
1351
                                break;
1352
                            //case 3:
1353
                            //    lblCtrl.Invoke((Action)(() => lblCtrl.Text = "MK3MAG"));
1354
                            //    break;
1355
                            //case 4:
1356
                            //    lblCtrl.Invoke((Action)(() => lblCtrl.Text = "BL-CTRL"));
1357
                            //    break;
1358
                            default:
1359
                                Dispatcher.Invoke(() => tbCtrl.Text = "NA");
1360
                                break;
1361
                        }
1362
                       // _loadLabelNames();
1363
                    }
1364
                    // else
1365
                    //     Debug.Print("Address == 0?");
1366
 
1367
                    if (data != null && data.Length > 0)
1368
                    {
1369
                        s = new string(ASCIIEncoding.ASCII.GetChars(data, 1, data.Length - 1));
1370
                        s = s.Trim('\0', '\n');
1371
 
1372
                        switch (cmdID)
1373
                        {
1374
                            //case 'A': //Label names
1375
                            //    _processLabelNames(s);
1376
                            //    break;
1377
 
1378
                            case 'D': //Debug data
1379
                                _processDebugVals(adr, data);
1380
                                break;
1381
 
1382
                            case 'V': //Version
1383
                                _processVersion(adr, data);
1384
                                break;
1385
 
1386
                            case 'K'://BL-CTRL data
1387
                                _processBLCtrl(data);
1388
                                break;
1389
 
1390
                            case 'O': //NC Data
1391
                                _processNCData(data);
1392
                                break;
1393
 
2381 - 1394
                            //case 'E': //NC error-string
1395
                            //    ErrorLog(LogMsgType.Error, "NC Error: " + s);
1396
                            //    break;
2287 - 1397
 
1398
                            case 'L': //OSD Menue (called by pagenumber)
1399
                                _processOSDSingle(data);
1400
                                break;
1401
 
1402
                            case 'H': //OSD Menue (with autoupdate - called by Key)
1403
                                _processOSDAuto(data);
1404
                                break;
1405
 
1406
                            case 'X': //Waypoint data
1407
                                _processWPData(data);
1408
                                break;
1409
 
2313 - 1410
                            case 'W': //return new Waypoint items count after sending waypoint to copter
1411
                                _iWPCount = data[0];
1412
                                break;
2287 - 1413
                                //default:
1414
                                //    Log(LogMsgType.Incoming, "cmd: " + cmdID.ToString());
1415
                                //    Log(LogMsgType.Incoming, BitConverter.ToString(data));
1416
                                //    break;
1417
                        }
1418
                    }
1419
                    //else
1420
                    //{
1421
                    //    Log(LogMsgType.Incoming, "cmd: " + cmdID.ToString());
1422
                    //    Log(LogMsgType.Incoming, BitConverter.ToString(data));
1423
                    //}
1424
                }
1425
            }
1426
        }
1427
        /// <summary>
1428
        /// Analog label names 'A'
1429
        /// each label name is returned as a single string 
1430
        /// and added to string array sAnalogLabel[]
1431
        /// and the datatable dtAnalog
1432
        /// </summary>
1433
        /// <param name="s">the label name</param>
1434
        void _processLabelNames(string s)
1435
        {
1436
            //if (iLableIndex < 32)
1437
            //{
1438
            //    sAnalogLabel[iLableIndex] = s;
1439
            //    if (dtAnalog.Rows.Count < 32)
1440
            //        dtAnalog.Rows.Add(s, "");
1441
            //    else
1442
            //        dtAnalog.Rows[iLableIndex].SetField(0, s);
1443
 
1444
            //  //  _getAnalogLabels(iLableIndex + 1);
1445
            //}
1446
            //Debug.Print(s);
1447
        }
1448
        /// <summary>
1449
        /// Debug values 'D'
1450
        /// </summary>
1451
        /// <param name="adr">adress of the active controller (1-FC, 2-NC)</param>
1452
        /// <param name="data">the received byte array to process</param>
1453
        void _processDebugVals(byte adr, byte[] data)
1454
        {
1455
            if (data.Length == 66)
1456
            {
2324 - 1457
 
2287 - 1458
                double v;
1459
                int index = 0;
1460
                Int16 i16 = 0;
1461
                double dTemp = 0;
1462
                for (int i = 2; i < 66; i += 2)
1463
                {
1464
                    i16 = data[i + 1];
1465
                    i16 = (Int16)(i16 << 8);
1466
                    iAnalogData[index] = data[i] + i16;
1467
                    sAnalogData[index] = (data[i] + i16).ToString();
1468
                   // dtAnalog.Rows[index].SetField(1, sAnalogData[index]);
1469
 
1470
                    if (adr == 2) //NC
1471
                    {
1472
                        switch (index)
1473
                        {
1474
                            case 0: //pitch (German: nick)
1475
                                Dispatcher.Invoke(() => ArtHor.Pitch = ((double)iAnalogData[index] / (double)10));
1476
                                Dispatcher.Invoke((Action)(() => tbPitch.Text = ((double)iAnalogData[index] / (double)10).ToString("0.0°")));
1477
                                break;
1478
                            case 1: //roll
1479
                                Dispatcher.Invoke(() => ArtHor.Roll = ((double)iAnalogData[index] / (double)10));
1480
                                Dispatcher.Invoke((Action)(() => tbRoll.Text = ((double)iAnalogData[index] / (double)10).ToString("0.0°")));
1481
                                break;
1482
                            case 4: //altitude
1483
                                Dispatcher.Invoke(() => tbAlt.Text = ((double)iAnalogData[index] / (double)10).ToString("0.0 m"));
1484
                                Dispatcher.Invoke(() => tbTopHeight.Text = ((double)iAnalogData[index] / (double)10).ToString("0.0 m"));
2324 - 1485
                                Dispatcher.Invoke(() => { drGPX[3] = (double)iAnalogData[index] / (double)10; });
2287 - 1486
                                break;
1487
                            case 7: //Voltage
1488
                                v = (double)iAnalogData[index] / (double)10;
1489
                                Dispatcher.Invoke(() => tbVolt.Text = v.ToString("0.0 V"));
1490
                                Dispatcher.Invoke(() => tbTopVoltage.Text = v.ToString("0.0 V"));
1491
                                Dispatcher.Invoke(() => pbTopVoltage.Value = v);
1492
                                if (v - _dLipoVMin < 1 | v < _dThresholdVoltageWarn)
1493
                                {
1494
                                    if (v == _dVoltLast)
1495
                                        if(_iVoltJitter < 20) _iVoltJitter++;
1496
                                    else
1497
                                    {
1498
                                        _iVoltJitter = 0;
1499
                                        _dVoltLast = v;
1500
                                    }
1501
                                    if (_iVoltJitter == 20)
1502
                                    {
1503
                                        Dispatcher.Invoke(() => pbTopVoltage.Foreground = Brushes.Orange);
1504
 
1505
                                        if (v - _dLipoVMin < 1 | v < _dThresholdVoltageCrit)
1506
                                        {
1507
                                            Dispatcher.Invoke(() => pbTopVoltage.Foreground = Brushes.Red);
1508
                                            if (stbVoltageCritAnim != null && !_bCritAnimVoltActive)
1509
                                            {
1510
                                                Dispatcher.Invoke(() => stbVoltageCritAnim.Begin());
1511
                                                _bCritAnimVoltActive = true;
1512
                                            }
1513
                                            if (_bVoiceVoltPlay && !_bCritVoiceVoltActive)
1514
                                            {
2295 - 1515
                                                Thread t = new Thread(() => _mediaPlayer("Voice\\CriticalBattery.mp3"));
1516
                                                t.Start();
2287 - 1517
                                                _bCritVoiceVoltActive = true;
1518
                                            }
1519
                                        }
1520
                                        else
1521
                                        {
1522
                                            if (stbVoltageCritAnim != null && _bCritAnimVoltActive)
1523
                                            {
1524
                                                Dispatcher.Invoke(() => stbVoltageCritAnim.Stop());
1525
                                                _bCritAnimVoltActive = false;
1526
                                            }
1527
                                            _bCritVoiceVoltActive = false;
1528
 
2291 - 1529
                                            if (_bVoiceVoltPlay && !_bWarnVoiceVoltActive)
2287 - 1530
                                            {
2295 - 1531
                                                Thread t = new Thread(() => _mediaPlayer("Voice\\LowBattery.mp3"));
1532
                                                t.Start();
2291 - 1533
                                                _bWarnVoiceVoltActive = true;
2287 - 1534
                                            }
1535
                                        }
1536
                                    }
1537
                                }
1538
                                else
1539
                                {
1540
                                    Dispatcher.Invoke(() => pbTopVoltage.Foreground = new SolidColorBrush(Color.FromArgb(255, 107, 195, 123)));
1541
                                    if (stbVoltageCritAnim != null && _bCritAnimVoltActive)
1542
                                    {
1543
                                        Dispatcher.Invoke(() => stbVoltageCritAnim.Stop());
1544
                                        _bCritAnimVoltActive = false;
1545
                                    }
1546
                                    _bCritVoiceVoltActive = false;
2291 - 1547
                                    _bWarnVoiceVoltActive = false;
2287 - 1548
                                    _iVoltJitter = 0;
1549
                                }
1550
                                break;
1551
                            case 8: // Current
1552
                                Dispatcher.Invoke(() => tbCur.Text = ((double)iAnalogData[index] / (double)10).ToString("0.0 A"));
1553
                                Dispatcher.Invoke(() => tbTopCurrent.Text = ((double)iAnalogData[index] / (double)10).ToString("0.0 A"));
1554
                                break;
1555
                            case 10: //heading
2291 - 1556
                                Dispatcher.Invoke((Action)(() => tbHeading.Text = sAnalogData[index] + "°"));
2287 - 1557
                                Dispatcher.Invoke(() => ArtHor.rotate = iAnalogData[index]);
2385 - 1558
                               Dispatcher.Invoke(() => ((CustomMarkerCopter)(copter.Shape)).rotate = iAnalogData[index]);
2287 - 1559
                                break;
1560
                            case 12: // SPI error
2291 - 1561
                                Dispatcher.Invoke((Action)(() => tbSPI.Text = sAnalogData[index]));
2287 - 1562
                                break;
1563
                            case 14: //i2c error
2291 - 1564
                                Dispatcher.Invoke((Action)(() => tbI2C.Text = sAnalogData[index]));
2287 - 1565
                                break;
1566
                            case 20: //Earthmagnet field
2291 - 1567
                                Dispatcher.Invoke((Action)(() => tbMagF.Text = sAnalogData[index] + "%"));
1568
                                Dispatcher.Invoke((Action)(() => tbTopEarthMag.Text = sAnalogData[index] + "%"));
1569
 
1570
                                if (Math.Abs(100 - iAnalogData[index]) < _iThresholdMagField)
1571
                                {
1572
                                    Dispatcher.Invoke(() => imageEarthMag.Source = new BitmapImage(new Uri("Images/EarthMag.png", UriKind.Relative)));
1573
                                    _iMagneticFieldJitter = 0; _bVoiceMagneticFieldActive = false;
1574
                                    if (stbMagneticFieldAnim != null && _bAnimMagneticFieldActive)
1575
                                    {
1576
                                        Dispatcher.Invoke(() => stbMagneticFieldAnim.Stop());
1577
                                        _bAnimMagneticFieldActive = false;
1578
                                    }
1579
                                }
1580
                                else
1581
                                {
1582
                                    Dispatcher.Invoke(() => imageEarthMag.Source = new BitmapImage(new Uri("Images/EarthMag_R.png", UriKind.Relative)));
1583
                                    if(_iMagneticFieldLast >= Math.Abs(100 - iAnalogData[index]))
1584
                                    {
1585
                                        if (_iMagneticFieldJitter < 20)
1586
                                            _iMagneticFieldJitter++;
1587
                                    }
1588
                                    else
1589
                                    {
1590
                                        _iMagneticFieldJitter = 0;
1591
                                        _iMagneticFieldLast = Math.Abs(100 - iAnalogData[index]);
1592
                                    }
1593
                                    if(_iMagneticFieldJitter == 20)
1594
                                    {
1595
                                        if (stbMagneticFieldAnim != null && !_bAnimMagneticFieldActive)
1596
                                        {
1597
                                            Dispatcher.Invoke(() => stbMagneticFieldAnim.Begin());
1598
                                            _bAnimMagneticFieldActive = true;
1599
                                        }
1600
                                        if (_bVoiceMagneticFieldPlay && !_bVoiceMagneticFieldActive)
1601
                                        {
2295 - 1602
                                            Thread t = new Thread(() => _mediaPlayer("Voice\\MagneticField.mp3"));
1603
                                            t.Start();
2291 - 1604
                                            _bVoiceMagneticFieldActive = true;
1605
                                        }
1606
                                    }
1607
                                }
2287 - 1608
                                break;
1609
                            case 21: //GroundSpeed
1610
                                     Dispatcher.Invoke((Action)(() => tbSpeed.Text = ((double)iAnalogData[index] / (double)100).ToString("0.00 m/s")));
1611
                                     Dispatcher.Invoke((Action)(() => tbTopSpeed.Text = ((double)iAnalogData[index] / (double)100).ToString("0.00 m/s")));
1612
                                break;
2291 - 1613
 
1614
                            ///**********   needs testing --> not sure what position this is  ***************
2287 - 1615
                            case 28: //Distance East from saved home position -> calculate distance with distance N + height
1616
                                    dTemp = Math.Pow((double)iAnalogData[index], 2) + Math.Pow((double)iAnalogData[index - 1], 2);
1617
                                    dTemp = Math.Sqrt(dTemp) / (double)10; //'flat' distance from HP with N/E
1618
                                                                           //  lblNCDist.Invoke((Action)(() => lblNCDist.Text = dTemp.ToString("0.00")));
1619
                                    dTemp = Math.Pow(dTemp, 2) + Math.Pow(((double)iAnalogData[4] / (double)10), 2); //adding 'height' into calculation
1620
                                    dTemp = Math.Sqrt(dTemp) / (double)10;
1621
                               //     Dispatcher.Invoke((Action)(() => tbTopDistanceHP.Text = dTemp.ToString("0.0 m")));
1622
                                    Dispatcher.Invoke((Action)(() => tbHP1.Text = dTemp.ToString("0.0 m")));
1623
                                break;
2291 - 1624
 
2287 - 1625
                            case 31: //Sats used
1626
                                     Dispatcher.Invoke((Action)(() => tbSats.Text = sAnalogData[index]));
1627
                                    // Dispatcher.Invoke((Action)(() => tbTopSats.Text = sAnalogData[index]));                                   
1628
                                break;
1629
                        }
1630
                    }
1631
                    index++;
1632
                }
1633
            }
1634
            else
1635
                Debug.Print("wrong data-length (66): " + data.Length.ToString());
1636
        }
1637
        /// <summary>
1638
        /// Version string 'V'
1639
        /// </summary>
1640
        /// <param name="adr">adress of the active controller (1-FC, 2-NC)</param>
1641
        /// <param name="data">the received byte array to process</param>
1642
        void _processVersion(byte adr, byte[] data)
1643
        {
1644
            if (data.Length == 12)
1645
            {
1646
                if (!check_HWError)
1647
                {
1648
                    string[] sVersionStruct = new string[10] { "SWMajor: ", "SWMinor: ", "ProtoMajor: ", "LabelTextCRC: ", "SWPatch: ", "HardwareError 1: ", "HardwareError 2: ", "HWMajor: ", "BL_Firmware: ", "Flags: " };
1649
                    string sVersion = "";
1650
                    //sbyte[] signed = Array.ConvertAll(data, b => unchecked((sbyte)b));
1651
                    Log(LogMsgType.Warning, (adr == 1 ? "FC-" : "NC-") + "Version: ");
1652
                    sVersion = "HW V" + (data[7] / 10).ToString() + "." + (data[7] % 10).ToString();
1653
                    Log(LogMsgType.Incoming, sVersion);
1654
                    sVersion = "SW V" + (data[0]).ToString() + "." + (data[1]).ToString() + ((char)(data[4] + 'a')).ToString();
1655
                    Log(LogMsgType.Incoming, sVersion);
1656
                    Log(LogMsgType.Incoming, "BL-Firmware: V" + (data[8] / 100).ToString() + "." + (data[8] % 100).ToString());
1657
                }
1658
                if (data[5] > 0) //error0 
1659
                {
1660
                    if (adr == 1)
2381 - 1661
                        ErrorLog(LogMsgType.Error, " FC - HW-Error " + data[5].ToString() + ": " + ((FC_HWError0)data[5]).ToString(),"","");
2287 - 1662
                    if (adr == 2)
2381 - 1663
                        ErrorLog(LogMsgType.Error, " NC - HW-Error " + data[5].ToString() + ": " + ((NC_HWError0)data[5]).ToString(),"","");
2287 - 1664
                }
1665
                if (data[6] > 0) //error1 
1666
                {
1667
                    if (adr == 1)
2381 - 1668
                        ErrorLog(LogMsgType.Error, " FC - HW-Error " + data[6].ToString() + ": " + ((FC_HWError1)data[6]).ToString(),"","");
2287 - 1669
                    if (adr == 2)
2381 - 1670
                        ErrorLog(LogMsgType.Error, " NC - Unknown HW-ERROR: " + data[6].ToString(),"",""); //@moment NC has only one error field
2287 - 1671
                }
2381 - 1672
                //if ((data[5] + data[6] == 0) && _bErrorLog)
1673
                //    _clearErrorLog(adr == 1 ? "FC - HW-Error" : "NC - HW-Error");
2287 - 1674
 
1675
            }
1676
            check_HWError = false;
1677
        }
1678
        /// <summary>
1679
        /// BL-Ctrl data 'K'
1680
        /// for FC you have to use a customized firmware
1681
        /// </summary>
1682
        /// <param name="data">the received byte array to process</param>
1683
        void _processBLCtrl(byte[] data)
1684
        {
1685
            if (data.Length % 6 == 0) //data.Length up to 96 (16 motors x 6 byte data) --> new datastruct in FC -> not standard!
1686
            {
1687
                bool bAvailable = false;
1688
                for (int i = 0; i < data.Length && data[i] < _iMotors; i += 6) // data[i] < _iMotors -- only show set number of motors (12 max @ moment)
1689
                {
1690
 
1691
                    if ((data[i + 4] & 128) == 128) //Status bit at pos 7 = 128 dec -- if true, motor is available
1692
                        bAvailable = true;
1693
                    else
1694
                        bAvailable = false;
1695
 
1696
                    if (data[i] < _iMotors)
1697
                    {
1698
                        if (bAvailable)
1699
                        {
2315 - 1700
                            dtMotors.Rows[data[i]].SetField(1, ((double)data[i + 1] / (double)10).ToString("0.0 A"));
1701
                            dtMotors.Rows[data[i]].SetField(2, data[i + 2].ToString("0 °C"));
2287 - 1702
                        }
1703
                        else
1704
                        {
2315 - 1705
                            dtMotors.Rows[data[i]].SetField(1, "NA");
1706
                            dtMotors.Rows[data[i]].SetField(2, "NA");
2287 - 1707
                        }
1708
                    }
1709
                    //if (data[i] > 3 && data[i] < 8)
1710
                    //{
1711
                    //    if (bAvailable)
1712
                    //    {
1713
                    //        dtMotors2.Rows[data[i] - 4].SetField(1, ((double)data[i + 1] / (double)10).ToString("0.0 A"));
1714
                    //        dtMotors2.Rows[data[i] - 4].SetField(2, data[i + 2].ToString("0 °C"));
1715
                    //    }
1716
                    //    else
1717
                    //    {
1718
                    //        dtMotors2.Rows[data[i] - 4].SetField(1, "NA");
1719
                    //        dtMotors2.Rows[data[i] - 4].SetField(2, "NA");
1720
                    //    }
1721
                    //}
1722
                }
1723
            }
1724
        }
1725
        /// <summary>
1726
        /// Navi-Ctrl data 'O'
1727
        /// GPS-Position, capacatiy, flying time...
1728
        /// </summary>
1729
        /// <param name="data">the received byte array to process</param>
1730
        void _processNCData(byte[] data)
1731
        {
1732
            int i_32, i_16, iVal;
1733
            double d;
1734
            i_32 = data[4];
1735
            iVal = i_32 << 24;
1736
            i_32 = data[3];
1737
            iVal += i_32 << 16;
1738
            i_32 = data[2];
1739
            iVal += i_32 << 8;
1740
            iVal += data[1];
1741
            d = (double)iVal / Math.Pow(10, 7);
2324 - 1742
            Dispatcher.Invoke(() => { drGPX[2] = d; });
1743
 
2287 - 1744
            PointLatLng p = new PointLatLng();
1745
 
1746
            p.Lng = d;
1747
          //  lblNCGPSLong.Invoke((Action)(() => lblNCGPSLong.Text = d.ToString("0.######°"))); //GPS-Position: Longitude in decimal degree
1748
            //lblNCGPSLong.Invoke((Action)(() => lblNCGPSLong.Text = _convertDegree(d))); //GPS-Position: Longitude in minutes, seconds
1749
 
1750
            i_32 = data[8];
1751
            iVal = i_32 << 24;
1752
            i_32 = data[7];
1753
            iVal += i_32 << 16;
1754
            i_32 = data[6];
1755
            iVal += i_32 << 8;
1756
            iVal += data[5];
1757
            d = (double)iVal / Math.Pow(10, 7);
2324 - 1758
            Dispatcher.Invoke(() => { drGPX[1] = d; });
1759
            Dispatcher.Invoke(() => { drGPX[4] = DateTime.UtcNow.ToString("u", System.Globalization.CultureInfo.InvariantCulture); }); //2011-01-14T01:59:01Z });
2287 - 1760
            p.Lat = d;
2291 - 1761
            if (data[50] > 4)//if more than 4 sats in use . otherwise the map would jump and scroll insane at beginning
1762
            {
1763
                _bSatFix = true; _iSatsJitter = 0; _bVoiceSatFixActive = false;
2295 - 1764
                if(_bAutoHome && !_bFirstSatFix)
1765
                {
1766
                    if (_iFirstSatFix < 3)
1767
                        _iFirstSatFix++;
1768
                    else
1769
                    {
1770
                        _bFirstSatFix = true;
2347 - 1771
                        Dispatcher.Invoke(() => _setHomePos());
2295 - 1772
                    }
1773
                }
2291 - 1774
                if (stbSatFixLostAnim != null && _bAnimSatFixActive)
1775
                {
1776
                    Dispatcher.Invoke(() => stbSatFixLostAnim.Stop());
1777
                    _bAnimSatFixActive = false;
1778
                }
1779
                if (!_bFollowCopter)
1780
                {
1781
                    _setCopterData(p);
1782
                    if (!MainMap.ViewArea.Contains(p))
1783
                        Dispatcher.Invoke(() => MainMap.Position = p);
2287 - 1784
 
2291 - 1785
                }
1786
                else
2287 - 1787
                    Dispatcher.Invoke(() => MainMap.Position = p);
1788
            }
1789
            else
2291 - 1790
            {
1791
                if(_bSatFix)
1792
                {
1793
                    if (data[50] == _iSatsLast)
1794
                    {
1795
                        if (_iSatsJitter < 20) _iSatsJitter++;
1796
                    }
1797
                    else
1798
                    {
1799
                        _iSatsJitter = 0;
1800
                        _iSatsLast = data[50];
1801
                    }
2287 - 1802
 
2291 - 1803
                    if (_iSatsJitter == 20)
1804
                    {
1805
                        if (stbSatFixLostAnim != null && !_bAnimSatFixActive)
1806
                        {
1807
                            Dispatcher.Invoke(() => stbSatFixLostAnim.Begin());
1808
                            _bAnimSatFixActive = true;
1809
                        }
1810
                        if (_bVoiceSatFixPlay && !_bVoiceSatFixActive)
1811
                        {
2335 - 1812
                            Thread th = new Thread(() => _mediaPlayer("Voice\\SatFixLost.mp3"));
2295 - 1813
                            th.Start();
2291 - 1814
                            _bVoiceSatFixActive = true;
1815
                        }
1816
 
1817
                        _bSatFix = false;
1818
                    }
1819
                }
1820
            }
1821
 
2287 - 1822
            i_16 = data[28];
1823
            i_16 = (Int16)(i_16 << 8);
1824
            iVal = data[27] + i_16;
1825
            Dispatcher.Invoke((Action)(() => tbWP.Text = ((double)iVal / (double)10).ToString("0.0 m"))); //Distance to next WP
1826
 
1827
            i_16 = data[45];
1828
            i_16 = (Int16)(i_16 << 8);
1829
            iVal = data[44] + i_16;
1830
        //    Dispatcher.Invoke((Action)(() => tbTopDistanceHP.Text = ((double)iVal / (double)10).ToString("0.0 m"))); //Distance to HP set by GPS on
1831
            Dispatcher.Invoke((Action)(() => tbHP.Text = ((double)iVal / (double)10).ToString("0.0 m"))); //Distance to HP set by GPS on
1832
 
1833
            Dispatcher.Invoke((Action)(() => tbWPIndex.Text = data[48].ToString())); //Waypoint index
2355 - 1834
            Dispatcher.Invoke((Action)(() => lblWPIndexNC.Content = data[48].ToString()));
2347 - 1835
            if(data[48] > 0 && _wpIndex != data[48] -1 && wpList.Count > 0)
2342 - 1836
            {
2347 - 1837
                _setActiveWP(data[48]-1);
2355 - 1838
                if((data[67] & 2) == 2)
1839
                    Dispatcher.Invoke(() => {
1840
                        DataGridRow row;
1841
                        if (_wpIndex > -1)
1842
                        {
1843
                            row = (DataGridRow)dgvWP.ItemContainerGenerator.ContainerFromIndex(_wpIndex);
1844
                            row.Background = new SolidColorBrush(Colors.Transparent);
1845
                            row.BorderBrush = new SolidColorBrush(Colors.Transparent);
1846
                            row.BorderThickness = new Thickness(0);
1847
                        }
1848
                        _wpIndex = data[48] - 1;
1849
                        row = (DataGridRow)dgvWP.ItemContainerGenerator.ContainerFromIndex(_wpIndex);
2366 - 1850
                        row.Background = new SolidColorBrush(Color.FromArgb(80, 0, 255, 100));
1851
                        row.BorderBrush = new SolidColorBrush(Colors.SpringGreen);
2355 - 1852
                        row.BorderThickness = new Thickness(2);
1853
                        dgvWP.UpdateLayout();
1854
                    });
2347 - 1855
                _wpIndex = data[48]-1;
2342 - 1856
            }
2347 - 1857
            else
1858
            {
1859
                if ((data[48] == 0 || wpList.Count == 0) & MainMap.Markers.Contains(wpActiveMarker))
2355 - 1860
                {
2347 - 1861
                    Dispatcher.Invoke(() => MainMap.Markers.Remove(wpActiveMarker));
2355 - 1862
                    Dispatcher.Invoke(() =>
1863
                    {
1864
                        DataGridRow row;
2368 - 1865
                        if (_wpIndex > -1 && data[48] == 0 && wpList.Count > _wpIndex)
2355 - 1866
                        {
1867
                            row = (DataGridRow)dgvWP.ItemContainerGenerator.ContainerFromIndex(_wpIndex);
1868
                            row.Background = new SolidColorBrush(Colors.Transparent);
1869
                            row.BorderBrush = new SolidColorBrush(Colors.Transparent);
1870
                            row.BorderThickness = new Thickness(0);
1871
                            _wpIndex = -1;
1872
                        }
1873
                    });
1874
 
1875
                }
2347 - 1876
            }
2342 - 1877
 
2287 - 1878
            Dispatcher.Invoke((Action)(() => tbWPCount.Text = data[49].ToString())); //Waypoints count
2355 - 1879
            Dispatcher.Invoke((Action)(() => lblWPCountNC.Content = data[49].ToString())); //Waypoints count
2340 - 1880
            _wpCount = data[49];
2287 - 1881
            Dispatcher.Invoke((Action)(() => tbTopSats.Text = data[50].ToString())); //Satellites
1882
 
1883
            //--------------- Capacity used ------------------------
1884
            i_16 = data[81];
1885
            i_16 = (Int16)(i_16 << 8);
1886
            iVal = data[80] + i_16;
1887
            Dispatcher.Invoke((Action)(() => tbCapacity.Text = iVal.ToString() + " mAh"));
1888
            Dispatcher.Invoke((Action)(() => tbTopCapacity.Text = iVal.ToString() + " mAh"));
1889
 
1890
            //--------------- Flying time ------------------------
1891
            i_16 = data[56];
1892
            i_16 = (Int16)(i_16 << 8);
1893
            iVal = data[55] + i_16;
1894
            TimeSpan t = TimeSpan.FromSeconds(iVal);
1895
            string Text = t.Hours.ToString("D2") + ":" + t.Minutes.ToString("D2") + ":" + t.Seconds.ToString("D2");
1896
            Dispatcher.Invoke((Action)(() => tbFTime.Text = Text.ToString()));
1897
            Dispatcher.Invoke((Action)(() => tbTopFTime.Text = Text.ToString()));
1898
 
1899
            //--------------- RC quality ------------------------
1900
            Dispatcher.Invoke((Action)(() => tbRCQ.Text = data[66].ToString()));
1901
            Dispatcher.Invoke((Action)(() => tbTopRC.Text = data[66].ToString()));
1902
 
2291 - 1903
            if(data[66] > _iThresholdRC)
1904
            {
1905
                _iRCLevelJitter = 0; _bVoiceRCLevelActive = false;
1906
                if (stbRCLevelAnim != null && _bAnimRCLevelActive)
1907
                {
1908
                    Dispatcher.Invoke(() => stbRCLevelAnim.Stop());
1909
                    _bAnimRCLevelActive = false;
1910
                }
1911
            }
1912
            else
1913
            {
1914
                if (_iRCLevelJitter < 20) _iRCLevelJitter++;
1915
                if (_iRCLevelJitter == 20)
1916
                {
1917
                    if (stbRCLevelAnim != null && !_bAnimRCLevelActive)
1918
                    {
1919
                        Dispatcher.Invoke(() => stbRCLevelAnim.Begin());
1920
                        _bAnimRCLevelActive = true;
1921
                    }
1922
                    if (_bVoiceRCLevelPlay && !_bVoiceRCLevelActive)
1923
                    {
2295 - 1924
                        Thread th = new Thread(() => _mediaPlayer("Voice\\RCLevel.mp3"));
1925
                        th.Start();
2291 - 1926
                        _bVoiceRCLevelActive = true;
1927
                    }
1928
                        _iRCLevelJitter++;
1929
                }
1930
            }
1931
 
2287 - 1932
            //--------------- NC Error ------------------------
1933
            Dispatcher.Invoke((Action)(() => tbNCErr.Text = data[69].ToString()));  //NC Errornumber
1934
            if (data[69] > 0)
1935
                _readNCError();
1936
            if (data[69] > 0 & data[69] < 44)
2381 - 1937
                ErrorLog(LogMsgType.Error," NC Error [" + data[69].ToString() + "]: ",NC_Error_Link[data[69]], NC_Error[data[69]]);
1938
            //else
1939
            //    if (_bErrorLog) _clearErrorLog("NC Error");
2287 - 1940
 
2298 - 1941
            //-------------FC / NC Status Flags
1942
            Dispatcher.Invoke((Action)(() => FC1_1.Background = ((data[67] & 1) ==1) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS_MOTOR_RUN                             0x01
1943
            Dispatcher.Invoke((Action)(() => FC1_2.Background = ((data[67] & 2) ==2) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS_FLY                                   0x02
1944
            Dispatcher.Invoke((Action)(() => FC1_3.Background = ((data[67] & 4) ==4) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS_CALIBRATE                             0x04
1945
            Dispatcher.Invoke((Action)(() => FC1_4.Background = ((data[67] & 8) ==8) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS_START                                 0x08
1946
            Dispatcher.Invoke((Action)(() => FC1_5.Background = ((data[67] & 16) ==16) ? new SolidColorBrush(Colors.LightCoral) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS_EMERGENCY_LANDING                      0x10
1947
            Dispatcher.Invoke((Action)(() => FC1_6.Background = ((data[67] & 32) ==32) ? new SolidColorBrush(Colors.LightCoral) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS_LOWBAT                         0x20
1948
 
1949
            Dispatcher.Invoke((Action)(() => FC2_1.Background = ((data[74] & 1) ==1) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS2_CAREFREE                             0x01
1950
            Dispatcher.Invoke((Action)(() => FC2_2.Background = ((data[74] & 2) ==2) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS2_ALTITUDE_CONTROL                     0x02
1951
            Dispatcher.Invoke((Action)(() => FC2_3.Background = ((data[74] & 4) ==4) ? new SolidColorBrush(Colors.LightCoral) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS2_RC_FAILSAVE_ACTIVE                      0x04
1952
            Dispatcher.Invoke((Action)(() => FC2_4.Background = ((data[74] & 8) ==8) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS2_OUT1_ACTIVE                          0x08
1953
            Dispatcher.Invoke((Action)(() => FC2_5.Background = ((data[74] & 16) ==16) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS2_OUT2_ACTIVE                        0x10
1954
            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
1955
            Dispatcher.Invoke((Action)(() => FC2_7.Background = ((data[74] & 64) ==64) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS2_AUTO_STARTING                              0x40
1956
            Dispatcher.Invoke((Action)(() => FC2_8.Background = ((data[74] & 128) ==128) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS2_AUTO_LANDING                             0x80
1957
 
1958
            Dispatcher.Invoke((Action)(() => NC1_2.Background = ((data[68] & 2) == 2) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// NC_FLAG_PH                                     0x02
1959
            Dispatcher.Invoke((Action)(() => NC1_3.Background = ((data[68] & 4) == 4) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// NC_FLAG_CH                                     0x04
1960
            Dispatcher.Invoke((Action)(() => NC1_4.Background = ((data[68] & 8) == 8) ? new SolidColorBrush(Colors.LightCoral) : new SolidColorBrush(Colors.Transparent)));// NC_FLAG_RANGE_LIMIT                               0x08
1961
            Dispatcher.Invoke((Action)(() => NC1_5.Background = ((data[68] & 16) == 16) ? new SolidColorBrush(Colors.LightCoral) : new SolidColorBrush(Colors.Transparent)));// NC_FLAG_NOSERIALLINK                            0x10
1962
            Dispatcher.Invoke((Action)(() => NC1_6.Background = ((data[68] & 32) == 32) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// NC_FLAG_TARGET_REACHED                               0x20
1963
            Dispatcher.Invoke((Action)(() => NC1_7.Background = ((data[68] & 64) == 64) ? new SolidColorBrush(Colors.DodgerBlue) : new SolidColorBrush(Colors.Transparent)));// NC_FLAG_MANUAL_CONTROL                          0x40
1964
            Dispatcher.Invoke((Action)(() => NC1_8.Background = ((data[68] & 128) == 128) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// NC_FLAG_GPS_OK                                     0x80
2299 - 1965
 
1966
            //Sidebar StatusSymbols
1967
            Dispatcher.Invoke((Action)(() => tbSideBarStatusMotors.Background = ((data[67] & 1) ==1) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS_MOTOR_RUN                             0x01
1968
            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
1969
            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
1970
 
1971
            Dispatcher.Invoke((Action)(() => tbSideBarStatusCF.Background = ((data[74] & 1) == 1) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS2_CAREFREE                                0x01
1972
            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
1973
            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
1974
 
1975
            Dispatcher.Invoke((Action)(() => tbSideBarStatusEmergencyLanding.Background = ((data[67] & 16) == 16) ? new SolidColorBrush(Colors.LightCoral) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS_EMERGENCY_LANDING                   0x10
2304 - 1976
            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
1977
            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 - 1978
 
1979
            Dispatcher.Invoke((Action)(() => tbSideBarStatusAC.Background = ((data[74] & 2) ==2) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS2_ALTITUDE_CONTROL                         0x02
1980
            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
1981
            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
1982
 
1983
            Dispatcher.Invoke((Action)(() => tbSideBarStatusPH.Text = ((data[68] & 4) == 4) ? "CH" : "PH"));// NC_FLAG_PH 0x02 / NC_FLAG_CH 0x04
2304 - 1984
            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
1985
            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
1986
            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 - 1987
 
2324 - 1988
            _bAirborne = (data[67] & 2) == 2 ? true : false;
2287 - 1989
        }
1990
        /// <summary>
1991
        /// Navi-Ctrl WP data struct 'X'
1992
        /// called by index
1993
        /// </summary>
1994
        /// <param name="data">the received byte array to process</param>
1995
        void _processWPData(byte[] data)
1996
        {
2313 - 1997
            _iWPCount = data[0];
2287 - 1998
            _bGetWPCount = false;
1999
            if (data.Length >= 28)
2000
            {
2001
                Dispatcher.Invoke(() => lblWPIndex.Content = data[1].ToString());
2002
                Dispatcher.Invoke(() => lblWPCount.Content = data[0].ToString());
2003
                if (_bGetWP)
2004
                {
2005
                    if (data[1] == 1)
2315 - 2006
                    {
2333 - 2007
                        Dispatcher.Invoke(() =>
2008
                        {
2356 - 2009
                            wpList.Clear();
2010
                            _clearMapMarkers(typeof(CustomMarkerWP));
2011
                            if (mRouteWP != null)
2012
                                MainMap.Markers.Remove(mRouteWP);
2013
                            if (wpActiveMarker != null)
2014
                                MainMap.Markers.Remove(wpActiveMarker);
2015
                            lblWPRouteDistance.Content = "0 m";
2016
                            dtWaypoints.Rows.Clear();
2368 - 2017
                            _wpEdit = -1;_wpIndex = -1;
2318 - 2018
                        });
2315 - 2019
                    }
2287 - 2020
                    DataRow dr = dtWaypoints.NewRow();
2021
                    dr = Waypoints.toDataRow(data, dr);
2313 - 2022
                    dtWaypoints.Rows.Add(dr);
2363 - 2023
                    _createWP(new PointLatLng((double)dr[3], (double)dr[4]), (string)dr[2], (int)dr[1]);
2313 - 2024
                    Dispatcher.Invoke(() => dgvWP.Items.Refresh());
2025
                    Dispatcher.Invoke(() => _iWPIndex = data[1]);
2287 - 2026
                    if (data[1] == data[0])
2027
                    {
2028
                        _bGetWP = false;
2368 - 2029
                        _routeUpdate();
2287 - 2030
                    }
2031
 
2032
                }
2033
            }
2034
            else
2035
            {
2036
                Dispatcher.Invoke(() => lblWPIndex.Content = 0);
2037
                Dispatcher.Invoke(() => lblWPCount.Content = 0);
2038
            }
2039
        }
2040
        /// <summary>
2041
        /// OSD Menue 'L'
2042
        /// single page called by pagenumber
2043
        /// no autoupdate
2044
        /// </summary>
2045
        /// <param name="data">the received byte array to process</param>
2046
        void _processOSDSingle(byte[] data)
2047
        {
2048
            if (data.Length == 84)
2049
            {
2050
                string sMessage = "";
2051
                iOSDPage = data[0];
2052
                iOSDMax = data[1];
2053
                if (cbOSD.Items.Count != iOSDMax) _initOSDCB();
2054
                sMessage = new string(ASCIIEncoding.ASCII.GetChars(data, 2, data.Length - 4));
2055
                OSD(LogMsgType.Incoming, sMessage.Substring(0, 20)+ "\r", true);
2056
                OSD(LogMsgType.Incoming, sMessage.Substring(20, 20)+ "\r", false);
2057
                OSD(LogMsgType.Incoming, sMessage.Substring(40, 20)+ "\r", false);
2058
                OSD(LogMsgType.Incoming, sMessage.Substring(60, 20), false);
2059
                Dispatcher.Invoke(() => { cbOSD.SelectedValue = iOSDPage; });
2060
              //  lblOSDPageNr.Invoke((Action)(() => lblOSDPageNr.Text = iOSDPage.ToString("[0]")));
2061
 
2062
            }
2063
            //else
2064
            //    OSD(LogMsgType.Incoming, "Wrong length: " + data.Length + " (should be 84)");
2065
 
2066
        }
2067
        /// <summary>
2068
        /// OSD Menue 'H'
2069
        /// called by keys (0x01,0x02,0x03,0x04)
2070
        /// autoupdate
2071
        /// </summary>
2072
        /// <param name="data">the received byte array to process</param>
2073
        void _processOSDAuto(byte[] data)
2074
        {
2075
            if (data.Length == 81)
2076
            {
2077
                string sMessage = "";
2078
                sMessage = new string(ASCIIEncoding.ASCII.GetChars(data, 0, data.Length - 1));
2079
                OSD(LogMsgType.Incoming, sMessage.Substring(0, 20)+ "\r", true);
2080
                OSD(LogMsgType.Incoming, sMessage.Substring(20, 20)+ "\r", false);
2081
                OSD(LogMsgType.Incoming, sMessage.Substring(40, 20)+ "\r", false);
2082
                OSD(LogMsgType.Incoming, sMessage.Substring(60, 20), false);
2083
 
2084
            }
2085
            //else
2086
            //    OSD(LogMsgType.Incoming, "Wrong length: " + data.Length + " (should be 81)");
2087
        }
2088
 
2089
        #endregion processing received data
2090
 
2091
        #region controller messages
2092
        /// <summary> send message to controller to request data
2093
        /// for detailed info see http://wiki.mikrokopter.de/en/SerialProtocol/
2094
        /// </summary>
2095
        /// <param name="CMDID"> the command ID </param>
2096
        /// <param name="address"> the address of the controller: 0-any, 1-FC, 2-NC </param>
2097
        private void _sendControllerMessage(char CMDID, byte address)
2098
        {
2099
            if (serialPortCtrl.Port.IsOpen)
2100
            {
2101
                Stream serialStream = serialPortCtrl.Port.BaseStream;
2102
                byte[] bytes = FlightControllerMessage.CreateMessage(CMDID, address);
2103
                serialStream.Write(bytes, 0, bytes.Length);
2104
 
2105
            }
2106
            else
2107
                Log(LogMsgType.Error, "NOT CONNECTED!");
2108
        }
2109
        /// <summary> send message to controller to request data
2110
        /// for detailed info see http://wiki.mikrokopter.de/en/SerialProtocol/
2111
        /// </summary>
2112
        /// <param name="CMDID"> the command ID </param>
2113
        /// <param name="address"> the address of the controller: 0-any, 1-FC, 2-NC </param>
2114
        /// <param name="data"> additional data for the request</param>
2115
        private void _sendControllerMessage(char CMDID, byte address, byte[] data)
2116
        {
2117
            if (serialPortCtrl.Port.IsOpen)
2118
            {
2119
                Stream serialStream = serialPortCtrl.Port.BaseStream;
2120
                byte[] bytes = FlightControllerMessage.CreateMessage(CMDID, address, data);
2121
                serialStream.Write(bytes, 0, bytes.Length);
2122
 
2123
            }
2124
            else
2125
                Log(LogMsgType.Error, "NOT CONNECTED!");
2126
        }
2127
 
2128
        /// <summary>
2129
        /// start/stop continous polling of controller values
2130
        /// </summary>
2131
        /// <param name="b">start/stop switch</param>
2132
        void _readCont(bool b)
2133
        {
2134
            bReadContinously = b;
2135
            if (bReadContinously)
2136
            {
2137
                if (_debugDataAutorefresh) { _readDebugData(true); Thread.Sleep(10); }
2138
                if (_blctrlDataAutorefresh) { _readBLCtrl(true); Thread.Sleep(10); }
2139
                if (_navCtrlDataAutorefresh && _iCtrlAct == 2) { _readNavData(true); Thread.Sleep(10); }
2140
                if (_OSDAutorefresh) { _OSDMenueAutoRefresh(); Thread.Sleep(10); }
2141
                // Dispatcher.Invoke((Action)(() => rctConnection.Fill = Brushes.LightGreen));
2142
                Dispatcher.Invoke(() => imageConn.Source = new BitmapImage(new Uri("Images/Data_G.png", UriKind.Relative)));
2143
            }
2144
            else
2145
            {
2146
                // Dispatcher.Invoke((Action)(() => rctConnection.Fill = Brushes.LightGray));
2147
                Dispatcher.Invoke(() => imageConn.Source = new BitmapImage(new Uri("Images/Data_W.png", UriKind.Relative)));
2148
                _bConnErr = false;
2149
            }
2150
            _iLifeCounter = 0;
2151
        }
2152
 
2153
        private void _getVersion()
2154
        {
2155
            _sendControllerMessage('v', 0);
2156
        }
2157
        /// <summary>
2158
        /// get FC version struct via NC
2159
        /// by sending '1' as data (not documented in wiki...)
2160
        /// returns HW error 255 (comment in uart1.c : tells the KopterTool that it is the FC-version)
2161
        /// </summary>
2162
        /// <param name="ctrl">controller number 1=FC</param> 
2163
        private void _getVersion(byte ctrl)
2164
        {
2165
            _sendControllerMessage('v', 0, new byte[1] { ctrl });
2166
        }
2167
        /// <summary>
2168
        /// Switch back to NC by sending the 'Magic Packet' 0x1B,0x1B,0x55,0xAA,0x00
2169
        /// </summary>
2170
        private void _switchToNC()
2171
        {
2172
            if (serialPortCtrl.Port.IsOpen)
2173
            {
2174
                Stream serialStream = serialPortCtrl.Port.BaseStream;
2175
                byte[] bytes = new byte[5] { 0x1B, 0x1B, 0x55, 0xAA, 0x00 };
2176
                serialStream.Write(bytes, 0, bytes.Length);
2177
 
2178
                Thread.Sleep(100);
2179
                _getVersion();
2180
                Thread.Sleep(100);
2181
               // _OSDMenue(0);
2182
            }
2183
            else
2184
                Log(LogMsgType.Error, "NOT CONNECTED!");
2185
        }
2186
        /// <summary>
2187
        /// switch to FC
2188
        /// </summary>
2189
        private void _switchToFC()
2190
        {
2191
            _sendControllerMessage('u', 2, new byte[1] { (byte)0 });
2192
            Thread.Sleep(100);
2193
            _getVersion();
2194
            Thread.Sleep(100);
2195
          //  _OSDMenue(0);
2196
        }
2197
        /// <summary>
2198
        /// send RESET signal to FC
2199
        /// </summary>
2200
        private void _resetCtrl()
2201
        {
2202
            _sendControllerMessage('R', 1);
2203
        }
2204
        /// <summary>
2205
        /// poll the debug data (4sec subscription)
2206
        /// </summary>
2207
        /// <param name="auto"> onetimequery(false) or autoupdate(true) with set timing interval </param>
2208
        private void _readDebugData(bool auto)
2209
        {
2210
            byte interval = auto ? debugInterval : (byte)0;
2211
            _sendControllerMessage('d', 0, new byte[1] { debugInterval });
2212
        }
2213
        /// <summary>
2214
        /// poll the BL-CTRL status via NC (4sec subscription)
2215
        /// </summary>
2216
        /// <param name="auto"> onetimequery(false) or autoupdate(true) with set timing interval </param>
2217
        private void _readBLCtrl(bool auto)
2218
        {
2219
            byte interval = auto ? blctrlInterval : (byte)0;
2220
            _sendControllerMessage('k', 0, new byte[1] { interval });
2221
        }
2222
        /// <summary>
2223
        /// poll the NC data struct (4sec subscription)
2224
        /// </summary>
2225
        /// <param name="auto"> onetimequery(false) or autoupdate(true) with set timing interval </param>
2226
        private void _readNavData(bool auto)
2227
        {
2228
            byte interval = auto ? navctrlInterval : (byte)0;
2229
            _sendControllerMessage('o', 2, new byte[1] { interval });
2230
        }
2231
        /// <summary>
2232
        /// get the errortext for pending NC error
2233
        /// </summary>
2234
        private void _readNCError()
2235
        {
2236
            _sendControllerMessage('e', 2);
2237
        }
2238
        /// <summary>
2239
        /// request the Waypoint at index
2240
        /// </summary>
2241
        /// <param name="index"></param>
2242
        void _getpWP(int index)
2243
        {
2244
            if (serialPortCtrl.Port.IsOpen)
2245
            {
2246
                Stream serialStream = serialPortCtrl.Port.BaseStream;
2247
                byte[] bytes = FlightControllerMessage.CreateMessage('x', 2, new byte[1] { (byte)index });
2248
                serialStream.Write(bytes, 0, bytes.Length);
2249
            }
2250
            else
2251
                Log(LogMsgType.Error, "NOT CONNECTED!");
2252
 
2253
        }
2254
        void _getWP()
2255
        {
2335 - 2256
            int iTimeout = 0;
2287 - 2257
            _bGetWPCount = true;
2315 - 2258
            _getpWP(1); //get the itemscount of wp
2335 - 2259
            while (_bGetWPCount & iTimeout < _iWPTimeout * 5)
2260
            {
2261
                Thread.Sleep(10);
2262
                iTimeout++;
2263
            }
2264
            if (_iWPCount > 0 & !_bGetWPCount)
2287 - 2265
                _getWPList();
2266
        }
2267
        void _getWPList()
2268
        {
2269
            _bGetWP = true;
2313 - 2270
            int iTimeout=0;
2271
            for (int j = 0; j < _iWPCount; j++)
2287 - 2272
            {
2273
                _getpWP(j + 1);
2313 - 2274
                iTimeout = 0;
2275
                while (_iWPIndex != j + 1 & iTimeout < _iWPTimeout * 5)
2276
                {
2277
                    Thread.Sleep(1);
2278
                    iTimeout++;
2279
                }
2287 - 2280
            }
2281
        }
2363 - 2282
        /// <summary>
2283
        /// Wrapper for _clearCopterWPList()
2284
        /// necessary, cause it is called by threadnew which does not like return values...
2285
        /// </summary>
2340 - 2286
        void clearCopterWPList()
2313 - 2287
        {
2340 - 2288
            _clearCopterWPList();
2289
        }
2363 - 2290
        /// <summary>
2291
        /// clear the WP list of the copter
2292
        /// by sending 'invalid' and index '0'
2293
        /// </summary>
2294
        /// <returns></returns>
2340 - 2295
        bool _clearCopterWPList()
2296
        {
2335 - 2297
            int iTimeout = 0;
2313 - 2298
            if (serialPortCtrl.Port.IsOpen)
2299
            {
2300
                byte[] bData = new byte[30];
2301
                for (int i = 0; i < 30; i++)
2302
                    bData[i] = 0;
2303
                Stream serialStream = serialPortCtrl.Port.BaseStream;
2304
                byte[] bytes = FlightControllerMessage.CreateMessage('w', 2, bData); //delete all WP on Copter by sending 'invalid'(==0) at index 0
2305
                serialStream.Write(bytes, 0, bytes.Length);
2287 - 2306
 
2313 - 2307
                _iWPCount = -1;
2340 - 2308
                while (_iWPCount == -1 & iTimeout < _iWPTimeout)
2335 - 2309
                {
2313 - 2310
                    Thread.Sleep(10);
2335 - 2311
                    iTimeout++;
2312
                }
2313 - 2313
                Dispatcher.Invoke(() => lblWPCount.Content = _iWPCount.ToString());
2335 - 2314
                if (_iWPCount > -1)
2340 - 2315
                    return true;
2316
                else
2317
                    Log(LogMsgType.Error, "Timeout while sending list!");
2318
            }
2319
            else
2320
                Log(LogMsgType.Error, "NOT CONNECTED!");
2321
 
2322
            return false;
2323
}
2324
        void _sendWPList()
2325
        {
2362 - 2326
            _sendWPList(0);
2327
        }
2328
        void _sendWPList(int iStart)
2329
        {
2340 - 2330
            int iTimeout = 0;
2331
            if (serialPortCtrl.Port.IsOpen)
2332
            {
2333
                if (_clearCopterWPList())
2313 - 2334
                {
2362 - 2335
                    int k = 1;
2336
                    for (int i = iStart; i < dtWaypoints.Rows.Count; i++)
2335 - 2337
                    {
2362 - 2338
                        k = iStart > 0 ? k : -1;
2376 - 2339
                        _sendWayPoint(dtWaypoints.Rows[i], k, 'w',false);
2313 - 2340
 
2335 - 2341
                        _iWPCount = -1;
2342
                        iTimeout = 0;
2343
                        while (_iWPCount == -1 & iTimeout < _iWPTimeout * 5)
2344
                        {
2345
                            Thread.Sleep(10);
2346
                            iTimeout++;
2347
                        }
2348
                        if (_iWPCount == -1)
2349
                        {
2350
                            Log(LogMsgType.Error, "Timeout while sending list!");
2351
                            break;
2352
                        }
2353
                        Dispatcher.Invoke(() => lblWPCount.Content = _iWPCount.ToString());
2362 - 2354
                        k++;
2335 - 2355
                    }
2313 - 2356
                }
2357
            }
2358
            else
2359
                Log(LogMsgType.Error, "NOT CONNECTED!");
2360
 
2361
        }
2376 - 2362
        bool _sendWayPoint(DataRow dr, int index, char command,bool bSim)
2340 - 2363
        {
2313 - 2364
 
2340 - 2365
            if (serialPortCtrl.Port.IsOpen)
2366
            {
2367
                byte[] bData = new byte[30];
2368
                for (int i = 0; i < 30; i++)
2369
                    bData[i] = 0;
2370
                Stream serialStream = serialPortCtrl.Port.BaseStream;
2371
                byte[] bytes;
2372
                int iVal;
2373
                double dVal;
2374
                NumberFormatInfo nfi = new NumberFormatInfo();
2375
                nfi.NumberDecimalSeparator = ",";
2376
 
2377
                //longitude
2378
                dVal = Convert.ToDouble(dr[4], nfi);
2379
                iVal = (int)(dVal * Math.Pow(10, 7));
2380
                bData[0] = (byte)(iVal & 0xff);
2381
                bData[1] = (byte)((iVal >> 8) & 0xff);
2382
                bData[2] = (byte)((iVal >> 16) & 0xff);
2383
                bData[3] = (byte)(iVal >> 24);
2384
                //latitude
2385
                dVal = Convert.ToDouble(dr[3], nfi);
2386
                iVal = (int)(dVal * Math.Pow(10, 7));
2387
                bData[4] = (byte)(iVal & 0xff);
2388
                bData[5] = (byte)((iVal >> 8) & 0xff);
2389
                bData[6] = (byte)((iVal >> 16) & 0xff);
2390
                bData[7] = (byte)(iVal >> 24);
2391
                //altitude
2392
                dVal = Convert.ToDouble(dr[5], nfi);
2393
                iVal = (int)(dVal * 10);
2394
                bData[8] = (byte)(iVal & 0xff);
2395
                bData[9] = (byte)((iVal >> 8) & 0xff);
2396
                bData[10] = (byte)((iVal >> 16) & 0xff);
2397
                bData[11] = (byte)(iVal >> 24);
2376 - 2398
                if(bSim)
2399
                    bData[12] = 3; //Status 'SIMULATE'
2340 - 2400
                //Status 'NEWDATA'
2376 - 2401
                else
2402
                    bData[12] = 1;
2340 - 2403
                //heading
2404
                iVal = Convert.ToInt16(dr[6]);
2405
                bData[13] = (byte)(iVal & 0xff);
2406
                bData[14] = (byte)((iVal >> 8) & 0xff);
2407
                //ToleranceRadius
2408
                bData[15] = Convert.ToByte(dr[9]);
2409
                //HoldTime
2410
                bData[16] = Convert.ToByte(dr[10]);
2411
                //Event_Flag
2412
                bData[17] = Convert.ToByte(dr[13]);
2413
                //Index
2379 - 2414
                bData[18] = index > -1 ? (byte)index : Convert.ToByte((int)dr[0]);
2340 - 2415
                //Type
2416
                bData[19] = Convert.ToByte(dr[1]);
2417
                //WP_EventChannelValue
2418
                bData[20] = Convert.ToByte(dr[14]);
2419
                //AltitudeRate
2420
                bData[21] = Convert.ToByte(dr[8]);
2421
                //Speed
2422
                bData[22] = Convert.ToByte(dr[7]);
2423
                //CamAngle
2424
                bData[23] = (byte)Convert.ToInt16(dr[12]);
2425
                //Name
2362 - 2426
                string s = index > 0 ? ((string)dr[2]).Substring(0, 1) + index.ToString() : (string)dr[2];
2427
                byte[] name = ASCIIEncoding.ASCII.GetBytes(s);
2340 - 2428
                bData[24] = name.Length > 0 ? name[0] : (byte)0;
2429
                bData[25] = name.Length > 1 ? name[1] : (byte)0;
2430
                bData[26] = name.Length > 2 ? name[2] : (byte)0;
2431
                bData[27] = name.Length > 3 ? name[3] : (byte)0;
2432
                //Autotrigger
2433
                bData[28] = Convert.ToByte(dr[11]);
2434
 
2356 - 2435
                bytes = FlightControllerMessage.CreateMessage(command, 2, bData);
2340 - 2436
                serialStream.Write(bytes, 0, bytes.Length);
2437
 
2438
                return true;
2439
            }
2440
 
2441
            return false;
2442
        }
2287 - 2443
        #region OSD-Menue
2444
 
2445
        /// <summary>
2446
        /// one time query of the OSD Menue with pagenumber
2447
        /// </summary>
2448
        /// <param name="iMenue">Menue page</param>
2449
        void _OSDMenue(int iMenue)
2450
        {
2451
            if (serialPortCtrl.Port.IsOpen)
2452
            {
2453
                if (iMenue > iOSDMax)
2454
                    iMenue = 0;
2455
                Stream serialStream = serialPortCtrl.Port.BaseStream;
2456
                byte[] bytes = FlightControllerMessage.CreateMessage('l', 0, new byte[1] { (byte)iMenue });
2457
                serialStream.Write(bytes, 0, bytes.Length);
2458
            }
2459
            else
2460
                Log(LogMsgType.Error, "NOT CONNECTED!");
2461
 
2462
        }
2463
        /// <summary>
2464
        /// call the OSDMenue and start autorefresh
2465
        ///  usually by sending a menuekey
2466
        /// 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)
2467
        /// therefore the value has to be negative (inverted) in order to distinguish from old (2 line) menuestyle
2468
        /// and must not have any bits of the menue keys 0x1 0x2 0x4 0x8 (0x10?) --> 0x20 = -33
2469
        /// </summary>
2470
        void _OSDMenueAutoRefresh()
2471
        {
2472
            _sendControllerMessage('h', 0, new byte[2] { unchecked((byte)(-33)), OSDInterval });
2473
        }
2474
        void _OSDMenueAutoRefresh(byte key)
2475
        {
2476
            _sendControllerMessage('h', 0, new byte[2] { unchecked((byte)~key), OSDInterval });
2477
        }
2478
        /// <summary>
2479
        /// initialize the OSD menue combobox
2480
        /// combox is filled by numbers from 0 to max pagenumber
2481
        /// </summary>
2482
        void _initOSDCB()
2483
        {
2484
            _bCBInit = true;
2485
            if (iOSDMax == 0)
2486
            {
2487
                _OSDMenue(0);
2488
                Thread.Sleep(10);
2489
            }
2490
            Dispatcher.Invoke((Action)(() => cbOSD.Items.Clear()));
2491
            for (int i = 0; i <= iOSDMax; i++)
2492
            {
2493
                Dispatcher.Invoke((Action)(() => cbOSD.Items.Add(i)));
2494
            }
2495
            Dispatcher.Invoke((Action)(() => cbOSD.SelectedItem = iOSDPage));
2496
            _bCBInit = false;
2497
        }
2498
        private void btnOSDForward_Click(object sender, RoutedEventArgs e)
2499
        {
2500
            iOSDPage++;
2501
            if (iOSDPage > iOSDMax)
2502
                iOSDPage = 0;
2503
 
2504
            _OSDMenue(iOSDPage);
2505
        }
2506
        private void btnOSDBackward_Click(object sender, RoutedEventArgs e)
2507
        {
2508
            iOSDPage--;
2509
            if (iOSDPage < 0)
2510
                iOSDPage = iOSDMax;
2511
 
2512
            _OSDMenue(iOSDPage);
2513
        }
2514
        private void btnOSDLeave_Click(object sender, RoutedEventArgs e)
2515
        {
2516
            _OSDMenueAutoRefresh(8);
2517
        }
2518
        private void btnOSDEnter_Click(object sender, RoutedEventArgs e)
2519
        {
2520
            _OSDMenueAutoRefresh(4);
2521
        }
2522
        private void cbOSD_DropDownClosing(object sender, EventArgs e)
2523
        {
2524
            if (!_bCBInit && cbOSD.SelectedIndex > -1)
2525
                _OSDMenue(cbOSD.SelectedIndex);
2526
        }
2527
        private void OSD(LogMsgType msgtype, string msg, bool bNew)
2528
        {
2529
            Dispatcher.Invoke(() =>
2530
            {
2531
                TextRange tr;
2532
                if (bNew)
2533
                {
2534
                    rtfOSD.SelectAll();
2535
                    rtfOSD.Selection.Text = string.Empty;
2536
                }
2537
                tr = new TextRange(rtfOSD.Document.ContentEnd, rtfOSD.Document.ContentEnd);
2538
                tr.Text = msg;
2539
                tr.ApplyPropertyValue(TextElement.ForegroundProperty, new SolidColorBrush(LogMsgTypeColor[(int)msgtype]));
2540
                //     rtfOSD.AppendText("\r");
2541
                rtfOSD.ScrollToEnd();
2542
 
2543
            });
2544
        }
2545
 
2546
        #endregion OSD-Menue
2547
 
2548
        #endregion controller messages
2549
 
2295 - 2550
        void _mediaPlayer(string file)
2551
        {
2552
            if (File.Exists(file))
2553
            {
2554
                MediaPlayer.MediaPlayer mp = new MediaPlayer.MediaPlayer();
2555
                mp.Open(file);
2556
                mp.Play();
2557
            }
2558
        }
2310 - 2559
 
2362 - 2560
        #region ui
2310 - 2561
        /// <summary>
2562
        /// Switch between fullscreen and normal window mode
2563
        /// save & restore scaling settings
2564
        /// </summary>
2565
        /// <param name="sender"></param>
2566
        /// <param name="e"></param>
2287 - 2567
        private void imageFullscreen_MouseDown(object sender, MouseButtonEventArgs e)
2568
        {
2569
            if (winState.isMaximized)
2570
            {
2571
                winState.Restore(this);
2572
                imageFullscreen.Source = new BitmapImage(new Uri("Images/Fullscreen.png", UriKind.Relative));
2573
                if(_bSaveWinStateFull)
2574
                    _saveScaleSliders(true);
2575
                if(_bSaveWinStateNormal)
2576
                    _setScaleSliders(false);
2577
            }
2578
            else
2579
            {
2580
                winState.Maximize(this);
2581
                imageFullscreen.Source = new BitmapImage(new Uri("Images/RestoreScreen.png", UriKind.Relative));
2582
                if(_bSaveWinStateNormal)
2583
                    _saveScaleSliders(false);
2584
                if(_bSaveWinStateFull)
2585
                    _setScaleSliders(true);
2586
            }
2587
        }
2588
 
2589
        /// <summary>
2590
        /// reset the scaling of all UI elements to default
2591
        /// </summary>
2592
        /// <param name="sender"></param>
2593
        /// <param name="e"></param>
2594
        private void buttonUIScaleReset_Click(object sender, RoutedEventArgs e)
2595
        {
2596
            UIScaleHorizonSlider.Value =
2597
                UIScaleLOGSlider.Value =
2598
                UIScaleMotorsSlider.Value =
2599
                UIScaleOSDSlider.Value =
2600
                UIScaleSlider.Value =
2601
                UIScaleTopSlider.Value = 1;
2602
        }
2603
        /// <summary>
2604
        /// adjust the top postion of UI elements below the top bar to fit the bottom position of the bar when scaling the top bar
2605
        /// </summary>
2606
        /// <param name="sender"></param>
2607
        /// <param name="e"></param>
2608
        private void UIScaleTopSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
2609
        {
2610
            GridSettings.Margin = new Thickness(GridSettings.Margin.Left, 36 * UIScaleTopSlider.Value, GridSettings.Margin.Right, GridSettings.Margin.Bottom);
2611
            if (GridMotors != null)
2612
                GridMotors.Margin = new Thickness(GridMotors.Margin.Left, 36 * UIScaleTopSlider.Value, GridMotors.Margin.Right, GridMotors.Margin.Bottom);
2613
            if (GridSideBar != null)
2614
                GridSideBar.Margin = new Thickness(GridSideBar.Margin.Left, 36 * UIScaleTopSlider.Value, GridSideBar.Margin.Right, GridSideBar.Margin.Bottom);
2615
            if (GridOSD != null)
2616
                GridOSD.Margin = new Thickness(GridOSD.Margin.Left, 36 * UIScaleTopSlider.Value, GridOSD.Margin.Right, GridOSD.Margin.Bottom);
2617
            if (GridData != null)
2618
                GridData.Margin = new Thickness(GridData.Margin.Left, 36 * UIScaleTopSlider.Value, GridData.Margin.Right, GridData.Margin.Bottom);
2619
            if (GridWP != null)
2620
                GridWP.Margin = new Thickness(GridWP.Margin.Left, 36 * UIScaleTopSlider.Value, GridWP.Margin.Right, GridWP.Margin.Bottom);
2621
        }
2310 - 2622
        /// <summary>
2623
        /// restore the saved scalings for the fullscreen/normal window mode
2624
        /// </summary>
2625
        /// <param name="bFull">the mode the window is set to</param>
2287 - 2626
        void _setScaleSliders(bool bFull)
2627
        {
2628
            if(bFull)
2629
            {
2630
                UIScaleSlider.Value = scaleFullAll;
2631
                UIScaleTopSlider.Value = scaleFullTopBar;
2632
                UIScaleMotorsSlider.Value = scaleFullMotors;
2633
                UIScaleOSDSlider.Value = scaleFullOSD;
2634
                UIScaleLOGSlider.Value = scaleFullLOG;
2635
                UIScaleHorizonSlider.Value = scaleFullHorizon;
2636
            }
2637
            else
2638
            {
2639
                UIScaleSlider.Value = scaleNormalAll;
2640
                UIScaleTopSlider.Value = scaleNormalTopBar;
2641
                UIScaleMotorsSlider.Value = scaleNormalMotors;
2642
                UIScaleOSDSlider.Value = scaleNormalOSD;
2643
                UIScaleLOGSlider.Value = scaleNormalLOG;
2644
                UIScaleHorizonSlider.Value = scaleNormalHorizon;
2645
            }
2646
        }
2647
 
2310 - 2648
        /// <summary>
2649
        /// save the scalings for the actual window mode
2650
        /// </summary>
2651
        /// <param name="bFull">the actual window mode</param>
2287 - 2652
        void _saveScaleSliders(bool bFull)
2653
        {
2654
 
2655
            if (bFull)
2656
            {
2657
                scaleFullAll = UIScaleSlider.Value;
2658
                scaleFullTopBar = UIScaleTopSlider.Value;
2659
                scaleFullMotors = UIScaleMotorsSlider.Value;
2660
                scaleFullOSD = UIScaleOSDSlider.Value;
2661
                scaleFullLOG = UIScaleLOGSlider.Value;
2662
                scaleFullHorizon = UIScaleHorizonSlider.Value;
2663
            }
2664
            else
2665
            {
2666
                scaleNormalAll = UIScaleSlider.Value;
2667
                scaleNormalTopBar = UIScaleTopSlider.Value;
2668
                scaleNormalMotors = UIScaleMotorsSlider.Value;
2669
                scaleNormalOSD = UIScaleOSDSlider.Value;
2670
                scaleNormalLOG = UIScaleLOGSlider.Value;
2671
                scaleNormalHorizon = UIScaleHorizonSlider.Value;
2672
            }
2673
        }
2362 - 2674
        #endregion ui
2287 - 2675
 
2676
        /// <summary>
2677
        /// read settings from ini-file
2678
        /// </summary>
2679
        void _readIni()
2680
        {
2681
            if (!File.Exists(filePath + "\\MKLiveViewSettings.ini"))
2682
                _writeIni();
2683
            IniFile ini = new IniFile("MKLiveViewSettings.ini");
2684
            ini.path = filePath + "\\MKLiveViewSettings.ini";
2312 - 2685
            try
2686
            {
2287 - 2687
 
2312 - 2688
                string sVal = ini.IniReadValue("timings", "AutorefreshDebugData");
2689
                if (sVal != "") _debugDataAutorefresh = Convert.ToBoolean(sVal);
2690
                sVal = ini.IniReadValue("timings", "AutorefreshNavCtrlData");
2691
                if (sVal != "") _navCtrlDataAutorefresh = Convert.ToBoolean(sVal);
2692
                sVal = ini.IniReadValue("timings", "AutorefreshBLCtrlData");
2693
                if (sVal != "") _blctrlDataAutorefresh = Convert.ToBoolean(sVal);
2694
                sVal = ini.IniReadValue("timings", "AutorefreshOSDData");
2695
                if (sVal != "") _OSDAutorefresh = Convert.ToBoolean(sVal);
2287 - 2696
 
2312 - 2697
                sVal = ini.IniReadValue("timings", "IntervalDebugData");
2698
                if (sVal != "") debugInterval = (byte)Convert.ToInt16(sVal);
2699
                sVal = ini.IniReadValue("timings", "IntervalNavCtrlData");
2700
                if (sVal != "") navctrlInterval = (byte)Convert.ToInt16(sVal);
2701
                sVal = ini.IniReadValue("timings", "IntervalBLCtrlData");
2702
                if (sVal != "") blctrlInterval = (byte)Convert.ToInt16(sVal);
2703
                sVal = ini.IniReadValue("timings", "IntervalOSDData");
2704
                if (sVal != "") OSDInterval = (byte)Convert.ToInt16(sVal);
2287 - 2705
 
2312 - 2706
                sVal = ini.IniReadValue("topBar", "voltage");
2707
                if (sVal != "") chkBoxTopBarShowVoltage.IsChecked = Convert.ToBoolean(sVal);
2708
                sVal = ini.IniReadValue("topBar", "capacity");
2709
                if (sVal != "") chkBoxTopBarShowCapacity.IsChecked = Convert.ToBoolean(sVal);
2710
                sVal = ini.IniReadValue("topBar", "current");
2711
                if (sVal != "") chkBoxTopBarShowCurrent.IsChecked = Convert.ToBoolean(sVal);
2712
                sVal = ini.IniReadValue("topBar", "flightTime");
2713
                if (sVal != "") chkBoxTopBarShowFlightTime.IsChecked = Convert.ToBoolean(sVal);
2714
                sVal = ini.IniReadValue("topBar", "distanceHP");
2715
                if (sVal != "") chkBoxTopBarShowDistanceHP.IsChecked = Convert.ToBoolean(sVal);
2716
                sVal = ini.IniReadValue("topBar", "height");
2717
                if (sVal != "") chkBoxTopBarShowHeight.IsChecked = Convert.ToBoolean(sVal);
2718
                sVal = ini.IniReadValue("topBar", "speed");
2719
                if (sVal != "") chkBoxTopBarShowSpeed.IsChecked = Convert.ToBoolean(sVal);
2720
                sVal = ini.IniReadValue("topBar", "magneticField");
2721
                if (sVal != "") chkBoxTopBarShowMF.IsChecked = Convert.ToBoolean(sVal);
2722
                sVal = ini.IniReadValue("topBar", "satellites");
2723
                if (sVal != "") chkBoxTopBarShowSatellites.IsChecked = Convert.ToBoolean(sVal);
2724
                sVal = ini.IniReadValue("topBar", "rc");
2725
                if (sVal != "") chkBoxTopBarShowRC.IsChecked = Convert.ToBoolean(sVal);
2287 - 2726
 
2312 - 2727
                sVal = ini.IniReadValue("style", "saveFullScreen");
2728
                if (sVal != "") chkBoxSaveFullScreenState.IsChecked = Convert.ToBoolean(sVal);
2729
                sVal = ini.IniReadValue("style", "saveNormalState");
2730
                if (sVal != "") chkBoxSaveNormalState.IsChecked = Convert.ToBoolean(sVal);
2287 - 2731
 
2312 - 2732
                sVal = ini.IniReadValue("style", "scaleNormalAll");
2733
                if (sVal != "") scaleNormalAll = Convert.ToDouble(sVal);
2734
                sVal = ini.IniReadValue("style", "scaleNormalTopBar");
2735
                if (sVal != "") scaleNormalTopBar = Convert.ToDouble(sVal);
2736
                sVal = ini.IniReadValue("style", "scaleNormalMotors");
2737
                if (sVal != "") scaleNormalMotors = Convert.ToDouble(sVal);
2738
                sVal = ini.IniReadValue("style", "scaleNormalOSD");
2739
                if (sVal != "") scaleNormalOSD = Convert.ToDouble(sVal);
2740
                sVal = ini.IniReadValue("style", "scaleNormalLOG");
2741
                if (sVal != "") scaleNormalLOG = Convert.ToDouble(sVal);
2742
                sVal = ini.IniReadValue("style", "scaleNormalHorizon");
2743
                if (sVal != "") scaleNormalHorizon = Convert.ToDouble(sVal);
2287 - 2744
 
2312 - 2745
                sVal = ini.IniReadValue("style", "scaleFullAll");
2746
                if (sVal != "") scaleFullAll = Convert.ToDouble(sVal);
2747
                sVal = ini.IniReadValue("style", "scaleFullTopBar");
2748
                if (sVal != "") scaleFullTopBar = Convert.ToDouble(sVal);
2749
                sVal = ini.IniReadValue("style", "scaleFullMotors");
2750
                if (sVal != "") scaleFullMotors = Convert.ToDouble(sVal);
2751
                sVal = ini.IniReadValue("style", "scaleFullOSD");
2752
                if (sVal != "") scaleFullOSD = Convert.ToDouble(sVal);
2753
                sVal = ini.IniReadValue("style", "scaleFullLOG");
2754
                if (sVal != "") scaleFullLOG = Convert.ToDouble(sVal);
2755
                sVal = ini.IniReadValue("style", "scaleFullHorizon");
2756
                if (sVal != "") scaleFullHorizon = Convert.ToDouble(sVal);
2287 - 2757
 
2312 - 2758
                sVal = ini.IniReadValue("general", "LiPoCells");
2759
                _LipoCells = Convert.ToInt16(sVal);
2760
                sVal = ini.IniReadValue("general", "Motors");
2761
                if (sVal != "") _iMotors = Convert.ToInt16(sVal);
2287 - 2762
 
2312 - 2763
                sVal = ini.IniReadValue("map", "followMe");
2764
                if (sVal != "") _bFollowCopter = Convert.ToBoolean(sVal);
2765
                sVal = ini.IniReadValue("map", "AutoSetHome");
2766
                if (sVal != "") _bAutoHome = Convert.ToBoolean(sVal);
2324 - 2767
                sVal = ini.IniReadValue("map", "GPXLog");
2768
                if (sVal != "") _bGPXLog = Convert.ToBoolean(sVal);
2287 - 2769
 
2312 - 2770
                sVal = ini.IniReadValue("threshold", "VoltageWarning");
2771
                if(sVal != "") _dThresholdVoltageWarn = Convert.ToDouble(sVal);
2772
                sVal = ini.IniReadValue("threshold", "VoltageCritical");
2773
                if(sVal != "") _dThresholdVoltageCrit = Convert.ToDouble(sVal);
2774
                sVal = ini.IniReadValue("threshold", "VoiceVoltageEnable");
2775
                if(sVal != "") _bVoiceVoltPlay = Convert.ToBoolean(sVal);
2776
                sVal = ini.IniReadValue("threshold", "VoiceSatFixEnable");
2777
                if(sVal != "") _bVoiceSatFixPlay = Convert.ToBoolean(sVal);
2778
                sVal = ini.IniReadValue("threshold", "VoiceMagFieldEnable");
2779
                if(sVal != "") _bVoiceMagneticFieldPlay = Convert.ToBoolean(sVal);
2780
                sVal = ini.IniReadValue("threshold", "DistanceWarning");
2781
                if(sVal != "") _dThresholdDistanceWarn = Convert.ToDouble(sVal);
2782
                sVal = ini.IniReadValue("threshold", "VoiceDistanceWarnEnable");
2783
                if(sVal != "") _bVoiceDistancePlay = Convert.ToBoolean(sVal);
2784
                sVal = ini.IniReadValue("threshold", "VoiceRCLevelWarnEnable");
2785
                if(sVal != "") _bVoiceRCLevelPlay = Convert.ToBoolean(sVal);
2786
                sVal = ini.IniReadValue("threshold", "MaxDistance");
2787
                if(sVal != "") _dThresholdDistanceMax = Convert.ToDouble(sVal);
2788
                sVal = ini.IniReadValue("threshold", "RCThreshold");
2789
                if(sVal != "") _iThresholdRC = Convert.ToInt32(sVal);
2790
                sVal = ini.IniReadValue("threshold", "MagFieldThreshold");
2791
                if(sVal != "") _iThresholdMagField = Convert.ToInt32(sVal);
2321 - 2792
 
2793
                sVal = ini.IniReadValue("waypoints", "wpcolor");
2794
                if(sVal != "") comboBoxWPColor.SelectedIndex = Convert.ToInt32(sVal);
2795
                sVal = ini.IniReadValue("waypoints", "poicolor");
2796
                if(sVal != "") comboBoxPOIColor.SelectedIndex = Convert.ToInt32(sVal);
2797
                sVal = ini.IniReadValue("waypoints", "fscolor");
2798
                if(sVal != "") comboBoxFSColor.SelectedIndex = Convert.ToInt32(sVal);
2799
                sVal = ini.IniReadValue("waypoints", "coptercolor");
2800
                if(sVal != "") comboBoxCopterColor.SelectedIndex = Convert.ToInt32(sVal);
2385 - 2801
                sVal = ini.IniReadValue("waypoints", "copterheadingcolor");
2802
                if(sVal != "") comboBoxCopterHeadingColor.SelectedIndex = Convert.ToInt32(sVal);
2379 - 2803
                sVal = ini.IniReadValue("waypoints", "landingcolor");
2804
                if(sVal != "") comboBoxLandingColor.SelectedIndex = Convert.ToInt32(sVal);
2328 - 2805
                sVal = ini.IniReadValue("waypoints", "routecolor");
2806
                if(sVal != "") comboBoxRouteColor.SelectedIndex = Convert.ToInt32(sVal);
2807
                sVal = ini.IniReadValue("waypoints", "showWPRoute");
2808
                if(sVal != "") _bShowWPRoute = Convert.ToBoolean(sVal);
2349 - 2809
 
2810
                for (int i = 0; i < 12; i++)
2811
                {
2812
                    sVal = ini.IniReadValue("serial", "ch" + i.ToString() + "Val");
2813
                    if (sVal != "")
2814
                        serChan[i] = Convert.ToInt16(sVal);
2815
                    sVal = ini.IniReadValue("serial", "ch" + i.ToString() + "Title");
2816
                    if (sVal != "")
2817
                        serChanTitle[i] = sVal;
2818
                    for (int y = 0; i < 4 && y < 3; y++)
2819
                    {
2820
                        sVal = ini.IniReadValue("serial", "ch" + i.ToString() + "ValSub" + y.ToString());
2821
                        if (sVal != "")
2822
                            serChan_sub[(i * 3) + y] = Convert.ToInt16(sVal);
2823
                    }
2824
                }
2825
 
2312 - 2826
            }
2827
            catch (Exception e)
2828
            {
2287 - 2829
 
2312 - 2830
                MessageBox.Show("Error parsing ini-file!" + Environment.NewLine + e.Message,"Read ini-file" ,MessageBoxButton.OK,MessageBoxImage.Error);
2831
            }
2832
 
2287 - 2833
        }
2834
 
2835
        /// <summary>
2836
        /// save settings to ini-file
2837
        /// </summary>
2838
        void _writeIni()
2839
        {
2840
 
2841
            IniFile ini = new IniFile("MKLiveViewSettings.ini");
2842
            ini.path = filePath + "\\MKLiveViewSettings.ini";
2843
 
2312 - 2844
            try
2845
            {
2287 - 2846
 
2312 - 2847
                ini.IniWriteValue("timings", "AutorefreshDebugData", _debugDataAutorefresh ? "true" : "false");
2848
                ini.IniWriteValue("timings", "AutorefreshNavCtrlData", _navCtrlDataAutorefresh ? "true" : "false");
2849
                ini.IniWriteValue("timings", "AutorefreshBLCtrlData", _blctrlDataAutorefresh ? "true" : "false");
2850
                ini.IniWriteValue("timings", "AutorefreshOSDData", _OSDAutorefresh ? "true" : "false");
2287 - 2851
 
2312 - 2852
                ini.IniWriteValue("timings", "IntervalDebugData", debugInterval.ToString());
2853
                ini.IniWriteValue("timings", "IntervalNavCtrlData", navctrlInterval.ToString());
2854
                ini.IniWriteValue("timings", "IntervalBLCtrlData", blctrlInterval.ToString());
2855
                ini.IniWriteValue("timings", "IntervalOSDData", OSDInterval.ToString());
2287 - 2856
 
2312 - 2857
                ini.IniWriteValue("general", "LiPoCells", _LipoCells.ToString());
2858
                ini.IniWriteValue("general", "Motors", _iMotors.ToString());
2287 - 2859
 
2312 - 2860
                ini.IniWriteValue("map", "followMe", _bFollowCopter.ToString());
2861
                ini.IniWriteValue("map", "AutoSetHome", _bAutoHome.ToString());
2324 - 2862
                ini.IniWriteValue("map", "GPXLog", _bGPXLog.ToString());
2287 - 2863
 
2312 - 2864
                ini.IniWriteValue("topBar", "voltage", chkBoxTopBarShowVoltage.IsChecked.ToString());
2865
                ini.IniWriteValue("topBar", "capacity", chkBoxTopBarShowCapacity.IsChecked.ToString());
2866
                ini.IniWriteValue("topBar", "current", chkBoxTopBarShowCurrent.IsChecked.ToString());
2867
                ini.IniWriteValue("topBar", "flightTime", chkBoxTopBarShowFlightTime.IsChecked.ToString());
2868
                ini.IniWriteValue("topBar", "distanceHP", chkBoxTopBarShowDistanceHP.IsChecked.ToString());
2869
                ini.IniWriteValue("topBar", "height", chkBoxTopBarShowHeight.IsChecked.ToString());
2870
                ini.IniWriteValue("topBar", "speed", chkBoxTopBarShowSpeed.IsChecked.ToString());
2871
                ini.IniWriteValue("topBar", "magneticField", chkBoxTopBarShowMF.IsChecked.ToString());
2872
                ini.IniWriteValue("topBar", "satellites", chkBoxTopBarShowSatellites.IsChecked.ToString());
2873
                ini.IniWriteValue("topBar", "rc", chkBoxTopBarShowRC.IsChecked.ToString());
2287 - 2874
 
2312 - 2875
                ini.IniWriteValue("style", "saveFullScreen", chkBoxSaveFullScreenState.IsChecked.ToString());
2876
                ini.IniWriteValue("style", "saveNormalState", chkBoxSaveNormalState.IsChecked.ToString());
2287 - 2877
 
2312 - 2878
                ini.IniWriteValue("style", "scaleNormalAll", scaleNormalAll.ToString());
2879
                ini.IniWriteValue("style", "scaleNormalTopBar", scaleNormalTopBar.ToString());
2880
                ini.IniWriteValue("style", "scaleNormalMotors", scaleNormalMotors.ToString());
2881
                ini.IniWriteValue("style", "scaleNormalOSD", scaleNormalOSD.ToString());
2882
                ini.IniWriteValue("style", "scaleNormalLOG", scaleNormalLOG.ToString());
2883
                ini.IniWriteValue("style", "scaleNormalHorizon", scaleNormalHorizon.ToString());
2287 - 2884
 
2312 - 2885
                ini.IniWriteValue("style", "scaleFullAll", scaleFullAll.ToString());
2886
                ini.IniWriteValue("style", "scaleFullTopBar", scaleFullTopBar.ToString());
2887
                ini.IniWriteValue("style", "scaleFullMotors", scaleFullMotors.ToString());
2888
                ini.IniWriteValue("style", "scaleFullOSD", scaleFullOSD.ToString());
2889
                ini.IniWriteValue("style", "scaleFullLOG", scaleFullLOG.ToString());
2890
                ini.IniWriteValue("style", "scaleFullHorizon", scaleFullHorizon.ToString());
2287 - 2891
 
2312 - 2892
                ini.IniWriteValue("style", "horizon", chkBoxShowHorizon.IsChecked.ToString());
2893
 
2894
                ini.IniWriteValue("threshold", "VoltageWarning", _dThresholdVoltageWarn.ToString());
2895
                ini.IniWriteValue("threshold", "VoltageCritical", _dThresholdVoltageCrit.ToString());
2896
                ini.IniWriteValue("threshold", "VoiceVoltageEnable", _bVoiceVoltPlay.ToString());
2897
                ini.IniWriteValue("threshold", "VoiceSatFixEnable", _bVoiceSatFixPlay.ToString());
2898
                ini.IniWriteValue("threshold", "VoiceMagFieldEnable", _bVoiceMagneticFieldPlay.ToString());
2899
                ini.IniWriteValue("threshold", "VoiceDistanceWarnEnable", _bVoiceDistancePlay.ToString());
2900
                ini.IniWriteValue("threshold", "VoiceRCLevelWarnEnable", _bVoiceRCLevelPlay.ToString());
2901
                ini.IniWriteValue("threshold", "DistanceWarning", _dThresholdDistanceWarn.ToString());
2902
                ini.IniWriteValue("threshold", "MaxDistance", _dThresholdDistanceMax.ToString());
2903
                ini.IniWriteValue("threshold", "RCThreshold", _iThresholdRC.ToString());
2904
                ini.IniWriteValue("threshold", "MagFieldThreshold", _iThresholdMagField.ToString());
2321 - 2905
 
2906
                ini.IniWriteValue("waypoints", "wpcolor", comboBoxWPColor.SelectedIndex.ToString());
2907
                ini.IniWriteValue("waypoints", "poicolor", comboBoxPOIColor.SelectedIndex.ToString());
2908
                ini.IniWriteValue("waypoints", "fscolor", comboBoxFSColor.SelectedIndex.ToString());
2909
                ini.IniWriteValue("waypoints", "coptercolor", comboBoxCopterColor.SelectedIndex.ToString());
2385 - 2910
                ini.IniWriteValue("waypoints", "copterheadingcolor", comboBoxCopterHeadingColor.SelectedIndex.ToString());
2379 - 2911
                ini.IniWriteValue("waypoints", "landingcolor", comboBoxLandingColor.SelectedIndex.ToString());
2328 - 2912
                ini.IniWriteValue("waypoints", "routecolor", comboBoxRouteColor.SelectedIndex.ToString());
2913
                ini.IniWriteValue("waypoints", "showWPRoute", _bShowWPRoute.ToString());
2349 - 2914
 
2915
                for (int i = 0; i < 12; i++)
2916
                {
2917
                    ini.IniWriteValue("serial", "ch" + i.ToString() + "Val", serChan[i].ToString());
2918
                    ini.IniWriteValue("serial", "ch" + i.ToString() + "Title", serChanTitle[i]);
2919
                    for (int y = 0; i < 4 && y < 3; y++)
2920
                    {
2921
                        ini.IniWriteValue("serial", "ch" + i.ToString() + "ValSub" + y.ToString(), serChan_sub[(i * 3) + y].ToString());
2922
                    }
2923
                }
2924
 
2312 - 2925
            }
2926
            catch (Exception e)
2927
            {
2928
 
2929
                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);
2930
            }
2287 - 2931
        }
2350 - 2932
 
2349 - 2933
        #region serial channels
2934
        /// <summary>
2935
        /// Sending the serial channel values
2936
        /// </summary>
2937
        void _sendSerialData()
2938
        {
2939
            byte[] serData = new byte[12];
2940
            for (int i = 0; i < 12; i++)
2941
            {
2942
                serData[i] = unchecked((byte)(serChan[i] - 127));
2943
            }
2944
            _sendControllerMessage('y', 1, serData);
2945
        }
2946
        /// <summary>
2947
        /// init the controls for displaying
2948
        /// and setting serial control channels
2949
        /// </summary>
2950
        void _initSerialCtrl()
2951
        {
2952
            SerChan1ScaleSlider.Value = serChan[0];
2953
            textBoxSerial1.Text = serChanTitle[0];
2954
            SerChan2ScaleSlider.Value = serChan[1];
2955
            textBoxSerial2.Text = serChanTitle[1];
2350 - 2956
            SerChan3ScaleSlider.Value = serChan[2];
2957
            textBoxSerial3.Text = serChanTitle[2];
2349 - 2958
            //SerChan4ScaleSlider.Value = serChan[3];
2959
            //textBoxSerial4.Text = serChanTitle[3];
2960
            //trckbarSerial5.Value = serChan[4];
2961
            //textBoxSerial5.Text = serChanTitle[4];
2962
            //trckbarSerial6.Value = serChan[5];
2963
            //textBoxSerial6.Text = serChanTitle[5];
2964
            //trckbarSerial7.Value = serChan[6];
2965
            //textBoxSerial7.Text = serChanTitle[6];
2966
            //trckbarSerial8.Value = serChan[7];
2967
            //textBoxSerial8.Text = serChanTitle[7];
2312 - 2968
 
2349 - 2969
            textBoxSerial1_val1.Text = serChan_sub[0].ToString();
2970
            textBoxSerial1_val2.Text = serChan_sub[1].ToString();
2971
            textBoxSerial1_val3.Text = serChan_sub[2].ToString();
2972
            textBoxSerial2_val1.Text = serChan_sub[3].ToString();
2973
            textBoxSerial2_val2.Text = serChan_sub[4].ToString();
2974
            textBoxSerial2_val3.Text = serChan_sub[5].ToString();
2350 - 2975
            textBoxSerial3_val1.Text = serChan_sub[6].ToString();
2976
            textBoxSerial3_val2.Text = serChan_sub[7].ToString();
2977
            textBoxSerial3_val3.Text = serChan_sub[8].ToString();
2349 - 2978
            //textBoxSerial4_val1.Text = serChan_sub[9].ToString();
2979
            //textBoxSerial4_val2.Text = serChan_sub[10].ToString();
2980
            //textBoxSerial4_val3.Text = serChan_sub[11].ToString();
2981
        }
2982
        private void SerChan1ScaleSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
2983
        {
2984
            if (!_init)
2985
            {
2986
                serChan[0] = (int)SerChan1ScaleSlider.Value;
2987
                _sendSerialData();
2988
            }
2989
        }
2990
        private void textBoxSerial1_TextChanged(object sender, TextChangedEventArgs e)
2991
        {
2992
            if (!_init)
2993
            {
2994
                serChanTitle[0] = textBoxSerial1.Text;
2995
            }
2996
        }
2997
        private void textBoxSerial1_val1_TextChanged(object sender, TextChangedEventArgs e)
2998
        {
2999
            if (textBoxSerial1_val1.Text.Length > 0 & !_init)
3000
            {
3001
                serChan_sub[0] = Convert.ToInt16(textBoxSerial1_val1.Text);
3002
            }
3003
        }
3004
        private void textBoxSerial1_val2_TextChanged(object sender, TextChangedEventArgs e)
3005
        {
3006
            if (textBoxSerial1_val2.Text.Length > 0 & !_init)
3007
            {
3008
                serChan_sub[1] = Convert.ToInt16(textBoxSerial1_val2.Text);
3009
            }
3010
        }
3011
        private void textBoxSerial1_val3_TextChanged(object sender, TextChangedEventArgs e)
3012
        {
3013
            if (textBoxSerial1_val3.Text.Length > 0 & !_init)
3014
            {
3015
                serChan_sub[2] = Convert.ToInt16(textBoxSerial1_val3.Text);
3016
            }
3017
        }
3018
        private void btnSer1_val1_Click(object sender, RoutedEventArgs e)
3019
        {
3020
            if (textBoxSerial1_val1.Text.Length > 0)
3021
            {
3022
                SerChan1ScaleSlider.Value = Convert.ToInt16(textBoxSerial1_val1.Text);
3023
            }
3024
        }
3025
        private void btnSer1_0_Click(object sender, RoutedEventArgs e)
3026
        {
3027
            SerChan1ScaleSlider.Value = 0;
3028
        }
3029
        private void btnSer1_127_Click(object sender, RoutedEventArgs e)
3030
        {
3031
            SerChan1ScaleSlider.Value = 127;
3032
        }
3033
        private void btnSer1_254_Click(object sender, RoutedEventArgs e)
3034
        {
3035
            SerChan1ScaleSlider.Value = 254;
3036
        }
3037
        private void btnSer1_val2_Click(object sender, RoutedEventArgs e)
3038
        {
3039
            if (textBoxSerial1_val2.Text.Length > 0)
3040
            {
3041
                SerChan1ScaleSlider.Value = Convert.ToInt16(textBoxSerial1_val2.Text);
3042
            }
3043
        }
3044
        private void btnSer1_val3_Click(object sender, RoutedEventArgs e)
3045
        {
3046
            if (textBoxSerial1_val3.Text.Length > 0)
3047
            {
3048
                SerChan1ScaleSlider.Value = Convert.ToInt16(textBoxSerial1_val3.Text);
3049
            }
3050
        }
3051
 
3052
        private void SerChan2ScaleSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
3053
        {
3054
            if (!_init)
3055
            {
3056
                serChan[1] = (int)SerChan2ScaleSlider.Value;
3057
                _sendSerialData();
3058
            }
3059
        }
3060
        private void textBoxSerial2_TextChanged(object sender, TextChangedEventArgs e)
3061
        {
3062
            if (!_init)
3063
            {
3064
                serChanTitle[1] = textBoxSerial2.Text;
3065
            }
3066
        }
3067
        private void textBoxSerial2_val1_TextChanged(object sender, TextChangedEventArgs e)
3068
        {
3069
            if (textBoxSerial2_val1.Text.Length > 0 & !_init)
3070
            {
3071
                serChan_sub[3] = Convert.ToInt16(textBoxSerial2_val1.Text);
3072
            }
3073
        }
3074
        private void textBoxSerial2_val2_TextChanged(object sender, TextChangedEventArgs e)
3075
        {
3076
            if (textBoxSerial2_val2.Text.Length > 0 & !_init)
3077
            {
3078
                serChan_sub[4] = Convert.ToInt16(textBoxSerial2_val2.Text);
3079
            }
3080
        }
3081
        private void textBoxSerial2_val3_TextChanged(object sender, TextChangedEventArgs e)
3082
        {
3083
            if (textBoxSerial2_val3.Text.Length > 0 & !_init)
3084
            {
3085
                serChan_sub[5] = Convert.ToInt16(textBoxSerial2_val3.Text);
3086
            }
3087
        }
3088
        private void btnSer2_0_Click(object sender, RoutedEventArgs e)
3089
        {
3090
            SerChan2ScaleSlider.Value = 0;
3091
        }
3092
        private void btnSer2_127_Click(object sender, RoutedEventArgs e)
3093
        {
3094
            SerChan2ScaleSlider.Value = 127;
3095
        }
3096
        private void btnSer2_254_Click(object sender, RoutedEventArgs e)
3097
        {
3098
            SerChan2ScaleSlider.Value = 254;
3099
        }
3100
        private void btnSer2_val1_Click(object sender, RoutedEventArgs e)
3101
        {
3102
            if (textBoxSerial2_val1.Text.Length > 0)
3103
            {
3104
                SerChan2ScaleSlider.Value = Convert.ToInt16(textBoxSerial2_val1.Text);
3105
            }
3106
        }
3107
        private void btnSer2_val2_Click(object sender, RoutedEventArgs e)
3108
        {
3109
            if (textBoxSerial2_val2.Text.Length > 0)
3110
            {
3111
                SerChan2ScaleSlider.Value = Convert.ToInt16(textBoxSerial2_val2.Text);
3112
            }
3113
        }
3114
        private void btnSer2_val3_Click(object sender, RoutedEventArgs e)
3115
        {
3116
            if (textBoxSerial2_val3.Text.Length > 0)
3117
            {
3118
                SerChan2ScaleSlider.Value = Convert.ToInt16(textBoxSerial2_val3.Text);
3119
            }
3120
        }
2350 - 3121
 
3122
        private void SerChan3ScaleSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
3123
        {
3124
            if (!_init)
3125
            {
3126
                serChan[2] = (int)SerChan3ScaleSlider.Value;
3127
                _sendSerialData();
3128
            }
3129
        }
3130
        private void textBoxSerial3_TextChanged(object sender, TextChangedEventArgs e)
3131
        {
3132
            if (!_init)
3133
            {
3134
                serChanTitle[2] = textBoxSerial3.Text;
3135
            }
3136
        }
3137
        private void textBoxSerial3_val1_TextChanged(object sender, TextChangedEventArgs e)
3138
        {
3139
            if (textBoxSerial3_val1.Text.Length > 0 & !_init)
3140
            {
3141
                serChan_sub[6] = Convert.ToInt16(textBoxSerial3_val1.Text);
3142
            }
3143
        }
3144
        private void textBoxSerial3_val2_TextChanged(object sender, TextChangedEventArgs e)
3145
        {
3146
            if (textBoxSerial3_val2.Text.Length > 0 & !_init)
3147
            {
3148
                serChan_sub[7] = Convert.ToInt16(textBoxSerial3_val2.Text);
3149
            }
3150
        }
3151
        private void textBoxSerial3_val3_TextChanged(object sender, TextChangedEventArgs e)
3152
        {
3153
            if (textBoxSerial3_val3.Text.Length > 0 & !_init)
3154
            {
3155
                serChan_sub[8] = Convert.ToInt16(textBoxSerial3_val3.Text);
3156
            }
3157
        }
3158
        private void btnSer3_0_Click(object sender, RoutedEventArgs e)
3159
        {
3160
            SerChan3ScaleSlider.Value = 0;
3161
        }
3162
        private void btnSer3_127_Click(object sender, RoutedEventArgs e)
3163
        {
3164
            SerChan3ScaleSlider.Value = 127;
3165
        }
3166
        private void btnSer3_254_Click(object sender, RoutedEventArgs e)
3167
        {
3168
            SerChan3ScaleSlider.Value = 254;
3169
        }
3170
        private void btnSer3_val1_Click(object sender, RoutedEventArgs e)
3171
        {
3172
            if (textBoxSerial3_val1.Text.Length > 0)
3173
            {
3174
                SerChan3ScaleSlider.Value = Convert.ToInt16(textBoxSerial3_val1.Text);
3175
            }
3176
        }
3177
        private void btnSer3_val2_Click(object sender, RoutedEventArgs e)
3178
        {
3179
            if (textBoxSerial3_val2.Text.Length > 0)
3180
            {
3181
                SerChan3ScaleSlider.Value = Convert.ToInt16(textBoxSerial3_val2.Text);
3182
            }
3183
        }
3184
        private void btnSer3_val3_Click(object sender, RoutedEventArgs e)
3185
        {
3186
            if (textBoxSerial3_val3.Text.Length > 0)
3187
            {
3188
                SerChan3ScaleSlider.Value = Convert.ToInt16(textBoxSerial3_val3.Text);
3189
            }
3190
        }
2349 - 3191
        /// <summary>
3192
        /// checks the input of a textbox
3193
        /// for valid data
3194
        /// in this case values 0-254
3195
        /// </summary>
3196
        /// <param name="sender"></param>
3197
        /// <param name="e"></param>
3198
        private void textBox_serial_KeyPress(object sender, KeyEventArgs e)
3199
        {
3200
            if ("1234567890,\b".IndexOf(e.Key.ToString()) < 0) //general check for valid chars(0-9) and backspace (\b)
3201
                e.Handled = true;
3202
            else
3203
            if ("\b".IndexOf(e.Key.ToString()) < 0)
3204
                if (Convert.ToInt16(((TextBox)sender).Text + e.Key) > 254) //if valid and not backspace, check for upper limit of the resulting number
3205
                    e.Handled = true;
3206
                else
3207
                {
3208
                    int i = -1;
3209
                    switch (((TextBox)sender).Name)
3210
                    {
3211
                        case "textBoxSerial1_val1":
3212
                            i = 0;
3213
                            break;
3214
                        case "textBoxSerial1_val2":
3215
                            i = 1;
3216
                            break;
3217
                        case "textBoxSerial1_val3":
3218
                            i = 2;
3219
                            break;
3220
                        case "textBoxSerial2_val1":
3221
                            i = 3;
3222
                            break;
3223
                        case "textBoxSerial2_val2":
3224
                            i = 4;
3225
                            break;
3226
                        case "textBoxSerial2_val3":
3227
                            i = 5;
3228
                            break;
3229
                        case "textBoxSerial3_val1":
3230
                            i = 6;
3231
                            break;
3232
                        case "textBoxSerial3_val2":
3233
                            i = 7;
3234
                            break;
3235
                        case "textBoxSerial3_val3":
3236
                            i = 8;
3237
                            break;
3238
                        case "textBoxSerial4_val1":
3239
                            i = 9;
3240
                            break;
3241
                        case "textBoxSerial4_val2":
3242
                            i = 10;
3243
                            break;
3244
                        case "textBoxSerial4_val3":
3245
                            i = 11;
3246
                            break;
3247
                    }
3248
                    if (i > -1)
3249
                        serChan_sub[i] = Convert.ToInt16(((TextBox)sender).Text + e.Key.ToString());
3250
                }
3251
        }
3252
 
3253
        #endregion serial channels
2315 - 3254
        #region WP
2312 - 3255
        void _readWPLFile()
3256
        {
3257
            Microsoft.Win32.OpenFileDialog fd = new Microsoft.Win32.OpenFileDialog();
3258
            fd.Filter = "Waypointlists | *.wpl";
3259
            fd.Multiselect = false;
3260
            if (fd.ShowDialog().Value)
3261
            {
3262
                string file = fd.SafeFileName;
3263
                IniFile ini = new IniFile(fd.SafeFileName);
3264
                ini.path = fd.FileName;
3265
 
3266
                try
3267
                {
3268
                    string sVal = ini.IniReadValue("General", "FileVersion");
3269
                    if (sVal == "")
3270
                        MessageBox.Show("The file has no version declared - can't go on...", "", MessageBoxButton.OK, MessageBoxImage.Information);
3271
                    else
3272
                    {
3273
                        if (Convert.ToInt16(sVal) < 3)
3274
                            MessageBox.Show("The file version is not supported - can't go on...", "", MessageBoxButton.OK, MessageBoxImage.Information);
3275
                        else
3276
                        {
3277
                            sVal = ini.IniReadValue("General", "NumberOfWaypoints");
3278
                            if (sVal == "")
3279
                                MessageBox.Show("The file has no number of waypoints declared - can't go on...", "", MessageBoxButton.OK, MessageBoxImage.Information);
3280
                            else
3281
                            {
3282
                                int wpnum = Convert.ToInt16(sVal);
3283
                                string wp;
3284
                                int i;
2313 - 3285
                                NumberFormatInfo nfi = new NumberFormatInfo();
3286
                                nfi.NumberDecimalSeparator = ".";
2312 - 3287
                                dtWaypoints.Rows.Clear();
2368 - 3288
                                _wpEdit = -1;_wpIndex = -1;
2327 - 3289
                                _clearMapMarkers(typeof(CustomMarkerWP));
2363 - 3290
                                _clearMapMarkers(typeof(CustomMarkerWPActive));
2328 - 3291
                                wpList.Clear();
3292
                                if (mRouteWP != null)
3293
                                    MainMap.Markers.Remove(mRouteWP);
2363 - 3294
                                //if (wpActiveMarker != null)
3295
                                //    MainMap.Markers.Remove(wpActiveMarker);
2328 - 3296
                                Dispatcher.Invoke(() => lblWPRouteDistance.Content = "0 m");
3297
 
2312 - 3298
                                for (int k = 1; k <= wpnum; k++)
3299
                                {
3300
                                    DataRow dr = dtWaypoints.NewRow();
3301
                                    dr.ItemArray = new object[16];
3302
                                    object[] o = new object[16];
3303
                                    i = 0;
3304
                                    wp = "Point" + k.ToString();
3305
                                    o[i] = k;
3306
                                    i++;
3307
                                    sVal = ini.IniReadValue(wp, "Type");
3308
                                    if (sVal != "")
2315 - 3309
                                        o[i] = Convert.ToInt16(sVal) - 1;
2312 - 3310
                                    i++;
3311
                                    sVal = ini.IniReadValue(wp, "Prefix");
3312
                                    if (sVal != "")
2350 - 3313
                                        o[i] = sVal + k.ToString();
3314
                                   //     o[i] = sVal == "0" ? "!" + k.ToString() : sVal + k.ToString();
2312 - 3315
                                    i++;
2313 - 3316
                                    sVal = ini.IniReadValue(wp, "Latitude");
2312 - 3317
                                    if (sVal != "")
2313 - 3318
                                        o[i] = Convert.ToDouble(sVal, nfi);
2312 - 3319
                                    i++;
2313 - 3320
                                    sVal = ini.IniReadValue(wp, "Longitude");
2312 - 3321
                                    if (sVal != "")
2313 - 3322
                                        o[i] = Convert.ToDouble(sVal, nfi);
2312 - 3323
                                    i++;
3324
                                    sVal = ini.IniReadValue(wp, "Altitude");
3325
                                    if (sVal != "")
2313 - 3326
                                        o[i] = Convert.ToDouble(sVal, nfi);
2312 - 3327
                                    i++;
3328
                                    sVal = ini.IniReadValue(wp, "Heading");
3329
                                    if (sVal != "")
3330
                                        o[i] = Convert.ToInt16(sVal);
3331
                                    i++;
3332
                                    sVal = ini.IniReadValue(wp, "Speed");
3333
                                    if (sVal != "")
2315 - 3334
                                        o[i] = Convert.ToInt16(sVal);
2312 - 3335
                                    i++;
3336
                                    sVal = ini.IniReadValue(wp, "ClimbRate");
3337
                                    if (sVal != "")
3338
                                        o[i] = Convert.ToInt16(sVal);
3339
                                    i++;
3340
                                    sVal = ini.IniReadValue(wp, "Radius");
3341
                                    if (sVal != "")
3342
                                        o[i] = Convert.ToInt16(sVal);
3343
                                    i++;
3344
                                    sVal = ini.IniReadValue(wp, "DelayTime");
3345
                                    if (sVal != "")
3346
                                        o[i] = Convert.ToInt16(sVal);
3347
                                    i++;
3348
                                    sVal = ini.IniReadValue(wp, "AutoTrigger");
3349
                                    if (sVal != "")
3350
                                        o[i] = Convert.ToInt16(sVal); ;
3351
                                    i++;
3352
                                    sVal = ini.IniReadValue(wp, "CAM-Nick");
3353
                                    if (sVal != "")
2313 - 3354
                                        o[i] = Convert.ToInt16(sVal);
2312 - 3355
                                    i++;
3356
                                    o[i] = 0;
3357
                                    i++;
3358
                                    sVal = ini.IniReadValue(wp, "WP_Event_Channel_Value");
3359
                                    if (sVal != "")
3360
                                        o[i] = Convert.ToInt16(sVal);
3361
                                    i++;
3362
                                    o[i] = "New";
3363
 
3364
                                    dr.ItemArray = o;
3365
                                    dtWaypoints.Rows.Add(dr);
2363 - 3366
                                    _createWP(new PointLatLng((double)o[3], (double)o[4]), (string)dr[2], (int)o[1]);
2315 - 3367
 
2312 - 3368
                                    Dispatcher.Invoke(() => lblWPIndex.Content = k.ToString());
3369
                                    Dispatcher.Invoke(() => lblWPCount.Content = k.ToString());
3370
                                    Dispatcher.Invoke(() => dgvWP.Items.Refresh());
3371
                                    Thread.Sleep(10);
3372
                                }
2359 - 3373
                                _routeUpdate();
2312 - 3374
                            }
3375
                        }
3376
                    }
3377
 
3378
                }
3379
                catch (Exception e)
3380
                {
3381
 
3382
                    MessageBox.Show("Error parsing wpl-file!" + Environment.NewLine + e.Message, "Read wpl-file", MessageBoxButton.OK, MessageBoxImage.Error);
3383
                }
3384
 
3385
            }
3386
        }
2350 - 3387
        void _saveWPLFile()
3388
        {
3389
            if (dtWaypoints.Rows.Count > 0)
3390
            {
3391
                Microsoft.Win32.SaveFileDialog fd = new Microsoft.Win32.SaveFileDialog();
3392
                fd.Filter = "Waypointlists | *.wpl";
3393
                fd.AddExtension = true;
3394
                if (fd.ShowDialog().Value)
3395
                {
3396
                    string file = fd.SafeFileName;
3397
                    IniFile ini = new IniFile(fd.SafeFileName);
3398
                    ini.path = fd.FileName;
3399
                    NumberFormatInfo nfi = new NumberFormatInfo();
3400
                    nfi.NumberDecimalSeparator = ".";
3401
 
3402
                    try
3403
                    {
3404
                        ini.IniWriteValue("General", "FileVersion", "3");
3405
                        ini.IniWriteValue("General", "NumberOfWaypoints", dtWaypoints.Rows.Count.ToString());
3406
                        ini.IniWriteValue("General", "Mapfile", "");
3407
                        for(int i = 1; i<=dtWaypoints.Rows.Count; i++)
3408
                        {
3409
                            ini.IniWriteValue("Point" + i.ToString(), "Latitude", ((double)(dtWaypoints.Rows[i-1][3])).ToString(nfi));
3410
                            ini.IniWriteValue("Point" + i.ToString(), "Longitude", ((double)(dtWaypoints.Rows[i - 1][4])).ToString(nfi));
3411
                            ini.IniWriteValue("Point" + i.ToString(), "Radius", dtWaypoints.Rows[i - 1][9].ToString());
3412
                            ini.IniWriteValue("Point" + i.ToString(), "Altitude", dtWaypoints.Rows[i - 1][5].ToString());
3413
                            ini.IniWriteValue("Point" + i.ToString(), "ClimbRate", dtWaypoints.Rows[i - 1][8].ToString());
3414
                            ini.IniWriteValue("Point" + i.ToString(), "DelayTime", dtWaypoints.Rows[i - 1][10].ToString());
3415
                            ini.IniWriteValue("Point" + i.ToString(), "WP_Event_Channel_Value", dtWaypoints.Rows[i - 1][14].ToString());
3416
                            ini.IniWriteValue("Point" + i.ToString(), "Heading", dtWaypoints.Rows[i - 1][6].ToString());
3417
                            ini.IniWriteValue("Point" + i.ToString(), "Speed", dtWaypoints.Rows[i - 1][7].ToString());
3418
                            ini.IniWriteValue("Point" + i.ToString(), "CAM-Nick", dtWaypoints.Rows[i - 1][12].ToString());
3419
                            ini.IniWriteValue("Point" + i.ToString(), "Type", ((int)dtWaypoints.Rows[i - 1][1]+1).ToString());
3420
                            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));
3421
                            ini.IniWriteValue("Point" + i.ToString(), "AutoTrigger", dtWaypoints.Rows[i - 1][11].ToString());
3422
                        }
3423
                        MessageBox.Show(dtWaypoints.Rows.Count.ToString() + " points saved to " + file, "Waypointlist saved", MessageBoxButton.OK, MessageBoxImage.Information);
3424
                    }
3425
                    catch { }
3426
                }
3427
            }
3428
            else
3429
                MessageBox.Show("Nothing to save...");
3430
        }
3431
        private void btnSaveWPLFile_Click(object sender, RoutedEventArgs e)
3432
        {
3433
            _saveWPLFile();
3434
        }
3435
        /// <summary>
3436
        /// set the selected color for the route
3437
        /// </summary>
3438
        /// <param name="color"></param>
3439
        /// <returns></returns>
2328 - 3440
        Brush _getBrush(string color)
3441
        {
3442
            switch (color)
3443
            {
3444
                case "red":
3445
                    return Brushes.Red;
3446
                case "green":
3447
                    return Brushes.Lime;
3448
                case "blue":
3449
                    return Brushes.Aqua;
3450
                case "pink":
3451
                    return Brushes.Magenta;
3452
                case "yellow":
3453
                    return Brushes.Yellow;
3454
                default:
3455
                    return Brushes.Magenta;
3456
            }
3457
        }
2359 - 3458
        void _routeUpdate()
3459
        {
3460
            Dispatcher.Invoke(() =>
3461
            {
3462
                if (comboBoxRouteColor.SelectionBoxItem != null)
3463
                {
3464
                    string s = comboBoxRouteColor.SelectionBoxItem.ToString();
3465
                    mRouteWP = new GMapRoute(wpList, _getBrush(s));
3466
                }
3467
                else
3468
                    mRouteWP = new GMapRoute(wpList, null);
3469
 
3470
                if (_bShowWPRoute)
2368 - 3471
                    MainMap.Markers.Add(mRouteWP);
2359 - 3472
            });
3473
 
3474
            MapRoute mr = new MapRoute(wpList, "WPList");
3475
            Dispatcher.Invoke(() => lblWPRouteDistance.Content = (mr.Distance * 1000).ToString("0 m"));
3476
        }
2363 - 3477
        GMapMarker _createWP(PointLatLng p, string name, int type)
3478
        {
3479
            GMapMarker wpMarker = new GMapMarker(p);
2385 - 3480
            Dispatcher.Invoke(()=>
3481
            {
3482
                wpMarker.Shape = new CustomMarkerWP(this, wpMarker, name, type);
3483
                wpMarker.Offset = new System.Windows.Point(-11.5, -11.5);
3484
                wpMarker.ZIndex = 100;
3485
                _setMarkerColor(wpMarker, type);
3486
                MainMap.Markers.Add(wpMarker);
3487
                if (type == 0 || type == 3)
3488
                    wpList.Add(p);
3489
            });
2363 - 3490
            return wpMarker;
3491
        }
2315 - 3492
        void _setMarkerColor(GMapMarker wpMarker,int iType)
3493
        {
2369 - 3494
            if(wpMarker != null)
2315 - 3495
            Dispatcher.Invoke(() =>
3496
            {
3497
                switch (iType)
3498
                {
3499
                    case 0:
3500
                        if (comboBoxWPColor.SelectionBoxItem != null)
3501
                        {
3502
                            string s = comboBoxWPColor.SelectionBoxItem.ToString();
3503
                            ((CustomMarkerWP)(wpMarker.Shape)).setColor(s);
3504
                        }
3505
                        else
2372 - 3506
                            ((CustomMarkerWP)(wpMarker.Shape)).setColor("green");
2315 - 3507
                        break;
3508
                    case 1:
3509
                        if (comboBoxPOIColor.SelectionBoxItem != null)
3510
                        {
3511
                            string s = comboBoxPOIColor.SelectionBoxItem.ToString();
3512
                            ((CustomMarkerWP)(wpMarker.Shape)).setColor(s);
3513
                        }
3514
                        else
2372 - 3515
                            ((CustomMarkerWP)(wpMarker.Shape)).setColor("pink");
2315 - 3516
                        break;
3517
                    case 2:
3518
                        if (comboBoxFSColor.SelectionBoxItem != null)
3519
                        {
3520
                            string s = comboBoxFSColor.SelectionBoxItem.ToString();
3521
                            ((CustomMarkerWP)(wpMarker.Shape)).setColor(s);
3522
                        }
3523
                        else
3524
                            ((CustomMarkerWP)(wpMarker.Shape)).setColor("red");
3525
                        break;
2372 - 3526
                    case 3:
3527
                        if (comboBoxLandingColor.SelectionBoxItem != null)
3528
                        {
3529
                            string s = comboBoxLandingColor.SelectionBoxItem.ToString();
3530
                            ((CustomMarkerWP)(wpMarker.Shape)).setColor(s);
3531
                        }
3532
                        else
3533
                            ((CustomMarkerWP)(wpMarker.Shape)).setColor("blue");
3534
                        break;
2315 - 3535
                    default:
3536
                        ((CustomMarkerWP)(wpMarker.Shape)).setColor("red");
3537
                        break;
3538
                }
3539
            });
2312 - 3540
 
2315 - 3541
        }
2372 - 3542
        void _MarkerColorSelection(object sender,int type)
3543
        {
2315 - 3544
            Dispatcher.Invoke(() =>
3545
            {
2372 - 3546
                if (((ComboBox)sender).SelectionBoxItem != null)
2315 - 3547
                {
3548
                    for (int k = 0; k < MainMap.Markers.Count; k++)
3549
                    {
3550
                        GMapMarker p = MainMap.Markers[k];
2372 - 3551
                        if (p.Shape != null && p.Shape.GetType() == typeof(CustomMarkerWP))
2315 - 3552
                        {
2372 - 3553
                            if (((CustomMarkerWP)p.Shape).WPType == type)
2315 - 3554
                            {
2372 - 3555
                                string s = ((ComboBox)sender).SelectionBoxItem.ToString();
2315 - 3556
                                ((CustomMarkerWP)(p.Shape)).setColor(s);
3557
                            }
3558
                        }
3559
                    }
3560
                }
3561
            });
2287 - 3562
        }
2379 - 3563
        private void comboBoxWPColor_DropDownClosed(object sender, EventArgs e)
2318 - 3564
        {
2376 - 3565
            _MarkerColorSelection(sender, 0);
3566
        }
3567
        private void comboBoxPOIColor_DropDownClosed(object sender, EventArgs e)
3568
        {
3569
            _MarkerColorSelection(sender, 1);
3570
        }
3571
        private void comboBoxFSColor_DropDownClosed(object sender, EventArgs e)
3572
        {
3573
            _MarkerColorSelection(sender, 2);
3574
        }
3575
        private void comboBoxLandingColor_DropDownClosed(object sender, EventArgs e)
3576
        {
3577
            _MarkerColorSelection(sender,3);
3578
        }
2385 - 3579
        private void comboBoxCopterColor_DropDownClosed(object sender, EventArgs e)
2376 - 3580
        {
2318 - 3581
            Dispatcher.Invoke(() => {
3582
                if (comboBoxCopterColor.SelectionBoxItem != null)
3583
                {
3584
                    string s = comboBoxCopterColor.SelectionBoxItem.ToString();
2385 - 3585
                    ((CustomMarkerCopter)(copter.Shape)).setCopterColor(s);
2318 - 3586
                }
3587
                else
2385 - 3588
                    ((CustomMarkerCopter)(copter.Shape)).setCopterColor("red");
2318 - 3589
            });
3590
        }
2385 - 3591
        private void comboBoxCopterHeadingColor_DropDownClosed(object sender, EventArgs e)
3592
        {
3593
            Dispatcher.Invoke(() => {
3594
                if (comboBoxCopterHeadingColor.SelectionBoxItem != null)
3595
                {
3596
                    string s = comboBoxCopterHeadingColor.SelectionBoxItem.ToString();
3597
                    ((CustomMarkerCopter)(copter.Shape)).setHeadingColor(s);
3598
                }
3599
                else
3600
                    ((CustomMarkerCopter)(copter.Shape)).setHeadingColor("red");
3601
            });
3602
        }
2328 - 3603
        private void comboBoxRouteColor_DropDownClosed(object sender, EventArgs e)
3604
        {
3605
            Dispatcher.Invoke(() =>
3606
            {
3607
                if (comboBoxRouteColor.SelectionBoxItem != null)
3608
                {
3609
                    string s = comboBoxRouteColor.SelectionBoxItem.ToString();
3610
                    MainMap.Markers.Remove(mRouteWP);
3611
                    mRouteWP = new GMapRoute(wpList, _getBrush(s));
3612
                    if (_bShowWPRoute)
3613
                        MainMap.Markers.Add(mRouteWP);
3614
                }
3615
            });
3616
        }
3617
        private void checkBoxShowWPRoute_Click(object sender, RoutedEventArgs e)
3618
        {
3619
            _bShowWPRoute = (bool)checkBoxShowWPRoute.IsChecked;
3620
            if (_bShowWPRoute)
3621
            {
3622
                if (mRouteWP != null)
3623
                    MainMap.Markers.Add(mRouteWP);
3624
            }
3625
            else
3626
            {
3627
                if (mRouteWP != null)
3628
                    MainMap.Markers.Remove(mRouteWP);
3629
            }
3630
        }
2315 - 3631
        private void btnLoadWPLFile_Click(object sender, RoutedEventArgs e)
2287 - 3632
        {
2315 - 3633
            _readWPLFile();
2287 - 3634
        }
2335 - 3635
        private void btnClearWPList_Click(object sender, RoutedEventArgs e)
3636
        {
3637
            _clearMapMarkers(typeof(CustomMarkerWP));
2347 - 3638
            _clearMapMarkers(typeof(CustomMarkerWPActive));
2335 - 3639
            wpList.Clear();
3640
            if (mRouteWP != null)
3641
                MainMap.Markers.Remove(mRouteWP);
2347 - 3642
            //if (wpActiveMarker != null)
3643
            //    MainMap.Markers.Remove(wpActiveMarker);
2335 - 3644
            dtWaypoints.Rows.Clear();
2356 - 3645
            _wpEdit = -1;
2368 - 3646
            _wpIndex = -1;
2335 - 3647
            Dispatcher.Invoke(() => dgvWP.Items.Refresh());
3648
            Dispatcher.Invoke(() => lblWPIndex.Content = 0);
3649
            Dispatcher.Invoke(() => lblWPCount.Content = 0);
3650
            Dispatcher.Invoke(() => lblWPRouteDistance.Content = "0 m");
3651
        }
2340 - 3652
        private void btnClearCopterList_Click(object sender, RoutedEventArgs e)
3653
        {
3654
            Thread t = new Thread(new ThreadStart(clearCopterWPList));
3655
            t.Start();
3656
        }
2355 - 3657
        private void btnSendActiveWP_Click(object sender, RoutedEventArgs e)
2340 - 3658
        {
3659
            if (dgvWP.SelectedIndex > -1 && dgvWP.SelectedIndex < dtWaypoints.Rows.Count)
3660
            {
2372 - 3661
                if (_wpCount > 0)
2376 - 3662
                    _sendWayPoint(dtWaypoints.Rows[dgvWP.SelectedIndex], -1, 's',false);
2372 - 3663
                else
2376 - 3664
                    _sendWayPoint(dtWaypoints.Rows[dgvWP.SelectedIndex], 1, 's',false);
2363 - 3665
 
2372 - 3666
                //int index = dgvWP.SelectedIndex;
3667
                //Thread t = new Thread(() => _sendWPList(index));
3668
                //t.Start();
2354 - 3669
 
3670
                Dispatcher.Invoke(() => {
3671
                    DataGridRow row;
2368 - 3672
                    if (_wpEdit > -1 && _wpEdit < dgvWP.ItemContainerGenerator.Items.Count)
2354 - 3673
                    {
2368 - 3674
                        row = (DataGridRow)dgvWP.ItemContainerGenerator.ContainerFromIndex(_wpEdit);
2354 - 3675
                        row.Background = new SolidColorBrush(Colors.Transparent);
3676
                        row.BorderBrush = new SolidColorBrush(Colors.Transparent);
3677
                        row.BorderThickness = new Thickness(0);
2376 - 3678
                        dgvWP.UpdateLayout();
2354 - 3679
                    }
2376 - 3680
                    //_wpEdit = dgvWP.SelectedIndex;
3681
                    //row = (DataGridRow)dgvWP.ItemContainerGenerator.ContainerFromIndex(_wpEdit);
3682
                    //row.Background = new SolidColorBrush(Color.FromArgb(80, 0, 255, 100));
3683
                    //row.BorderBrush = new SolidColorBrush(Colors.SpringGreen);
3684
                    //row.BorderThickness = new Thickness(2);
2354 - 3685
                });
2340 - 3686
            }
3687
        }
2385 - 3688
        private void btnEditWPSendToCopter_Click(object sender, RoutedEventArgs e)
3689
        {
3690
            if (dgvWP.SelectedIndex > -1 && dgvWP.SelectedIndex < dtWaypoints.Rows.Count)
3691
            {
3692
 
3693
                object[] o = new object[16];
3694
                o[0] = dgvWP.SelectedIndex + 1;
3695
                o[1] = cbWPEditType.SelectedIndex;
3696
                o[2] = tbWPEditPrefix.Text + (dgvWP.SelectedIndex + 1).ToString();
3697
                o[3] = Convert.ToDouble(tbWPEditLat.Text.Replace('.', ','));
3698
                o[4] = Convert.ToDouble(tbWPEditLon.Text.Replace('.', ','));
3699
                o[5] = tbWPEditAlt.Text;
3700
                switch (cbWPEditHeading.SelectedIndex)
3701
                {
3702
                    case 0:
3703
                        o[6] = "0";
3704
                        break;
3705
                    case 1:
3706
                        o[6] = "-" + tbWPEditHeading.Text;
3707
                        break;
3708
                    case 2:
3709
                        o[6] = tbWPEditHeading.Text;
3710
                        break;
3711
                }
3712
                switch (cbWPEditSpeed.SelectedIndex)
3713
                {
3714
                    case 0:
3715
                        o[7] = "0";
3716
                        break;
3717
                    case 1:
3718
                        o[7] = (System.Convert.ToDouble(tbWPEditSpeed.Text.Replace('.', ',')) * 10).ToString("0");
3719
                        break;
3720
                    case 2:
3721
                        o[7] = (256 - Convert.ToInt16(tbWPEditSpeed.Text)).ToString();
3722
                        break;
3723
                }
3724
                switch (cbWPEditClimbrate.SelectedIndex)
3725
                {
3726
                    case 0:
3727
                        o[8] = "255";
3728
                        break;
3729
                    case 1:
3730
                        o[8] = (System.Convert.ToDouble(tbWPEditClimbrate.Text.Replace('.', ',')) * 10).ToString("0");
3731
                        break;
3732
                }
3733
                o[9] = tbWPEditRadius.Text;
3734
                o[10] = tbWPEditHoldtime.Text;
3735
                o[11] = tbWPEditAutoTrigger.Text;
3736
                switch (cbWPEditCamAngle.SelectedIndex)
3737
                {
3738
                    case 0:
3739
                        o[12] = "0";
3740
                        break;
3741
                    case 1:
3742
                        o[12] = "255";
3743
                        break;
3744
                    case 2:
3745
                        o[12] = tbWPEditCamAngle.Text;
3746
                        break;
3747
                }
3748
                o[13] = 0;
3749
                o[14] = tbWPEditOut1.Text;
3750
                DataRow dr = dtWaypoints.NewRow();
3751
                dr.ItemArray = o;
3752
 
3753
                if (_wpCount > 0)
3754
                    _sendWayPoint(dr, -1, 'w', false);
3755
                else
3756
                    _sendWayPoint(dr, 1, 'w', false);
3757
            }
3758
        }
2376 - 3759
        private void btnWPSimulateStart_Click(object sender, RoutedEventArgs e)
3760
        {
3761
            _Simulate = !_Simulate;
3762
            if (dtWaypoints.Rows.Count > 0)
3763
            {
3764
                DataRow dr = dtWaypoints.Rows[0];
3765
                dr[13] = _Simulate ? 3 : 0;
2379 - 3766
                _sendWayPoint(dr, 0, 's', true);
2381 - 3767
                rectSimulate.Visibility = lblSimu.Visibility = _Simulate ? Visibility.Visible : Visibility.Hidden;
2376 - 3768
            }
3769
        }
2355 - 3770
        private void dgvWP_MouseUp(object sender, MouseButtonEventArgs e)
3771
        {
2359 - 3772
            _dgvWPselectEditRow();
3773
        }
3774
        private void dgvWP_MouseDoubleClick(object sender, MouseButtonEventArgs e)
3775
        {
3776
        }
3777
        void _dgvWPselectEditRow()
3778
        {
2355 - 3779
            if (dgvWP.SelectedIndex > -1 && dgvWP.SelectedIndex < dtWaypoints.Rows.Count)
3780
            {
2368 - 3781
               Dispatcher.Invoke(() => {
2355 - 3782
                    DataGridRow row;
2368 - 3783
                    if (_wpEdit > -1 && _wpEdit < dgvWP.ItemContainerGenerator.Items.Count)
2355 - 3784
                    {
3785
                        row = (DataGridRow)dgvWP.ItemContainerGenerator.ContainerFromIndex(_wpEdit);
3786
                        row.Background = new SolidColorBrush(Colors.Transparent);
3787
                        row.BorderBrush = new SolidColorBrush(Colors.Transparent);
3788
                        row.BorderThickness = new Thickness(0);
3789
                    }
3790
                    _wpEdit = dgvWP.SelectedIndex;
3791
                    row = (DataGridRow)dgvWP.ItemContainerGenerator.ContainerFromIndex(_wpEdit);
3792
                    row.Background = new SolidColorBrush(Color.FromArgb(80, 0, 100, 255));
3793
                    row.BorderBrush = new SolidColorBrush(Colors.Aqua);
3794
                    row.BorderThickness = new Thickness(2);
3795
                    dgvWP.UpdateLayout();
2340 - 3796
 
2355 - 3797
                    _setWPEditFields(_wpEdit);
3798
                });
3799
            }
3800
        }
3801
        void _setWPEditFields(int index)
3802
        {
3803
            int iVal;
3804
            cbWPEditType.SelectedIndex = (int)dtWaypoints.Rows[index][1];
3805
            tbWPEditPrefix.Text = dtWaypoints.Rows[index][2].ToString().Substring(0,1);
3806
            tbWPEditLat.Text = dtWaypoints.Rows[index][3].ToString();
3807
            tbWPEditLon.Text = dtWaypoints.Rows[index][4].ToString();
3808
            tbWPEditAlt.Text = dtWaypoints.Rows[index][5].ToString();
3809
            iVal = Convert.ToInt16(dtWaypoints.Rows[index][6]);
3810
            if (iVal == 0)
3811
            {
3812
                cbWPEditHeading.SelectedIndex = 0;
3813
                tbWPEditHeading.Text = " - - -";
3814
                tbWPEditHeading.IsReadOnly = true;
3815
            }
3816
            if (iVal > 0 && iVal < 360)
3817
            {
3818
                cbWPEditHeading.SelectedIndex = 2;
3819
                tbWPEditHeading.Text = iVal.ToString();
3820
                tbWPEditHeading.IsReadOnly = false;
3821
            }
3822
            if (iVal < 0)
3823
            {
3824
                cbWPEditHeading.SelectedIndex = 1;
3825
                tbWPEditHeading.Text = (Math.Abs(iVal).ToString());
3826
                tbWPEditHeading.IsReadOnly = false;
3827
            }
3828
            iVal = Convert.ToInt16(dtWaypoints.Rows[index][7]);
3829
            if (iVal == 0)
3830
            {
3831
                cbWPEditSpeed.SelectedIndex = 0;
3832
                tbWPEditSpeed.Text = "MAX";
3833
                tbWPEditSpeed.IsReadOnly = true;
3834
            }
3835
            if (iVal > 0 && iVal < 248)
3836
            {
3837
                cbWPEditSpeed.SelectedIndex = 1;
3838
                tbWPEditSpeed.Text = ((double)iVal * 0.1).ToString();
3839
                tbWPEditSpeed.IsReadOnly = false;
3840
            }
3841
            if (iVal > 247)
3842
            {
3843
                cbWPEditSpeed.SelectedIndex = 256 - iVal + 1;
3844
                tbWPEditSpeed.Text = "";
3845
                tbWPEditSpeed.IsReadOnly = true;
3846
            }
3847
            iVal = Convert.ToInt16(dtWaypoints.Rows[index][8]);
3848
            if (iVal == 255)
3849
            {
3850
                cbWPEditClimbrate.SelectedIndex = 0;
3851
                tbWPEditClimbrate.Text = "AUTO";
3852
                tbWPEditClimbrate.IsReadOnly = true;
3853
            }
3854
            else
3855
            {
3856
                cbWPEditClimbrate.SelectedIndex = 1;
3857
                tbWPEditClimbrate.Text = (System.Convert.ToDouble(iVal) / 10).ToString("0.0");
3858
                tbWPEditClimbrate.IsReadOnly = false;
3859
            }
3860
            iVal = Convert.ToInt16(dtWaypoints.Rows[index][9]);
3861
            tbWPEditRadius.Text = iVal.ToString();
3862
            iVal = Convert.ToInt16(dtWaypoints.Rows[index][10]);
3863
            tbWPEditHoldtime.Text = iVal.ToString();
3864
            iVal = Convert.ToInt16(dtWaypoints.Rows[index][11]);
3865
            tbWPEditAutoTrigger.Text = iVal.ToString();
3866
            iVal = Convert.ToInt16(dtWaypoints.Rows[index][12]);
3867
            if (iVal == 0)
3868
            {
3869
                cbWPEditCamAngle.SelectedIndex = 0;
3870
                tbWPEditCamAngle.Text = " - - - ";
3871
                tbWPEditCamAngle.IsReadOnly = true;
3872
            }
3873
            if (iVal < 0 | iVal == 255)
3874
            {
3875
                cbWPEditCamAngle.SelectedIndex = 1;
3876
                tbWPEditCamAngle.Text = "AUTO";
3877
                tbWPEditCamAngle.IsReadOnly = true;
3878
            }
3879
            if (iVal > 0 & iVal < 255)
3880
            {
3881
                cbWPEditCamAngle.SelectedIndex = 2;
3882
                tbWPEditCamAngle.Text = iVal.ToString();
3883
                tbWPEditCamAngle.IsReadOnly = false;
3884
            }
3885
            iVal = Convert.ToInt16(dtWaypoints.Rows[index][14]);
3886
            tbWPEditOut1.Text = iVal.ToString();
3887
 
3888
        }
3889
 
2361 - 3890
        private void btnEditWPSave_Click(object sender, RoutedEventArgs e)
3891
        {
2363 - 3892
            if(dgvWP.SelectedIndex > -1 && dgvWP.SelectedIndex < dtWaypoints.Rows.Count)
3893
            {
2369 - 3894
                string oldName = (string)dtWaypoints.Rows[dgvWP.SelectedIndex][2];
2372 - 3895
                int oldType = (int)dtWaypoints.Rows[dgvWP.SelectedIndex][1];
3896
                PointLatLng pOld = new PointLatLng((double)dtWaypoints.Rows[dgvWP.SelectedIndex][3], (double)dtWaypoints.Rows[dgvWP.SelectedIndex][4]);
3897
                int i = wpList.IndexOf(pOld);
2363 - 3898
                dtWaypoints.Rows[dgvWP.SelectedIndex][1] = cbWPEditType.SelectedIndex;
3899
                dtWaypoints.Rows[dgvWP.SelectedIndex][2] = tbWPEditPrefix.Text + (dgvWP.SelectedIndex + 1).ToString();
3900
                dtWaypoints.Rows[dgvWP.SelectedIndex][3] = Convert.ToDouble(tbWPEditLat.Text.Replace('.', ','));
3901
                dtWaypoints.Rows[dgvWP.SelectedIndex][4] = Convert.ToDouble(tbWPEditLon.Text.Replace('.', ','));
2372 - 3902
                if (i > -1)
3903
                {
3904
                    if((int)dtWaypoints.Rows[dgvWP.SelectedIndex][1] == 0 || (int)dtWaypoints.Rows[dgvWP.SelectedIndex][1] == 3)
3905
                        wpList[i] = (new PointLatLng((double)dtWaypoints.Rows[dgvWP.SelectedIndex][3], (double)dtWaypoints.Rows[dgvWP.SelectedIndex][4]));
3906
                    else
3907
                        wpList.Remove(pOld);
3908
                }
3909
                else
3910
                {
3911
                    if ((int)dtWaypoints.Rows[dgvWP.SelectedIndex][1] == 0 || (int)dtWaypoints.Rows[dgvWP.SelectedIndex][1] == 3)
3912
                    {
3913
                        int found = 0;
3914
                        for (int k = 0; k < dgvWP.SelectedIndex; k++)
3915
                            if ((int)dtWaypoints.Rows[k][1] == 0)
3916
                                found++;
3917
                        wpList.Insert(found, new PointLatLng((double)dtWaypoints.Rows[dgvWP.SelectedIndex][3], (double)dtWaypoints.Rows[dgvWP.SelectedIndex][4]));
3918
                    }
3919
                }
2363 - 3920
                dtWaypoints.Rows[dgvWP.SelectedIndex][5] = tbWPEditAlt.Text;
3921
                switch (cbWPEditHeading.SelectedIndex)
3922
                {
3923
                    case 0:
3924
                        dtWaypoints.Rows[dgvWP.SelectedIndex][6] = "0";
3925
                        break;
3926
                    case 1:
3927
                        dtWaypoints.Rows[dgvWP.SelectedIndex][6] = "-" + tbWPEditHeading.Text;
3928
                        break;
3929
                    case 2:
3930
                        dtWaypoints.Rows[dgvWP.SelectedIndex][6] = tbWPEditHeading.Text;
3931
                        break;
3932
                }
3933
                switch (cbWPEditSpeed.SelectedIndex)
3934
                {
3935
                    case 0:
3936
                        dtWaypoints.Rows[dgvWP.SelectedIndex][7] = "0";
3937
                        break;
3938
                    case 1:
3939
                        dtWaypoints.Rows[dgvWP.SelectedIndex][7] = (System.Convert.ToDouble(tbWPEditSpeed.Text.Replace('.', ',')) * 10).ToString("0");
3940
                        break;
3941
                    case 2:
3942
                        dtWaypoints.Rows[dgvWP.SelectedIndex][7] = (256 - Convert.ToInt16(tbWPEditSpeed.Text)).ToString();
3943
                        break;
3944
                }
3945
                switch (cbWPEditClimbrate.SelectedIndex)
3946
                {
3947
                    case 0:
3948
                        dtWaypoints.Rows[dgvWP.SelectedIndex][8] = "255";
3949
                        break;
3950
                    case 1:
3951
                        dtWaypoints.Rows[dgvWP.SelectedIndex][8] = (System.Convert.ToDouble(tbWPEditClimbrate.Text.Replace('.',',')) * 10).ToString("0");
3952
                        break;
3953
                }
3954
                dtWaypoints.Rows[dgvWP.SelectedIndex][9] = tbWPEditRadius.Text;
3955
                dtWaypoints.Rows[dgvWP.SelectedIndex][10] = tbWPEditHoldtime.Text;
3956
                dtWaypoints.Rows[dgvWP.SelectedIndex][11] = tbWPEditAutoTrigger.Text;
3957
                switch (cbWPEditCamAngle.SelectedIndex)
3958
                {
3959
                    case 0:
3960
                        dtWaypoints.Rows[dgvWP.SelectedIndex][12] = "0";
3961
                        break;
3962
                    case 1:
3963
                        dtWaypoints.Rows[dgvWP.SelectedIndex][12] = "255";
3964
                        break;
3965
                    case 2:
3966
                        dtWaypoints.Rows[dgvWP.SelectedIndex][12] = tbWPEditCamAngle.Text;
3967
                        break;
3968
                }
3969
                dtWaypoints.Rows[dgvWP.SelectedIndex][14] = tbWPEditOut1.Text;
2361 - 3970
 
2369 - 3971
                // _clearMapMarkers(typeof(CustomMarkerWP));
3972
                _repositionWPMarker(new PointLatLng((double)dtWaypoints.Rows[dgvWP.SelectedIndex][3], (double)dtWaypoints.Rows[dgvWP.SelectedIndex][4]),oldName);
3973
                _renameWPMarker(oldName, (string)dtWaypoints.Rows[dgvWP.SelectedIndex][2]);
2363 - 3974
                _clearMapMarkers(typeof(CustomMarkerWPActive));
2369 - 3975
                _setMarkerColor(_findWPMarker((string)dtWaypoints.Rows[dgvWP.SelectedIndex][2]), (int)dtWaypoints.Rows[dgvWP.SelectedIndex][1]);
2372 - 3976
                _WPMarkerSetType((string)dtWaypoints.Rows[dgvWP.SelectedIndex][2], (int)dtWaypoints.Rows[dgvWP.SelectedIndex][1]);
2369 - 3977
               // wpList.Clear();
2363 - 3978
                if (mRouteWP != null)
3979
                    MainMap.Markers.Remove(mRouteWP);
3980
 
2369 - 3981
                //for (int k = 0; k < dtWaypoints.Rows.Count; k++)
3982
                //{
3983
                //    _createWP(new PointLatLng((double)dtWaypoints.Rows[k][3], (double)dtWaypoints.Rows[k][4]), (string)dtWaypoints.Rows[k][2], (int)dtWaypoints.Rows[k][1]);
3984
                //}
2363 - 3985
                _routeUpdate();
3986
                dgvWP.Items.Refresh();
3987
 
3988
            }
3989
 
2361 - 3990
        }
3991
        private void btnEditWPDel_Click(object sender, RoutedEventArgs e)
3992
        {
2368 - 3993
            if (dgvWP.SelectedIndex > -1 && dgvWP.SelectedIndex < dtWaypoints.Rows.Count)
3994
            {
3995
                int index = dgvWP.SelectedIndex;
3996
                Dispatcher.Invoke(() => {
3997
                    DataGridRow row;
3998
                    if (_wpEdit > -1 && _wpEdit < dgvWP.ItemContainerGenerator.Items.Count)
3999
                    {
4000
                        row = (DataGridRow)dgvWP.ItemContainerGenerator.ContainerFromIndex(_wpEdit);
4001
                        row.Background = new SolidColorBrush(Colors.Transparent);
4002
                        row.BorderBrush = new SolidColorBrush(Colors.Transparent);
4003
                        row.BorderThickness = new Thickness(0);
4004
                    }
2372 - 4005
                    if ((int)dtWaypoints.Rows[index][1] == 0 || (int)dtWaypoints.Rows[index][1] == 3)
2368 - 4006
                        wpList.Remove(new PointLatLng((double)dtWaypoints.Rows[index][3], (double)dtWaypoints.Rows[index][4]));
4007
                    _clearWPMarker((string)dtWaypoints.Rows[index][2]);
2369 - 4008
                    if (wpActiveMarker != null)
4009
                        MainMap.Markers.Remove(wpActiveMarker);
2368 - 4010
                    dtWaypoints.Rows[index].Delete();
4011
                    _wpIndex = -1;
4012
                    _wpEdit = -1;
4013
                    for (int i = index; i < dtWaypoints.Rows.Count; i++) //change the index of points behind deleted point + rename to new index
4014
                    {
4015
                        dtWaypoints.Rows[i][0] = i + 1;
4016
                        string s1 = (string)dtWaypoints.Rows[i][2]; //old name of WP (Prefix + index)
4017
                        string s2 = s1.Substring(0, 1) + (i + 1).ToString(); //new name of WP
4018
                        _renameWPMarker(s1, s2);
4019
                        dtWaypoints.Rows[i][2] = s2;
4020
                    }
4021
                    lblWPCount.Content = dtWaypoints.Rows.Count;
4022
                    if (mRouteWP != null)
4023
                        MainMap.Markers.Remove(mRouteWP);
4024
                    _routeUpdate();
2361 - 4025
 
2368 - 4026
                    dgvWP.UpdateLayout();
4027
                });
4028
            }
2361 - 4029
        }
2366 - 4030
        private void tbWPEdit_TouchDown(object sender, TouchEventArgs e)
4031
        {
4032
            _wpWEdit(sender);
4033
        }
2361 - 4034
        private void tbWPEdit_KeyDown(object sender, KeyEventArgs e)
4035
        {
2366 - 4036
            _wpWEdit(sender);
4037
        }
2369 - 4038
        private void tbWPEdit_MouseDown(object sender, MouseButtonEventArgs e)
4039
        {
4040
            _wpWEdit(sender);
4041
        }
2366 - 4042
        void _wpWEdit(object sender)
4043
        {
2369 - 4044
           // if (!((TextBox)sender).IsReadOnly)
2361 - 4045
            {
4046
                KeyPad.Keypad k = new KeyPad.Keypad(this);
4047
 
2363 - 4048
                switch (((TextBox)sender).Name)
4049
                {
4050
                    case "tbWPEditLat":
4051
                        k.Title = "Latitude";
4052
                        k.LENGTH = 17;
4053
                        k.MAX = 359.9;
4054
                        break;
4055
                    case "tbWPEditLon":
4056
                        k.Title = "Longitude";
4057
                        k.LENGTH = 17;
4058
                        k.MAX = 359.9;
4059
                        break;
4060
                    case "tbWPEditAlt":
4061
                        k.Title = "Altitude";
4062
                        k.LENGTH = 3;
4063
                        k.MAX = 254;
4064
                        k.disableDecimal();
4065
                        break;
4066
                    case "tbWPEditHeading":
4067
                        k.Title = "Heading";
4068
                        k.LENGTH = 3;
4069
                        k.MAX = 359;
4070
                        k.MIN = 1;
4071
                        k.disableDecimal();
4072
                        break;
4073
                    case "tbWPEditSpeed":
4074
                        k.Title = "Speed";
4075
                        k.LENGTH = 4;
4076
                        k.MAX = 24.7;
4077
                        k.MIN = 0.1;
4078
                        break;
4079
                    case "tbWPEditClimbrate":
4080
                        k.Title = "Climbrate";
4081
                        k.LENGTH = 4;
4082
                        k.MAX = 25.4;
4083
                        k.MIN = 0.1;
4084
                        break;
4085
                    case "tbWPEditRadius":
4086
                        k.Title = "Radius";
4087
                        k.LENGTH = 3;
4088
                        k.MAX = 254;
4089
                        k.disableDecimal();
4090
                        break;
4091
                    case "tbWPEditHoldtime":
4092
                        k.Title = "Holdtime";
4093
                        k.LENGTH = 3;
4094
                        k.MAX = 254;
4095
                        break;
4096
                    case "tbWPEditAutoTrigger":
4097
                        k.Title = "Autotrigger";
4098
                        k.LENGTH = 3;
4099
                        k.MAX = 254;
4100
                        k.disableDecimal();
4101
                        break;
4102
                    case "tbWPEditCamAngle":
4103
                        k.Title = "Camera angle";
4104
                        k.LENGTH = 3;
4105
                        k.MAX = 254;
4106
                        k.MIN = 1;
4107
                        k.disableDecimal();
4108
                        break;
4109
                    case "tbWPEditOut1":
4110
                        k.Title = "OUT1 timer interval";
4111
                        k.LENGTH = 3;
4112
                        k.MAX = 254;
4113
                        k.disableDecimal();
4114
                        break;
4115
                }
4116
                k.Result = ((TextBox)sender).Text;
2366 - 4117
                if (k.ShowDialog() == true && k.Result.Length > 0)
2363 - 4118
                    ((TextBox)sender).Text = k.Result;
2361 - 4119
            }
2366 - 4120
 
2361 - 4121
        }
4122
        private void btnWPAddCurrentPos_Click(object sender, RoutedEventArgs e)
2356 - 4123
        {
2359 - 4124
            object[] o = new object[16];
2356 - 4125
 
2359 - 4126
            o[0] = dgvWP.ItemContainerGenerator.Items.Count+1;
4127
            o[1] = 0;
4128
           //     cbWPEditType.SelectedIndex = 0;
4129
          //  tbWPEditPrefix.Text = "P";
4130
            o[2] = "P" + o[0].ToString();
4131
         //   tbWPEditLat.Text = copter.Position.Lat.ToString();
4132
            o[3] = copter.Position.Lat;
4133
          //  tbWPEditLon.Text = copter.Position.Lng.ToString();
4134
            o[4] = copter.Position.Lng;            
4135
         //   tbWPEditAlt.Text = ((double)iAnalogData[4] / (double)10).ToString();
4136
            o[5] = iAnalogData[4].ToString();
2356 - 4137
 
2359 - 4138
        //    cbWPEditHeading.SelectedIndex = 2;
4139
            o[6] = tbWPEditHeading.Text = iAnalogData[10].ToString();
4140
        //    tbWPEditHeading.IsReadOnly = false;
2356 - 4141
 
2359 - 4142
       //     cbWPEditSpeed.SelectedIndex = 1;
4143
       //     tbWPEditSpeed.Text = "5.0";
4144
       //     tbWPEditSpeed.IsReadOnly = false;
2372 - 4145
            o[7] = "10";
2356 - 4146
 
2359 - 4147
      //      cbWPEditClimbrate.SelectedIndex = 1;
4148
     //       tbWPEditClimbrate.Text = "5.0";
4149
     //       tbWPEditClimbrate.IsReadOnly = false;
2372 - 4150
            o[8] = "10";
2356 - 4151
 
2359 - 4152
     //       tbWPEditRadius.Text = "10";
2372 - 4153
            o[9] = "5";
2359 - 4154
     //       tbWPEditHoldtime.Text = "5";
4155
            o[10] = "5";
4156
      //      tbWPEditAutoTrigger.Text = "0";
4157
            o[11] = "0";
4158
     //       cbWPEditCamAngle.SelectedIndex = 1;
4159
     //       tbWPEditCamAngle.Text = "AUTO";
4160
     //       tbWPEditCamAngle.IsReadOnly = true;
4161
            o[12] = "255";
2356 - 4162
 
2359 - 4163
            o[13] = "0";
4164
           //     tbWPEditOut1.Text = "0";
4165
            o[14] = "0";
4166
            o[15] = "0";
4167
 
4168
            dtWaypoints.Rows.Add(o);
2368 - 4169
            _createWP(new PointLatLng((double)o[3], (double)o[4]), (string)o[2], (int)o[1]);
2359 - 4170
            Dispatcher.Invoke(() => lblWPCount.Content = o[0].ToString());
4171
            if (mRouteWP != null)
4172
                MainMap.Markers.Remove(mRouteWP);
4173
            _routeUpdate();
4174
            Dispatcher.Invoke(() => {
4175
                dgvWP.Items.Refresh();
4176
                dgvWP.SelectedIndex = (int)o[0] -1;
4177
                dgvWP.UpdateLayout();
4178
                _dgvWPselectEditRow();
4179
                });
2356 - 4180
        }
4181
 
2315 - 4182
        #endregion WP
2324 - 4183
        #region GPX
4184
        private void checkBoxGPXLog_Click(object sender, RoutedEventArgs e)
4185
        {
4186
            _bGPXLog = (bool)checkBoxGPXLog.IsChecked;
4187
        }
4188
        void _gpxAdd(double lat,double lon, int elevation)
4189
        {
4190
            DataRow dr = dtGPX.NewRow();
4191
            dr[0] = dtGPX.Rows.Count - 1;
4192
            dr[1] = lat;
4193
            dr[2] = lon;
4194
            dr[3] = elevation;
4195
            dr[4] = DateTime.UtcNow.ToString("s", System.Globalization.CultureInfo.InvariantCulture); //2011-01-14T01:59:01Z
4196
            dtGPX.Rows.Add(dr);
4197
        }
4198
        void _saveGPXLog()
4199
        {
4200
            if (!Directory.Exists("GPXLog"))
4201
                Directory.CreateDirectory("GPXLog");
4202
            string SaveFileName = "GPXLog\\" + DateTime.Now.ToString("yyyyMMdd_HHmm") + ".gpx";
4203
            XmlTextWriter myXmlTextWriter = null;
4204
            myXmlTextWriter = new XmlTextWriter(SaveFileName, null);
4205
            NumberFormatInfo nfi = new NumberFormatInfo();
4206
            nfi.NumberDecimalSeparator = ".";
2315 - 4207
 
2324 - 4208
            try
4209
            {
4210
                myXmlTextWriter.Formatting = Formatting.Indented;
4211
 
4212
                myXmlTextWriter.WriteStartDocument();
4213
 
4214
                myXmlTextWriter.WriteStartElement("gpx");
4215
 
4216
                myXmlTextWriter.WriteAttributeString("version", "1.0");
4217
                myXmlTextWriter.WriteAttributeString("creator", "MKLiveView v1.0");
4218
                myXmlTextWriter.WriteAttributeString("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
4219
                myXmlTextWriter.WriteAttributeString("xmlns", "http://www.topografix.com/GPX/1/1");
4220
                myXmlTextWriter.WriteAttributeString("xsi:schemaLocation", "http://www.topografix.com/GPX/1/1/gpx.xsd");
4221
 
4222
                myXmlTextWriter.WriteElementString("time", DateTime.UtcNow.ToString("u", System.Globalization.CultureInfo.InvariantCulture));
4223
 
4224
                myXmlTextWriter.WriteStartElement("trk");
4225
                myXmlTextWriter.WriteStartElement("trkseg");
4226
                for(int i = 0; i< dtGPX.Rows.Count;i++)
4227
                {
4228
                    myXmlTextWriter.WriteStartElement("trkpt");
4229
                    myXmlTextWriter.WriteAttributeString("lat", dtGPX.Rows[i][1].ToString() != "" ? ((double)dtGPX.Rows[i][1]).ToString(nfi) : "");
4230
                    myXmlTextWriter.WriteAttributeString("lon", dtGPX.Rows[i][2].ToString() != "" ? ((double)dtGPX.Rows[i][2]).ToString(nfi) : "");
4231
                    myXmlTextWriter.WriteElementString("ele", dtGPX.Rows[i][3].ToString());
4232
                    myXmlTextWriter.WriteElementString("time", dtGPX.Rows[i][4].ToString());
4233
                    myXmlTextWriter.WriteEndElement();
4234
                }
4235
                myXmlTextWriter.WriteEndElement();
4236
                myXmlTextWriter.WriteEndElement();
4237
                myXmlTextWriter.WriteEndElement();
4238
            }
4239
            catch (Exception e)
4240
            {
4241
                Console.WriteLine("Exception: {0}", e.ToString());
4242
            }
4243
            finally
4244
            {
4245
                if (myXmlTextWriter != null)
4246
                {
4247
                    myXmlTextWriter.Close();
4248
                }
4249
            }
4250
        }
2356 - 4251
 
2385 - 4252
 
2324 - 4253
        private void btnLoadGPXLog_Click(object sender, RoutedEventArgs e)
4254
        {
4255
            _loadGPXLog();
4256
        }
2327 - 4257
        private void btnClearRoute_Click(object sender, RoutedEventArgs e)
4258
        {
4259
            _clearMapMarkers(typeof(GMapRoute));
4260
        }
2324 - 4261
        void _loadGPXLog()
4262
        {
4263
 
4264
            Microsoft.Win32.OpenFileDialog fd = new Microsoft.Win32.OpenFileDialog();
4265
            fd.Filter = "GPX-Logfile | *.gpx";
4266
            fd.Multiselect = false;
4267
            if (fd.ShowDialog().Value)
4268
            {
4269
                string file = fd.FileName;
4270
                try
4271
                {
4272
                    XDocument gpxDoc = XDocument.Load(file);
4273
                    XNamespace gpx = XNamespace.Get("http://www.topografix.com/GPX/1/1");
4274
 
4275
                    NumberFormatInfo nfi = new NumberFormatInfo();
4276
                    nfi.NumberDecimalSeparator = ".";
4277
 
4278
                    var tracks = from track in gpxDoc.Descendants(gpx + "trk")
4279
                                 select new
4280
                                 {
4281
                                     Name = track.Element(gpx + "name") != null ? track.Element(gpx + "name").Value : null,
4282
                                     Segs = (
4283
                                         from trackpoint in track.Descendants(gpx + "trkpt")
4284
                                         select new
4285
                                         {
4286
                                             Latitude = trackpoint.Attribute("lat").Value,
4287
                                             Longitude = trackpoint.Attribute("lon").Value,
4288
                                             Elevation = trackpoint.Element(gpx + "ele") != null ?
4289
                                             trackpoint.Element(gpx + "ele").Value : null,
4290
                                             Time = trackpoint.Element(gpx + "time") != null ?
4291
                                             trackpoint.Element(gpx + "time").Value : null
4292
                                         }
4293
                                     )
4294
                                 };
4295
 
4296
                    List<PointLatLng> wpl = new List<PointLatLng>();
4297
                    foreach(var trk in tracks)
4298
                    {
4299
                        foreach(var trkseg in trk.Segs)
4300
                        {
4301
                            if(trkseg.Latitude != "" && trkseg.Longitude !="")
4302
                            wpl.Add(new PointLatLng(Convert.ToDouble(trkseg.Latitude, nfi), Convert.ToDouble(trkseg.Longitude, nfi)));
4303
                        }
4304
 
4305
                    }
4306
                    if(wpl.Count() > 0)
4307
                    {
2327 - 4308
                        _clearMapMarkers(typeof(GMapRoute));
2324 - 4309
                        MapRoute mr = new MapRoute(wpl, "flying");
2328 - 4310
                        Dispatcher.Invoke(() =>
4311
                        {
4312
                            GMapRoute mRoute;
4313
                            if (comboBoxRouteColor.SelectionBoxItem != null)
4314
                            {
4315
                                string s = comboBoxRouteColor.SelectionBoxItem.ToString();
2366 - 4316
                                mRoute = new GMapRoute(wpl, _getBrush(s));
2328 - 4317
                            }
4318
                            else
2366 - 4319
                                mRoute = new GMapRoute(wpl, null);
2324 - 4320
 
2328 - 4321
                            MainMap.Markers.Add(mRoute);
4322
                        });
2324 - 4323
                    }
4324
 
4325
                }
4326
                catch (Exception e)
4327
                {
4328
                    Console.WriteLine("Exception: {0}", e.ToString());
4329
                }
4330
            }
4331
        }
4332
        #endregion GPX
2315 - 4333
        #endregion functions
2287 - 4334
    }
2315 - 4335
     /// <summary>
4336
    /// formats the wp datatable values for display in datagrid - this is bound in the datagrid as a converter
4337
    /// </summary>
2313 - 4338
    public class waypointsConverter : IValueConverter
4339
    {
4340
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
4341
        {
4342
            if (value != null)
4343
            {
4344
                switch ((string)parameter)
4345
                {
4346
                    case "Latitude":
4347
                        return value.ToString() + " °";
4348
                    case "Longitude":
4349
                        return value.ToString() + " °";
4350
                    case "Radius":
4351
                        return value.ToString() + " m";
4352
                    case "Altitude":
4353
                        return value.ToString() + " m";
4354
                    case "ClimbRate":
4355
                        return value.ToString() == "255" ? "Auto" : (System.Convert.ToDouble(value) / 10).ToString("0.0 m/s");
4356
                    case "DelayTime":
4357
                        return value.ToString() + " s";
4358
                    case "Heading":
4359
                        return Waypoints.Heading(System.Convert.ToInt32(value));
4360
                    case "Speed":
4361
                        return Waypoints.WPSpeed(System.Convert.ToInt16(value));
4362
                    case "CamAngle":
4363
                        return Waypoints.CAMAngle(System.Convert.ToInt16(value));
4364
                    case "Type":
4365
                        return ((Waypoints.pointType)(System.Convert.ToInt16(value))).ToString();
4366
                    case "AutoTrigger":
4367
                        return value.ToString() == "0" ? "- - -" : value.ToString() + " m";
4368
                    case "Status":
2355 - 4369
                        return (Waypoints.status)(System.Convert.ToInt16(value));
2313 - 4370
                }
4371
 
4372
                return value.ToString();
4373
            }
4374
            else return value;
4375
        }
4376
 
4377
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
4378
        {
4379
            throw new NotImplementedException();
4380
        }
4381
    }
4382
 
2287 - 4383
    public class IniFile
4384
    {
4385
        public string path;
4386
 
4387
        [DllImport("kernel32")]
4388
        private static extern long WritePrivateProfileString(string section,
4389
          string key, string val, string filePath);
4390
 
4391
        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
4392
        static extern uint GetPrivateProfileSectionNames(IntPtr lpszReturnBuffer,
4393
               uint nSize, string lpFileName);
4394
 
4395
        [DllImport("kernel32")]
4396
        private static extern int GetPrivateProfileString(string section,
4397
          string key, string def, StringBuilder retVal,
4398
          int size, string filePath);
4399
 
4400
        public IniFile(string INIPath)
4401
        {
4402
            path = INIPath;
4403
        }
4404
 
4405
        public void IniWriteValue(string Section, string Key, string Value)
4406
        {
4407
            WritePrivateProfileString(Section, Key, Value, this.path);
4408
        }
4409
 
4410
        public string IniReadValue(string Section, string Key)
4411
        {
4412
            StringBuilder temp = new StringBuilder(255);
4413
            int i = GetPrivateProfileString(Section, Key, "", temp, 255, this.path);
4414
            return temp.ToString();
4415
        }
4416
        //Ini_sections auslesen in String-Array
4417
        public string[] IniSectionNames()
4418
        {
4419
 
4420
            //  uint MAX_BUFFER = 32767;
4421
            uint MAX_BUFFER = 8388608;
4422
            IntPtr pReturnedString = Marshal.AllocCoTaskMem((int)MAX_BUFFER);
4423
            uint bytesReturned = GetPrivateProfileSectionNames(pReturnedString, MAX_BUFFER, this.path);
4424
            if (bytesReturned == 0)
4425
            {
4426
                Marshal.FreeCoTaskMem(pReturnedString);
4427
                return null;
4428
            }
4429
            string local = Marshal.PtrToStringAuto(pReturnedString, (int)bytesReturned).ToString();
4430
            Marshal.FreeCoTaskMem(pReturnedString);
4431
            //use of Substring below removes terminating null for split
4432
            return local.Substring(0, local.Length - 1).Split('\0');
4433
 
4434
 
4435
        }
4436
    }
4437
 
4438
    /// <summary>
4439
    /// Selected Win AI Function Calls
4440
    /// </summary>
4441
    public class WinApi
4442
    {
4443
        [DllImport("user32.dll", EntryPoint = "GetSystemMetrics")]
4444
        public static extern int GetSystemMetrics(int which);
4445
        [DllImport("user32.dll")]
4446
        public static extern void
4447
                SetWindowPos(IntPtr hwnd, IntPtr hwndInsertAfter,
4448
                             int X, int Y, int width, int height, uint flags);
4449
 
4450
        private const int SM_CXSCREEN = 0;
4451
        private const int SM_CYSCREEN = 1;
4452
        private static IntPtr HWND_TOP = IntPtr.Zero;
4453
        private const int SWP_SHOWWINDOW = 64; // 0x0040
4454
 
4455
        public static int ScreenX
4456
        {
4457
            get { return GetSystemMetrics(SM_CXSCREEN); }
4458
        }
4459
 
4460
        public static int ScreenY
4461
        {
4462
            get { return GetSystemMetrics(SM_CYSCREEN); }
4463
        }
4464
 
4465
        public static void SetWinFullScreen(IntPtr hwnd)
4466
        {
4467
            SetWindowPos(hwnd, HWND_TOP, -8, -7, ScreenX+15, ScreenY+14, SWP_SHOWWINDOW);
4468
        }
4469
    }
4470
    /// <summary>
4471
    /// Class used to preserve / restore state of the window
4472
    /// </summary>
4473
    public class WinState
4474
    {
4475
        private WindowState winState;
4476
        private WindowStyle brdStyle;
4477
        private bool topMost;
4478
        private Rect restore;
4479
        private bool IsMaximized = false;
4480
 
4481
        public bool isMaximized
4482
        {
4483
            get { return IsMaximized; }
4484
        }
4485
        public void Maximize(Window targetForm)
4486
        {
4487
            if (!IsMaximized)
4488
            {
4489
                IsMaximized = true;
4490
                Save(targetForm);
4491
                targetForm.WindowState = WindowState.Maximized;
4492
                targetForm.WindowStyle = WindowStyle.None;
4493
                targetForm.Topmost = true;
4494
                WinApi.SetWinFullScreen(new WindowInteropHelper(targetForm).Handle);
4495
            }
4496
        }
4497
 
4498
        public void Save(Window targetForm)
4499
        {
4500
            winState = targetForm.WindowState;
4501
            brdStyle = targetForm.WindowStyle;
4502
            topMost = targetForm.Topmost;
4503
            restore = targetForm.RestoreBounds;
4504
        }
4505
        public void Restore(Window targetForm)
4506
        {
4507
            targetForm.WindowState = winState;
4508
            targetForm.WindowStyle = brdStyle;
4509
            targetForm.Topmost = topMost;
4510
 
4511
            targetForm.Left = restore.Left;
4512
            targetForm.Top = restore.Top;
4513
            targetForm.Height = restore.Height;
4514
            targetForm.Width = restore.Width;
4515
            IsMaximized = false;
4516
        }
4517
    }
4518
 
4519
}