|
6 | 6 | // Declare variables
|
7 | 7 | "use strict";
|
8 | 8 | // Unsaved
|
9 |
| - const CurrentVersion = 0.16, |
| 9 | + const CurrentVersion = 0.17, |
10 | 10 | GeolocationAPIOptions = {
|
11 | 11 | enableHighAccuracy: true
|
12 | 12 | };
|
|
81 | 81 | },
|
82 | 82 | Speed: {
|
83 | 83 | Speed: 0, Vertical: 0, Pitch: 0,
|
84 |
| - GS: 0, GSDisplay: 0, TAS: 0, TASDisplay: 0, |
| 84 | + GS: 0, GSDisplay: 0, |
| 85 | + SampleCount: 0, AvgGS: 0, AvgGSDisplay: 0, |
| 86 | + TAS: 0, TASDisplay: 0, |
85 | 87 | Wind: {
|
86 | 88 | Heading: 0, RelativeHeading: 0 // Wind "heading" is the opposite of wind direction.
|
87 | 89 | },
|
|
114 | 116 | }
|
115 | 117 | };
|
116 | 118 | Automation.ClockPFD = null;
|
| 119 | + Automation.ClockAvgGS = null; |
117 | 120 |
|
118 | 121 | // Saved
|
119 | 122 | var Subsystem = {
|
|
174 | 177 | Arrival: {
|
175 | 178 | Lat: 0, Lon: 0
|
176 | 179 | }
|
177 |
| - } |
| 180 | + }, |
| 181 | + ETACalcMethod: "UseAvgGS" |
178 | 182 | },
|
179 | 183 | FlightMode: {
|
180 | 184 | FlightMode: "DepartureGround",
|
|
243 | 247 | RefreshSystem();
|
244 | 248 | RefreshSubsystem();
|
245 | 249 | RefreshPFD();
|
| 250 | + ClockAvgGS(); |
246 | 251 |
|
247 | 252 | // PWA
|
248 | 253 | navigator.serviceWorker.register("script_ServiceWorker.js").then(function(ServiceWorkerRegistration) {
|
|
567 | 572 | ChangeText("Label_PFDDefaultPanelGPSStatusTitle", "GPS 状态");
|
568 | 573 | ChangeText("Label_PFDDefaultPanelAccelStatusTitle", "加速计状态");
|
569 | 574 | ChangeText("Label_PFDDefaultPanelGSTitle", "地速");
|
| 575 | + ChangeText("Label_PFDDefaultPanelAvgGSTitle", "平均地速"); |
570 | 576 | ChangeText("Label_PFDDefaultPanelTASTitle", "真空速");
|
571 | 577 | ChangeText("Label_PFDDefaultPanelWindTitle", "风");
|
572 | 578 | ChangeText("Label_PFDDefaultPanelFlapsTitle", "襟翼");
|
|
594 | 600 | ChangeText("Label_PFDDefaultPanelGPSStatusTitle", "GPS STS");
|
595 | 601 | ChangeText("Label_PFDDefaultPanelAccelStatusTitle", "ACCEL STS");
|
596 | 602 | ChangeText("Label_PFDDefaultPanelGSTitle", "GS");
|
| 603 | + ChangeText("Label_PFDDefaultPanelAvgGSTitle", "AVG GS"); |
597 | 604 | ChangeText("Label_PFDDefaultPanelTASTitle", "TAS");
|
598 | 605 | ChangeText("Label_PFDDefaultPanelWindTitle", "WIND");
|
599 | 606 | ChangeText("Label_PFDDefaultPanelFlapsTitle", "FLAPS");
|
|
973 | 980 |
|
974 | 981 | // GS
|
975 | 982 | PFD0.Stats.Speed.GS = Math.sqrt(Math.max(Math.pow(PFD0.Stats.Speed.Speed, 2) - Math.pow(PFD0.Stats.Speed.Vertical, 2), 0));
|
976 |
| - PFD0.Stats.Speed.GSDisplay += (PFD0.Stats.Speed.GS - PFD0.Stats.Speed.GSDisplay) / 50; |
| 983 | + PFD0.Stats.Speed.GSDisplay += (PFD0.Stats.Speed.GS - PFD0.Stats.Speed.GSDisplay) / 50 * ((PFD0.Stats.ClockTime - PFD0.Stats.PreviousClockTime) / 30); |
| 984 | + |
| 985 | + // Avg GS |
| 986 | + PFD0.Stats.Speed.AvgGSDisplay += (PFD0.Stats.Speed.AvgGS - PFD0.Stats.Speed.AvgGSDisplay) / 50 * ((PFD0.Stats.ClockTime - PFD0.Stats.PreviousClockTime) / 30); |
977 | 987 |
|
978 | 988 | // TAS
|
979 | 989 | if(PFD0.Status.GPS.IsHeadingAvailable == true) {
|
|
986 | 996 | } else {
|
987 | 997 | PFD0.Stats.Speed.TAS = CalcTAS(PFD0.Stats.Speed.GS, null, null, PFD0.Stats.Speed.Vertical);
|
988 | 998 | }
|
989 |
| - PFD0.Stats.Speed.TASDisplay += (PFD0.Stats.Speed.TAS - PFD0.Stats.Speed.TASDisplay) / 50; |
| 999 | + PFD0.Stats.Speed.TASDisplay += (PFD0.Stats.Speed.TAS - PFD0.Stats.Speed.TASDisplay) / 50 * ((PFD0.Stats.ClockTime - PFD0.Stats.PreviousClockTime) / 30); |
990 | 1000 |
|
991 | 1001 | // IAS
|
992 | 1002 | switch(PFD.FlightMode.FlightMode) {
|
|
1068 | 1078 | AlertSystemError("The value of PFD.FlightMode.FlightMode \"" + PFD.FlightMode.FlightMode + "\" in function RefreshPFDData is invalid.");
|
1069 | 1079 | break;
|
1070 | 1080 | }
|
1071 |
| - if(PFD0.Stats.Speed.GSDisplay > 0) { |
1072 |
| - PFD0.Stats.DME.ETA = PFD0.Stats.DME.Distance / PFD0.Stats.Speed.GSDisplay * 1000; // (Meter / meter per sec) = sec, sec * 1000 = millisec. |
| 1081 | + switch(PFD.DME.ETACalcMethod) { |
| 1082 | + case "UseRealTimeGS": |
| 1083 | + if(PFD0.Stats.Speed.GSDisplay > 0) { |
| 1084 | + PFD0.Stats.DME.ETA = PFD0.Stats.DME.Distance / PFD0.Stats.Speed.GSDisplay * 1000; // (Meter / meter per sec) = sec, sec * 1000 = millisec. |
| 1085 | + } |
| 1086 | + break; |
| 1087 | + case "UseAvgGS": |
| 1088 | + if(PFD0.Stats.Speed.AvgGSDisplay > 0) { |
| 1089 | + PFD0.Stats.DME.ETA = PFD0.Stats.DME.Distance / PFD0.Stats.Speed.AvgGSDisplay * 1000; |
| 1090 | + } |
| 1091 | + break; |
| 1092 | + default: |
| 1093 | + AlertSystemError("The value of PFD.DME.ETACalcMethod \"" + PFD.DME.ETACalcMethod + "\" in function RefreshPFDData is invalid."); |
| 1094 | + break; |
1073 | 1095 | }
|
1074 | 1096 | }
|
1075 | 1097 |
|
|
1382 | 1404 | (PFD.Speed.Mode == "DualChannel" && (PFD0.Status.GPS.IsSpeedAvailable == true || PFD0.Status.IsAccelAvailable == true)) ||
|
1383 | 1405 | PFD.Speed.Mode == "Manual") {
|
1384 | 1406 | ChangeText("Label_PFDDefaultPanelGSValue", ConvertUnit(PFD0.Stats.Speed.GSDisplay, "MeterPerSec", Subsystem.I18n.SpeedUnit).toFixed(0));
|
| 1407 | + ChangeText("Label_PFDDefaultPanelAvgGSValue", ConvertUnit(PFD0.Stats.Speed.AvgGSDisplay, "MeterPerSec", Subsystem.I18n.SpeedUnit).toFixed(0)); |
1385 | 1408 | ChangeText("Label_PFDDefaultPanelTASValue", ConvertUnit(PFD0.Stats.Speed.TASDisplay, "MeterPerSec", Subsystem.I18n.SpeedUnit).toFixed(0));
|
1386 | 1409 | } else {
|
1387 | 1410 | ChangeText("Label_PFDDefaultPanelGSValue", "---");
|
| 1411 | + ChangeText("Label_PFDDefaultPanelAvgGSValue", "---"); |
1388 | 1412 | ChangeText("Label_PFDDefaultPanelTASValue", "---");
|
1389 | 1413 | }
|
1390 | 1414 | if(PFD.Speed.Wind.Speed > 0) {
|
|
2437 | 2461 | Show("Ctrl_SettingsAirportCoordinatesDeparture");
|
2438 | 2462 | Show("Ctrl_SettingsAirportCoordinatesArrival");
|
2439 | 2463 | Show("Ctrl_SettingsAirportCoordinatesSwap");
|
| 2464 | + Show("Label_SettingsETA"); |
| 2465 | + Show("Ctrl_SettingsETACalcMethod"); |
2440 | 2466 | ChangeValue("Textbox_SettingsAirportCoordinatesDepartureLat", PFD.DME.AirportCoordinates.Departure.Lat.toFixed(5));
|
2441 | 2467 | ChangeValue("Textbox_SettingsAirportCoordinatesDepartureLon", PFD.DME.AirportCoordinates.Departure.Lon.toFixed(5));
|
2442 | 2468 | ChangeValue("Textbox_SettingsAirportCoordinatesArrivalLat", PFD.DME.AirportCoordinates.Arrival.Lat.toFixed(5));
|
|
2446 | 2472 | } else {
|
2447 | 2473 | ChangeDisabled("Button_SettingsAirportCoordinatesSwap", true);
|
2448 | 2474 | }
|
| 2475 | + ChangeValue("Combobox_SettingsETACalcMethod", PFD.DME.ETACalcMethod); |
2449 | 2476 | } else {
|
2450 | 2477 | Hide("Label_SettingsAirportCoordinates");
|
2451 | 2478 | Hide("Label_SettingsAirportCoordinatesInfo");
|
2452 | 2479 | Hide("Ctrl_SettingsAirportCoordinatesDeparture");
|
2453 | 2480 | Hide("Ctrl_SettingsAirportCoordinatesArrival");
|
2454 | 2481 | Hide("Ctrl_SettingsAirportCoordinatesSwap");
|
| 2482 | + Hide("Label_SettingsETA"); |
| 2483 | + Hide("Ctrl_SettingsETACalcMethod"); |
2455 | 2484 | }
|
2456 | 2485 |
|
2457 | 2486 | // Flight mode
|
|
2634 | 2663 | // Timestamp
|
2635 | 2664 | PFD0.RawData.Accel.Timestamp = Date.now();
|
2636 | 2665 | }
|
| 2666 | + function ClockAvgGS() { |
| 2667 | + // Automation |
| 2668 | + clearTimeout(Automation.ClockAvgGS); |
| 2669 | + Automation.ClockAvgGS = setTimeout(ClockAvgGS, 20); |
| 2670 | + |
| 2671 | + // Main |
| 2672 | + PFD0.Stats.Speed.SampleCount++; |
| 2673 | + PFD0.Stats.Speed.AvgGS = (PFD0.Stats.Speed.AvgGS * (PFD0.Stats.Speed.SampleCount - 1) + PFD0.Stats.Speed.GS) / PFD0.Stats.Speed.SampleCount; |
| 2674 | + } |
2637 | 2675 |
|
2638 | 2676 | // Cmds
|
2639 | 2677 | // PFD
|
|
3089 | 3127 | PFD.DME.AirportCoordinates.Arrival = structuredClone(Swapper);
|
3090 | 3128 | RefreshPFD();
|
3091 | 3129 | }
|
| 3130 | + function SetETACalcMethod() { |
| 3131 | + PFD.DME.ETACalcMethod = ReadValue("Combobox_SettingsETACalcMethod"); |
| 3132 | + RefreshPFD(); |
| 3133 | + } |
3092 | 3134 |
|
3093 | 3135 | // Flight mode
|
3094 | 3136 | function SetFlightMode() {
|
|
0 commit comments