2 * Copyright (C) 2016 The LibrePilot Project
3 * Contact: http://www.librepilot.org
5 * This file is part of LibrePilot GCS.
7 * LibrePilot GCS is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
12 * LibrePilot GCS is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with LibrePilot GCS. If not, see <http://www.gnu.org/licenses/>.
21 // ***************************
22 // Common javascript uav utils
23 // ***************************
28 .import UAVTalk.VtolPathFollowerSettings 1.0 as VtolPathFollowerSettings
31 .import UAVTalk.HomeLocation 1.0 as HomeLocation
32 .import UAVTalk.TakeOffLocation 1.0 as TakeOffLocation
35 .import UAVTalk.FlightBatterySettings 1.0 as FlightBatterySettings
38 .import UAVTalk.RevoSettings 1.0 as RevoSettings
41 .import UAVTalk.HwSettings 1.0 as HwSettings
42 .import UAVTalk.SystemSettings 1.0 as SystemSettings
47 .import UAVTalk.FlightStatus 1.0 as FlightStatus
48 .import UAVTalk.ManualControlCommand 1.0 as ManualControlCommand
49 .import UAVTalk.StabilizationDesired 1.0 as StabilizationDesired
50 .import UAVTalk.VelocityDesired 1.0 as VelocityDesired
53 .import UAVTalk.PathDesired 1.0 as PathDesired
54 .import UAVTalk.WaypointActive 1.0 as WaypointActive
57 .import UAVTalk.FlightBatteryState 1.0 as FlightBatteryState
58 .import UAVTalk.GPSPositionSensor 1.0 as GPSPositionSensor
59 .import UAVTalk.GPSSatellites 1.0 as GPSSatellites
62 .import UAVTalk.AttitudeState 1.0 as AttitudeState
63 .import UAVTalk.MagState 1.0 as MagState
64 .import UAVTalk.NedAccel 1.0 as NedAccel
65 .import UAVTalk.PositionState 1.0 as PositionState
66 .import UAVTalk.VelocityState 1.0 as VelocityState
69 .import UAVTalk.OPLinkStatus 1.0 as OPLinkStatus
70 .import UAVTalk.ReceiverStatus 1.0 as ReceiverStatus
71 .import UAVTalk.SystemAlarms 1.0 as SystemAlarms
73 Qt.include("common.js")
84 return Qt.vector3d(attitudeState.roll, attitudeState.pitch, attitudeState.yaw);
87 function attitudeRoll() {
88 return attitudeState.roll;
91 function attitudePitch() {
92 return attitudeState.pitch;
95 function attitudeYaw() {
96 return attitudeState.yaw;
99 function currentVelocity() {
100 return Math.sqrt(Math.pow(velocityState.north, 2) + Math.pow(velocityState.east, 2));
103 function positionStateDown() {
104 return positionState.down;
107 function velocityStateDown() {
108 return velocityState.down;
111 function nedAccelDown() {
112 return nedAccel.down;
115 function position() {
116 switch(gpsPositionSensor.status) {
117 case GPSPositionSensor.Status.Fix2D:
118 case GPSPositionSensor.Status.Fix3D:
119 return gpsPosition();
120 case GPSPositionSensor.Status.NoFix:
121 case GPSPositionSensor.Status.NoGPS:
123 return (homeLocation.set == HomeLocation.Set.True) ? homePosition() : defaultPosition();
127 function gpsPosition() {
129 gpsPositionSensor.longitude / 10000000.0,
130 gpsPositionSensor.latitude / 10000000.0,
131 gpsPositionSensor.altitude);
134 function homePosition() {
136 homeLocation.longitude / 10000000.0,
137 homeLocation.latitude / 10000000.0,
138 homeLocation.altitude);
141 function defaultPosition() {
142 return Qt.vector3d(pfdContext.longitude, pfdContext.latitude, pfdContext.altitude);
150 // Hack: detect Coptercontrol with mem free
151 return (freeMemoryBytes() < 3096);
154 function frameType() {
155 return ["FixedWing", "FixedWingElevon", "FixedWingVtail", "VTOL", "HeliCP", "QuadX", "QuadP",
156 "Hexa+", "Octo+", "Custom", "HexaX", "HexaH", "OctoV", "OctoCoaxP", "OctoCoaxX", "OctoX", "HexaCoax",
157 "Tricopter", "GroundVehicleCar", "GroundVehicleDiff", "GroundVehicleMoto"][systemSettings.airframeType]
160 function isVtolOrMultirotor() {
161 return ((systemSettings.airframeType > SystemSettings.AirframeType.FixedWingVtail) &&
162 (systemSettings.airframeType < SystemSettings.AirframeType.GroundVehicleCar));
165 function isFixedWing() {
166 return (systemSettings.airframeType <= SystemSettings.AirframeType.FixedWingVtail);
169 function isGroundVehicle() {
170 return (systemSettings.airframeType >= SystemSettings.AirframeType.GroundVehicleCar);
173 function freeMemoryBytes() {
174 return systemStats.heapRemaining;
177 function freeMemoryKBytes() {
178 return (systemStats.heapRemaining / 1024).toFixed(2);
181 function freeMemory() {
182 return (freeMemoryBytes() > 1024) ? freeMemoryKBytes() + "Kb" : freeMemoryBytes() + "bytes";
186 return systemStats.cpuLoad;
190 return systemStats.cpuTemp;
193 function flightTimeValue() {
194 return Math.round(systemStats.flightTime / 1000)
201 function isAttitudeValid() {
202 return (systemAlarms.alarmAttitude == SystemAlarms.Alarm.OK);
205 function isAttitudeNotInitialised() {
206 return (systemAlarms.alarmAttitude == SystemAlarms.Alarm.Uninitialised);
209 function isGpsValid() {
210 return (systemAlarms.alarmGPS == SystemAlarms.Alarm.OK);
213 function isGpsNotInitialised() {
214 return (systemAlarms.alarmGPS == SystemAlarms.Alarm.Uninitialised);
217 function isGpsStatusFix3D() {
218 return (gpsPositionSensor.status == GPSPositionSensor.Status.Fix3D);
221 function isOplmConnected() {
222 return (opLinkStatus.linkState == OPLinkStatus.LinkState.Connected);
225 function magSourceName() {
226 return [magState.source == MagState.Source.Aux ? ["GPSv9", "Flexi", "I2C", "DJI"][auxMagSettings.type] + " " : ""] +
227 ["Invalid", "OnBoard", "ExtMag"][magState.source];
230 function gpsSensorType() {
231 return ["Unknown", "NMEA", "UBX", "UBX7", "UBX8", "DJI"][gpsPositionSensor.sensorType]
234 function gpsNumSat() {
235 return gpsPositionSensor.satellites;
238 function gpsSatsInView() {
239 return gpsSatellites.satsInView;
242 function gpsHdopInfo() {
243 return gpsPositionSensor.hdop.toFixed(2) + "/" + gpsPositionSensor.vdop.toFixed(2) + "/" + gpsPositionSensor.pdop.toFixed(2);
246 function gpsAltitude() {
247 return gpsPositionSensor.altitude.toFixed(2);
250 function gpsStatus() {
251 return ["NO GPS", "NO FIX", "2D", "3D"][gpsPositionSensor.status];
254 function fusionAlgorithm() {
255 return ["None", "Basic (No Nav)", "CompMag", "Comp+Mag+GPS", "EKFIndoor", "GPSNav (INS13)"][revoSettings.fusionAlgorithm];
258 function receiverQuality() {
259 return (receiverStatus.quality > 0) ? receiverStatus.quality + "%" : "?? %";
262 function oplmLinkState() {
263 return ["Disabled", "Enabled", "Disconnected", "Connecting", "Connected"][opLinkStatus.linkState];
270 function batteryModuleEnabled() {
271 return (hwSettings.optionalModulesBattery == HwSettings.OptionalModules.Enabled);
274 function batteryNbCells() {
275 return flightBatterySettings.nbCells;
278 function batteryVoltage() {
279 return flightBatteryState.voltage.toFixed(2);
282 function batteryCurrent() {
283 return flightBatteryState.current.toFixed(2);
286 function batteryConsumedEnergy() {
287 return flightBatteryState.consumedEnergy.toFixed(0);
290 function estimatedFlightTimeValue() {
291 return Math.round(flightBatteryState.estimatedFlightTime);
294 function batteryAlarmColor() {
295 // Uninitialised, Ok, Warning, Critical, Error
296 return ["#2c2929", "green", "orange", "red", "red"][systemAlarms.alarmBattery];
299 function estimatedTimeAlarmColor() {
300 return ((estimatedFlightTimeValue() <= 120) && (estimatedFlightTimeValue() > 60)) ? "orange" :
301 (estimatedFlightTimeValue() <= 60) ? "red" : batteryAlarmColor();
305 * Pathplan and Waypoints
308 function isPathPlanValid() {
309 return (systemAlarms.alarmPathPlan == SystemAlarms.Alarm.OK);
312 function isPathDesiredActive() {
313 return ((pathDesired.endEast != 0.0) || (pathDesired.endNorth != 0.0) || (pathDesired.endingVelocity != 0.0))
316 function isTakeOffLocationValid() {
317 return (takeOffLocation.status == TakeOffLocation.Status.Valid);
320 function pathModeDesired() {
321 return ["GOTO ENDPOINT","FOLLOW VECTOR","CIRCLE RIGHT","CIRCLE LEFT","FIXED ATTITUDE",
322 "SET ACCESSORY","DISARM ALARM","LAND","BRAKE","VELOCITY","AUTO TAKEOFF"][pathDesired.mode]
325 function velocityDesiredDown() {
326 return velocityDesired.down;
329 function pathDesiredEndDown() {
330 return pathDesired.endDown;
333 function pathDesiredEndingVelocity() {
334 return pathDesired.endingVelocity;
337 function currentWaypointActive() {
338 return (waypointActive.index + 1);
341 function waypointCount() {
342 return pathPlan.waypointCount;
345 function homeHeading() {
346 return 180 / 3.1415 * Math.atan2(takeOffLocation.east - positionState.east, takeOffLocation.north - positionState.north);
349 function waypointHeading() {
350 return 180 / 3.1415 * Math.atan2(pathDesired.endEast - positionState.east, pathDesired.endNorth - positionState.north);
353 function homeDistance() {
354 return Math.sqrt(Math.pow((takeOffLocation.east - positionState.east), 2) +
355 Math.pow((takeOffLocation.north - positionState.north), 2));
358 function waypointDistance() {
359 return Math.sqrt(Math.pow((pathDesired.endEast - positionState.east), 2) +
360 Math.pow((pathDesired.endNorth - positionState.north), 2));
364 * FlightModes, Stabilization, Thrust modes
367 function isFlightModeManual() {
368 return (flightStatus.flightMode == FlightStatus.FlightMode.Manual);
371 function isFlightModeAssisted() {
372 return (flightStatus.flightMode > FlightStatus.FlightMode.Stabilized6);
375 function isVtolPathFollowerSettingsThrustAuto() {
376 return (vtolPathFollowerSettings.thrustControl == VtolPathFollowerSettings.ThrustControl.Auto);
379 function flightModeName() {
380 return ["MANUAL", "STAB 1", "STAB 2", "STAB 3", "STAB 4", "STAB 5", "STAB 6",
381 "POS HOLD", "COURSELOCK", "VEL ROAM", "HOME LEASH", "ABS POS", "RTB",
382 "LAND", "PATHPLAN", "POI", "AUTOCRUISE", "AUTOTAKEOFF"][flightStatus.flightMode];
385 function flightModeColor() {
386 return ["gray", "green", "green", "green", "green", "green", "green",
387 "cyan", "cyan", "cyan", "cyan", "cyan", "cyan",
388 "cyan", "cyan", "cyan", "cyan", "cyan"][flightStatus.flightMode];
391 function thrustMode() {
392 return !isFlightModeAssisted() ? stabilizationDesired.stabilizationModeThrust :
393 (isFlightModeAssisted() && isVtolOrMultirotor() && isVtolPathFollowerSettingsThrustAuto()) ?
394 StabilizationDesired.StabilizationDesiredConstants.StabilizationModeCount : (isFlightModeAssisted() && isFixedWing()) ?
395 StabilizationDesired.StabilizationDesiredConstants.StabilizationModeCount : 0;
398 function thrustModeName() {
399 // Last "Auto" Thrust mode is added to UAVO enum list
400 // Lower case modes are never displayed/used for Thrust
401 return ["MANUAL", "rate", "ratetrainer", "attitude", "axislock", "weakleveling", "virtualbar", "acro+ ", "rattitude",
402 "ALT HOLD", "ALT VARIO", "CRUISECTRL", "AUTO"][thrustMode()]
405 function thrustModeColor() {
406 return ["green", "grey", "grey", "grey", "grey", "grey", "grey", "grey", "grey",
407 "green", "green", "green", "cyan"][thrustMode()];
410 function armStatusName() {
411 return ["DISARMED","ARMING","ARMED"][flightStatus.armed];
414 function armStatusColor() {
415 return ["gray", "orange", "green"][flightStatus.armed];
422 function autopilotStatusColor() {
423 return statusColor(systemAlarms.alarmGuidance)
426 function rcInputStatusColor() {
427 return statusColor(systemAlarms.alarmManualControl)
430 function statusColor(module) {
431 return ["gray", "green", "red", "red", "red"][module];
434 function masterCautionWarning() {
435 return ((systemAlarms.alarmBootFault > SystemAlarms.Alarm.OK) ||
436 (systemAlarms.alarmOutOfMemory > SystemAlarms.Alarm.OK) ||
437 (systemAlarms.alarmStackOverflow > SystemAlarms.Alarm.OK) ||
438 (systemAlarms.alarmCPUOverload > SystemAlarms.Alarm.OK) ||
439 (systemAlarms.alarmEventSystem > SystemAlarms.Alarm.OK))