Merge pull request #1 from iNavFlight/master

Bump local repo
pull/1032/head
Daniel Ribeiro 5 years ago committed by GitHub
commit 16dc59f44f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -26,6 +26,14 @@ Depending on target operating system, _INAV Configurator_ is distributed as _sta
1. Run INAV Configurator app from unpacked folder
1. Configurator is not signed, so you have to allow Windows to run untrusted application. There might be a monit for it during first run
### Linux
1. Visit [release page](https://github.com/iNavFlight/inav-configurator/releases)
1. Download Configurator for Linux platform (linux32 and linux64 are present)
1. Extract tar.gz archive
1. Make the inav-configurator file executable (chmod +x inav-configurator)
1. Run INAV Configurator app from unpacked folder
### Mac
1. Visit [release page](https://github.com/iNavFlight/inav-configurator/releases)
@ -46,7 +54,7 @@ For local development, **node.js** build system is used.
1. From project folder run `npm install`
1. To build the JS and CSS files and start the configurator:
- With NW.js: Run `npm start`.
- With Chrome: Run `./node_modules/gulp/bin/gulp.js`. Then open `chrome://extensions`, enable
- With Chrome: Run `npm run gulp`. Then open `chrome://extensions`, enable
the `Developer mode`, click on the `Load unpacked extension...` button and select the `inav-configurator` directory.
Other tasks are also defined in `gulpfile.js`. To run a task, use `./node_modules/gulp/bin/gulp.js task-name`. Available ones are:
@ -119,7 +127,7 @@ GitHub issue tracker is reserved for bugs and other technical problems. If you d
everything, hardware is not working or have any other _support_ problem, please consult:
* [rcgroups main thread](https://www.rcgroups.com/forums/showthread.php?2495732-Cleanflight-iNav-(navigation-rewrite)-project)
* [Slack channel](https://inavflight.signup.team/)
* [Telegram Group](https://t.me/INAVFlight)
## Issue trackers

@ -101,8 +101,8 @@
"tabGPS": {
"message": "GPS"
},
"tabMotorTesting": {
"message": "Motors"
"tabOutputs": {
"message": "Outputs"
},
"tabLedStrip": {
"message": "LED Strip"
@ -159,7 +159,7 @@
"message": "No configuration received within <span style=\"color: red\">10 seconds</span>, communication <span style=\"color: red\">failed</span>"
},
"firmwareVersionNotSupported": {
"message": "This firmware version is <span style=\"color: red\">not supported</span>. Please upgrade to firmware that supports api version <strong>$1</strong> or higher. Use CLI for backup before flashing. CLI backup/restore procedure is in the documention."
"message": "This firmware version is <span style=\"color: red\">not supported</span>. This version of Configurator supports firmware from $1 to $2 (excluded)"
},
"firmwareVariantNotSupported": {
"message": "This firmware variant is <span style=\"color: red\">not supported</span>. Please upgrade to INAV firmware. Use CLI for backup before flashing. CLI backup/restore procedure is in the documention."
@ -245,7 +245,7 @@
},
"defaultWelcomeText": {
"message": "The application supports all hardware that can run INAV (<a href=\"http://www.multiwiicopter.com/products/inav-air3-fixed-wing\" target=\"_blank\">Sirius AIR3</a>, <a href=\"http://seriouslypro.com/spracingf3\" target=\"_blank\">SPRacingF3</a>, <a href=\"http://www.immersionrc.com/fpv-products/vortex-racing-quad/\" target=\"_blank\">Vortex</a>, <a href=\"https://github.com/TauLabs/TauLabs/wiki/Sparky\" target=\"_blank\">Sparky</a>, <a href=\"http://www.readymaderc.com/store/index.php?main_page=product_info&cPath=76_156&products_id=4221\" target=\"_blank\">DoDo</a>, <a href=\"https://www.openpilot.org/product/coptercontrol/\" target=\"_blank\">CC3D/EVO</a>, <a href=\"http://www.readytoflyquads.com/flight-controllers/flip-series\" target=\"_blank\">Flip32/+/Deluxe</a>, <a href=\"http://multirotormania.com/129-dragonfly32\" target=\"_blank\">DragonFly32</a>, <a href=\"http://www.goodluckbuy.com/micro-quadcopter-flight-driver-controller-9dof-9-axis-altitude-sensor-stm32f103.html\" target=\"_blank\">CJMCU Microquad</a>, Chebuzz F3, <a href=\"http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/PF254044\" target=\"_blank\">STM32F3Discovery</a>, <a href=\"http://www.overskyrc.com/hermit-micro-fpv-brushless-quadcopter-145mm-98g-fully-assembled-p-621.html\" target=\"_blank\">Hermit</a>, <a href=\"http://rcexplorer.se/blog/2015/05/introducing-the-naze32-tricopter-frame/\" target=\"_blank\">Naze32 Tricopter Frame</a>, <a href=\"http://www.2dogrc.com/skyline-32-naze-32-bit-flight-controller-acro-version.html\" target=\"_blank\">Skyline32</a>, <a href=\"http://abusemark.com/store/index.php?main_page=index&cPath=1\" target=\"_blank\">Naze/32/Mini/Pro</a>/<a href=\"http://www.massiverc.com/Shop/en/574-massive-acro-blackbox-flight-control-board.html\" target=\"_blank\">Blackbox</a> etc)<br /><br />The firmware source code can be downloaded from <a href=\"https://github.com/iNavFlight\" title=\"www.github.com\" target=\"_blank\">here</a><br />The newest binary firmware image is available <a href=\"https://github.com/iNavFlight/inav/releases\" title=\"www.github.com\" target=\"_blank\">here</a>.<br /><br />Latest <strong>CP210x Drivers</strong> can be downloaded from <a href=\"http://www.silabs.com/products/mcu/pages/usbtouartbridgevcpdrivers.aspx\" title=\"http://www.silabs.com\" target=\"_blank\">here</a><br />Latest <strong>STM USB VCP Drivers</strong> can be downloaded from <a href=\"http://www.st.com/web/en/catalog/tools/PF257938\" title=\"http://www.st.com\" target=\"_blank\">here</a><br />Latest <strong>Zadig</strong> for Windows DFU flashing can be downloaded from <a href=\"http://zadig.akeo.ie/\" title=\"http://zadig.akeo.ie\" target=\"_blank\">here</a><br />"
"message": "The application supports all hardware that can run INAV (<a href=\"https://inavflight.com/shop/p/MATEKF405WING\" target=\"_blank\">Matek F405-WING</a>, <a href=\"https://inavflight.com/shop/p/MATEKF722SE\" target=\"_blank\">Matek F722-SE</a> and many other). The full list of recommended hardware is available <a href=\"https://github.com/iNavFlight/inav/wiki/Welcome-to-INAV,-useful-links-and-products\" target=\"_blank\">here</a>.<br /><br />The firmware source code can be downloaded from <a href=\"https://github.com/iNavFlight\" title=\"www.github.com\" target=\"_blank\">here</a><br />The newest binary firmware image is available <a href=\"https://github.com/iNavFlight/inav/releases\" title=\"www.github.com\" target=\"_blank\">here</a>.<br /><br />Latest <strong>CP210x Drivers</strong> can be downloaded from <a href=\"http://www.silabs.com/products/mcu/pages/usbtouartbridgevcpdrivers.aspx\" title=\"http://www.silabs.com\" target=\"_blank\">here</a><br />Latest <strong>STM USB VCP Drivers</strong> can be downloaded from <a href=\"http://www.st.com/web/en/catalog/tools/PF257938\" title=\"http://www.st.com\" target=\"_blank\">here</a><br />Latest <strong>Zadig</strong> for Windows DFU flashing can be downloaded from <a href=\"http://zadig.akeo.ie/\" title=\"http://zadig.akeo.ie\" target=\"_blank\">here</a><br />"
},
"defaultContributingHead": {
"message": "Contributing"
@ -268,45 +268,6 @@
"defaultSponsorsHead": {
"message": "Sponsors"
},
"defaultDocumentationHead": {
"message": "Documentation / Manual"
},
"defaultDocumentation": {
"message": "INAV documentation is available in Markdown format.<br /><br />"
},
"defaultDocumentation1": {
"message": "The PDF manual appropriate to the firmware can be downloaded from the github releases page, <a href=\"https://github.com/iNavFlight/inav/releases\" target=\"_blank\">here</a>."
},
"defaultDocumentation2": {
"message": "The Markdown latest online documentation is available <a href=\"https://github.com/iNavFlight/inav/tree/master/docs\" target=\"_blank\">here</a> - you can switch to the appropriate version of the documentation by selecting the tag."
},
"defaultSupportHead": {
"message": "Support"
},
"defaultSupportSubline1": {
"message": "Support Scources"
},
"defaultSupportSubline2": {
"message": "Developer"
},
"defaultSupport": {
"message": "For support please search the forums first or contact your vendor.<br /><br />"
},
"defaultSupport1": {
"message": "<a href=\"http://www.rcgroups.com/forums/showthread.php?t=2249574&page=1\" target=\"_blank\">RC Groups thread</a>"
},
"defaultSupport2": {
"message": "<a href=\"http://www.multiwii.com/forum/viewtopic.php?f=23&t=5149\" target=\"_blank\">MultiWii forums thread</a>"
},
"defaultSupport3": {
"message": "<a href=\"https://github.com/iNavFlight\" target=\"_blank\">GitHub</a>"
},
"defaultSupport4": {
"message": "<a href=\"https://gitter.im/iNavFlight/inav\" target=\"_blank\">Gitter channel</a>"
},
"defaultSupport5": {
"message": "<a href=\"https://gitter.im/iNavFlight/inav\" target=\"_blank\">Join via WebClient</a>"
},
"communityRCGroupsSupport": {
"message": "RC Groups Support"
},
@ -502,6 +463,12 @@
"initialSetupMagCalibEnded": {
"message": "Magnetometer calibration <span style=\"color: #37a8db\">finished</span>"
},
"initialSetupOpflowCalibStarted": {
"message": "Optic flow calibration started"
},
"initialSetupOpflowCalibEnded": {
"message": "Optic flow calibration <span style=\"color: #37a8db\">finished</span>"
},
"initialSetupSettingsRestored": {
"message": "Settings restored to <strong>default</strong>"
},
@ -538,7 +505,7 @@
"message": "In-flight level calibration"
},
"featureMOTOR_STOP": {
"message": "Don't spin the motors when armed"
"message": "Stop motors on low throttle"
},
"featureSERVO_TILT": {
"message": "Servo gimbal"
@ -579,8 +546,8 @@
"featureCURRENT_METER": {
"message": "Battery current monitoring"
},
"feature3D": {
"message": "3D mode (for use with reversible ESCs)"
"featureREVERSIBLE_MOTORS": {
"message": "Reversible motors mode (for use with reversible ESCs)"
},
"featureRSSI_ADC": {
"message": "Analog RSSI input"
@ -639,6 +606,12 @@
"featureFW_LAUNCH": {
"message": "Permanently enable Launch Mode for Fixed Wing"
},
"featureDYNAMIC_FILTERS": {
"message": "Dynamic Gyro Filters"
},
"featureDYNAMIC_FILTERSTip": {
"message": "Use automatic FFT gyro analysis to setup notch filters to attenuate gyro noise. Should be enabled all the time!"
},
"configurationFeatureEnabled": {
"message": "Enabled"
},
@ -663,11 +636,17 @@
"configurationEscFeatures": {
"message": "ESC/Motor Features"
},
"serialrx_inverted": {
"message": "Serial Port Inverted (comparing to protocol default)"
},
"serialrx_halfduplex" : {
"message": "Serial receiver half-duplex"
},
"configurationFeaturesHelp": {
"message": "<strong>Note:</strong> Not all combinations of features are valid. When the flight controller firmware detects invalid feature combinations conflicting features will be disabled.<br /><strong>Note:</strong> Configure serial ports <span style=\"color: red\">before</span> enabling the features that will use the ports."
},
"configurationSerialRXHelp": {
"message": "<strong>Note:</strong> Remember to configure a Serial Port (via Ports tab) and choose a Serial Receiver Provider when using RX_SERIAL feature."
"message": "<strong>Note:</strong> Remember to configure a Serial Port (via Ports tab) for the serial receiver"
},
"configurationBoardAlignment": {
"message": "Board and Sensor Alignment"
@ -681,12 +660,6 @@
"configurationBoardAlignmentYaw": {
"message": "Yaw Degrees"
},
"configurationSensorAlignmentGyro": {
"message": "GYRO Alignment"
},
"configurationSensorAlignmentAcc": {
"message": "ACCEL Alignment"
},
"configurationSensorAlignmentMag": {
"message": "MAG Alignment"
},
@ -775,28 +748,28 @@
"message": "Capacity"
},
"configurationBatteryCapacityWarning": {
"message": "Warning Capacity (%)"
"message": "Warning Capacity (remaining %)"
},
"configurationBatteryCapacityCritical": {
"message": "Critical Capacity (%)"
"message": "Critical Capacity (remaining %)"
},
"configurationBatteryCapacityUnit": {
"message": "Battery Capacity Unit"
},
"configuration3d": {
"message": "3D"
"message": "Reversible motors"
},
"configuration3dDeadbandLow": {
"message": "3D Deadband Low"
"message": "Reversible Motors Deadband Low"
},
"configuration3dDeadbandHigh": {
"message": "3D Deadband High"
"message": "Reversible Motors Deadband High"
},
"configuration3dNeutral": {
"message": "3D Neutral"
"message": "Reversible Motors Neutral"
},
"configuration3dDeadbandThrottle": {
"message": "3D Deadband Throttle"
"message": "Reversible Motors Deadband Throttle"
},
"configurationSystem": {
"message": "System configuration"
@ -822,6 +795,9 @@
"configurationGPSHelp": {
"message": "<strong>Note:</strong> Remember to configure a Serial Port (via Ports tab) when using GPS feature."
},
"receiverType": {
"message": "Receiver type"
},
"configurationSerialRX": {
"message": "Serial Receiver Provider"
},
@ -886,7 +862,7 @@
"message": "<strong>Note:</strong> Do <span style=\"color: red\">NOT</span> disable MSP on the first serial port unless you know what you are doing. You may have to reflash and erase your configuration if you do."
},
"portsFirmwareUpgradeRequired": {
"message": "Firmware upgrade <span style=\"color: red\">required</span>. Serial port configurations of firmware &lt; 1.8.0 is not supported."
"message": "Firmware upgrade <span style=\"color: red\">required</span>."
},
"portsButtonSave": {
"message": "Save and Reboot"
@ -903,6 +879,12 @@
"portsFunction_RANGEFINDER": {
"message": "Rangefinder"
},
"portsFunction_OPFLOW": {
"message": "Optic flow"
},
"portsFunction_ESC": {
"message": "ESC output/telemetry"
},
"portsFunction_TELEMETRY_FRSKY": {
"message": "FrSky"
},
@ -918,6 +900,9 @@
"portsFunction_TELEMETRY_IBUS": {
"message": "IBUS"
},
"portsFunction_GSM_SMS": {
"message": "GSM SMS"
},
"portsFunction_TELEMETRY_MSP": {
"message": "MSP"
},
@ -939,6 +924,15 @@
"portsFunction_IRC_TRAMP": {
"message": "IRC Tramp"
},
"portsFunction_VTX_FFPV": {
"message": "FuriousFPV Vtx"
},
"portsFunction_FRSKY_OSD": {
"message": "FrSky OSD"
},
"portsFunction_DJI_FPV": {
"message": "DJI FPV VTX"
},
"pidTuningName": {
"message": "Name"
},
@ -951,6 +945,15 @@
"pidTuningDerivative": {
"message": "Derivative"
},
"pidTuningFeedForward": {
"message": "FeedForward"
},
"dtermSetpointWeight": {
"message": "Dterm setpoint weight"
},
"dtermSetpointWeightHelp": {
"message": "The lower the value, the more damped all the maneuvers are. 0 mean Dterm is computed from gyro, 1 from error and 2 from setpoint. For gentler feel lower the value. For sharper response, raise it"
},
"pidTuningRollPitchRate": {
"message": "ROLL &amp; PITCH rate"
},
@ -991,7 +994,7 @@
"message": "Maximum YAW rotation rate that MagHold controller can request from UAV. Used only when MagHold mode is enabled, during RTH and WAYPOINT navigation. Values below 30dps gives nice \"cinematic\" turns"
},
"pidTuningTPA": {
"message": "TPA"
"message": "Thrust PID Attenuation (TPA)"
},
"pidTuningTPABreakPoint": {
"message": "TPA Breakpoint"
@ -1246,25 +1249,58 @@
"message": "Board Pitch Alignment Adjustment"
},
"adjustmentsFunction32": {
"message": "PosR D Adjustment"
"message": "Level P Adjustment"
},
"adjustmentsFunction33": {
"message": "NavR P Adjustment"
"message": "Level I Adjustment"
},
"adjustmentsFunction34": {
"message": "NavR I Adjustment"
"message": "Level D Adjustment"
},
"adjustmentsFunction35": {
"message": "NavR D Adjustment"
"message": "Pos XY P Adjustment"
},
"adjustmentsFunction36": {
"message": "Level P Adjustment"
"message": "Pos XY I Adjustment"
},
"adjustmentsFunction37": {
"message": "Level I Adjustment"
"message": "Pos XY D Adjustment"
},
"adjustmentsFunction38": {
"message": "Level D Adjustment"
"message": "Pos Z P Adjustment"
},
"adjustmentsFunction39": {
"message": "Pos Z I Adjustment"
},
"adjustmentsFunction40": {
"message": "Pos Z D Adjustment"
},
"adjustmentsFunction41": {
"message": "Heading P Adjustment"
},
"adjustmentsFunction42": {
"message": "Vel XY P Adjustment"
},
"adjustmentsFunction43": {
"message": "Vel XY I Adjustment"
},
"adjustmentsFunction44": {
"message": "Vel XY D Adjustment"
},
"adjustmentsFunction45": {
"message": "Vel Z P Adjustment"
},
"adjustmentsFunction46": {
"message": "Vel Z I Adjustment"
},
"adjustmentsFunction47": {
"message": "Vel Z D Adjustment"
},
"adjustmentsFunction48": {
"message": "FW min thr down pitch angle Adjustment"
},
"adjustmentsFunction49": {
"message": "VTX power level Adjustment"
},
"adjustmentsSave": {
"message": "Save"
@ -1411,7 +1447,12 @@
"gpsSignalStr": {
"message": "Signal Strength"
},
"motors": {
"message": "Motors"
},
"servos": {
"message": "Servos"
},
"motorsMaster": {
"message": "Master"
},
@ -1459,6 +1500,24 @@
"cliClearOutputHistoryBtn": {
"message": "Clear output history"
},
"cliCopyToClipboardBtn": {
"message": "Copy to clipboard"
},
"cliCopySuccessful": {
"message": "Copied!"
},
"cliLoadFromFileBtn": {
"message": "Load from file"
},
"cliConfirmSnippetDialogTitle": {
"message": "Review loaded commands"
},
"cliConfirmSnippetNote": {
"message": "<strong>Note</strong>: You can review and edit commands before execution."
},
"cliConfirmSnippetBtn": {
"message": "Execute"
},
"loggingNote": {
"message": "Data will be logged in this tab <span style=\"color: red\">only</span>, leaving the tab will <span style=\"color: red\">cancel</span> logging and application will return to its normal <strong>\"configurator\"</strong> state.<br /> You are free to select the global update period, data will be written into the log file every <strong>1</strong> second for performance reasons."
@ -1493,12 +1552,8 @@
"loggingAutomaticallyRetained": {
"message": "Automatically loaded previous log file: <strong>$1</strong>"
},
"blackboxNotSupported": {
"message": "Your flight controller's firmware does not support Blackbox logging."
},
"blackboxMaybeSupported": {
"message": "Your flight controller's firmware is too old to support this tab, or the Blackbox feature is disabled on the Configuration tab."
"message": "Your flight controller's firmware does not support Blackbox logging or Blackbox feature is not enabled"
},
"blackboxConfiguration": {
"message": "Blackbox configuration"
@ -1790,7 +1845,7 @@
"message": "Failsafe Throttle"
},
"failsafeFeaturesHelpNew": {
"message": "Failsafe has two stages. <strong>Stage 1</strong> is entered when a flightchannel has an invalid pulse length, the receiver reports failsafe mode or there is no signal from the receiver at all, the channel fallback settings are applied to <span style=\"color: red\">all channels</span> and a short amount of time is provided to allow for recovery. <strong>Stage 2</strong> is entered when the error condition takes longer than the configured guard time while the craft is <span style=\"color: red\">armed</span>, all channels will remain at the applied channel fallback setting unless overruled by the chosen procedure. <br /><strong>Note:</strong> Prior to entering stage 1, channel fallback settings are also applied to individual radio channels that have invalid pulses."
"message": "Failsafe has two stages. <strong>Stage 1</strong> is entered when a flightchannel has an invalid pulse duration, the receiver reports failsafe mode or there is no signal from the receiver at all, the channel fallback settings are applied to <span style=\"color: red\">all channels</span> and a short amount of time is provided to allow for recovery. <strong>Stage 2</strong> is entered when the error condition takes longer than the configured guard time while the craft is <span style=\"color: red\">armed</span>, all channels will remain at the applied channel fallback setting unless overruled by the chosen procedure. <br /><strong>Note:</strong> Prior to entering stage 1, channel fallback settings are also applied to individual radio channels that have invalid pulses."
},
"failsafePulsrangeTitle": {
"message": "Valid Pulse Range Settings"
@ -1799,10 +1854,10 @@
"message": "Pulses shorter than minimum or longer than maximum are invalid and will trigger application of individual channel fallback settings for radio channels or entering stage 1 for flightchannels"
},
"failsafeRxMinUsecItem": {
"message": "Minimum length"
"message": "Minimum duration"
},
"failsafeRxMaxUsecItem": {
"message": "Maximum length"
"message": "Maximum duration"
},
"failsafeChannelFallbackSettingsTitle": {
"message": "Channel Fallback Settings"
@ -1891,9 +1946,6 @@
"warning": {
"message": "Warning"
},
"boardLimitedFunctionality": {
"message": "Due to limited flash size, the board you have selected will have limited functionality, not all functions and features will be available. Hardware support map is available on <a href=\"https://github.com/iNavFlight/inav/wiki/Hardware-support-map\" target=\"_blank\">INAV Wiki pages</a>"
},
"escProtocol": {
"message": "ESC protocol"
},
@ -1913,7 +1965,7 @@
"message" : "Servo has to support refresh rate. Change only if you know that servo supports it. Too high refresh rate might damage servos!"
},
"logPwmOutputDisabled": {
"message" : "PWM output is disabled. Motors and servos will not work. Use <u>Configuration</u> tab to enable!"
"message" : "PWM output is disabled. Motors and servos will not work. Use <u>Outputs</u> tab to enable!"
},
"configurationGyroSyncTitle": {
"message" : "Synchronize looptime with gyroscope"
@ -2095,6 +2147,15 @@
"calibrationHead4": {
"message": "Compass Calibration"
},
"calibrationHead5": {
"message": "Optic Flow Calibration"
},
"OpflowCalText": {
"message": "After pressing the button you have 30 seconds to hold the copter in the air and tilt it to sides without moving it horizontally. Note that optic flow sensor needs to observe the surface at all times."
},
"OpflowCalBtn": {
"message": "Calibrate Optic Flow sensor"
},
"accZero": {
"message": "Acc Zero"
},
@ -2144,7 +2205,7 @@
"message": "Warning"
},
"presetApplyDescription": {
"message": "Preset overwrites selected configuration values including mixer, filtering, PIDs and other. Settings like: flight modes, radio settings, failsafe and OSD are not changed. Applied values should <strong>NOT</strong> treated as final values, but entry points for final tuning. <br> Always check new configuration before flying!"
"message": "<p style='color: darkred;'>Make sure that <strong>mixer</strong> was configured before applying any Presets!</p><p>Preset overwrites selected configuration values including mixer, filtering, PIDs and other. Settings like: flight modes, radio settings, failsafe and OSD are not changed. Applied values should <strong>NOT</strong> treated as final values, but entry points for final tuning. <br> Always check new configuration before flying!</p>"
},
"OK": {
"message": "OK"
@ -2246,25 +2307,25 @@
"message": "Position Estimator"
},
"w_z_baro_p": {
"message": "Vertical Position Baro Weight"
"message": "Vertical position barometer weight"
},
"w_z_gps_p": {
"message": "Vertical Position GPS Weight"
"message": "Vertical position GPS weight"
},
"w_z_gps_v": {
"message": "Vertical Speed GPS Weight"
"message": "Vertical speed GPS weight"
},
"w_xy_gps_p": {
"message": "Horizontal Position GPS Weight"
"message": "Horizontal position GPS weight"
},
"w_xy_gps_v": {
"message": "Horizontal Speed GPS Weight"
"message": "Horizontal speed GPS weight"
},
"positionEstimatorConfigurationDisclaimer": {
"message": "Those value should be changed very carefully. In most cases there is not need to change them. For advanced users only!"
"message": "This value should be changed very carefully. In most cases there is not need to change that. For advanced users only!"
},
"gps_min_sats": {
"message": "Min. GPS sats for valid fix"
"message": "Min. GPS satellites for a valid fix"
},
"use_gps_velned": {
"message": "Use GPS data for velocity calculation"
@ -2288,13 +2349,13 @@
"message": "Min. RTH distance [cm]"
},
"minRthDistanceHelp": {
"message": "If UAV is within this distance from Home Point, it will execute Land instead of RTH and Land"
"message": "If UAV is within this distance from the home point, it will land instead of RTH then land"
},
"rthClimbFirst": {
"message": "Climb before RTH"
},
"rthClimbIgnoreEmergency": {
"message": "Climb regardless of position sensor health"
"message": "Climb regardless of position sensors health"
},
"rthTailFirst": {
"message": "Tail first"
@ -2303,16 +2364,16 @@
"message": "Land after RTH"
},
"rthAltControlMode": {
"message": "RTH Altitude mode"
"message": "RTH altitude mode"
},
"rthAbortThreshold": {
"message": "RTH abort threshold [cm]"
},
"rthAbortThresholdHelp": {
"message": "RTH sanity checking feature will notice if distance to home is increasing during RTH and once amount of increase exceeds the threshold defined by this parameter, instead of continuing RTH machine will enter emergency landing, self-level and go down safely. Default is 500m which is safe enough for both multirotor machines and airplanes."
"message": "RTH sanity checking feature will notice if the distance to home is increasing during RTH and if it exceeds the threshold defined by this parameter, instead of continuing RTH the UAV will enter emergency landing. Default is 500m which is safe enough for both multirotors and airplanes."
},
"rthAltitude": {
"message": "RTH Altitude [cm]"
"message": "RTH altitude [cm]"
},
"rthAltitudeHelp": {
"message": "Used in Extra, Fixed and 'At Least' RTH altitude modes"
@ -2413,6 +2474,54 @@
"osdAlarmMAX_NEG_ALTITUDE_HELP": {
"message": "The altitude indicator will flash when altitude is negative and its absolute value is greater than this alarm. Useful when taking off from elevated places. Zero disables this alarm."
},
"osdAlarmGFORCE": {
"message": "g force"
},
"osdAlarmGFORCE_HELP": {
"message": "The g force element will start blinking when greater than this value"
},
"osdAlarmGFORCE_AXIS_MIN": {
"message": "g force axis min"
},
"osdAlarmGFORCE_AXIS_MIN_HELP": {
"message": "The axes g force elements will start blinking when lower than this value"
},
"osdAlarmGFORCE_AXIS_MAX": {
"message": "g force axis max"
},
"osdAlarmGFORCE_AXIS_MAX_HELP": {
"message": "The axes g force elements will start blinking when greater than this value"
},
"osdAlarmCURRENT": {
"message": "Current"
},
"osdAlarmCURRENT_HELP": {
"message": "The current draw element will start blinking when the consumption is greater than this value. Zero disables this alarm."
},
"osdAlarmIMU_TEMPERATURE_MIN": {
"message": "Minimum IMU temperature"
},
"osdAlarmIMU_TEMPERATURE_MIN_HELP": {
"message": "The temperature indicator will flash when the IMU temperature is bellow this value"
},
"osdAlarmIMU_TEMPERATURE_MAX": {
"message": "Maximum IMU temperature"
},
"osdAlarmIMU_TEMPERATURE_MAX_HELP": {
"message": "The temperature indicator will flash when the IMU temperature is above this value"
},
"osdAlarmBARO_TEMPERATURE_MIN": {
"message": "Minimum baro temperature"
},
"osdAlarmBARO_TEMPERATURE_MIN_HELP": {
"message": "The temperature indicator will flash when the barometer temperature is bellow this value"
},
"osdAlarmBARO_TEMPERATURE_MAX": {
"message": "Maximum baro temperature"
},
"osdAlarmBARO_TEMPERATURE_MAX_HELP": {
"message": "The temperature indicator will flash when the barometer temperature is above this value"
},
"osdGroupGeneral": {
"message": "General"
},
@ -2422,6 +2531,12 @@
"osdGroupTimers": {
"message": "Timers"
},
"osdGroupGForce": {
"message": "G force"
},
"osdGroupTemperature": {
"message": "Temperature"
},
"osdGroupAttitude": {
"message": "Attitude"
},
@ -2537,7 +2652,7 @@
"message": "GPS HDOP"
},
"osdElement_GPS_HDOP_HELP": {
"message": "Shows the Horizontal Dilution Of Precission from the GPS. The lower, the most accurate the GPS fix is."
"message": "Shows the Horizontal Dilution Of Precision from the GPS. The lower, the more accurate the GPS fix is."
},
"osdElement_PLUS_CODE": {
"message": "Plus Code (latitude + longitude)"
@ -2552,11 +2667,35 @@
"message": "Shows vertical speed using up or down arrows. Each arrow represents 10cm (~4 inches) per second."
},
"osdElement_VARIO_NUM": {
"message": "Numeric Vario"
"message": "Numeric vario"
},
"osdElement_VARIO_NUM_HELP": {
"message": "Shows vertical speed using a number"
},
"osdElement_G_FORCE": {
"message": "g force"
},
"osdElement_G_FORCE_HELP": {
"message": "Shows the g force taking into account all axes"
},
"osdElement_G_FORCE_X": {
"message": "Longitudinal g force in body frame (X)"
},
"osdElement_G_FORCE_X_HELP": {
"message": "Shows the g force in the X axis (longitudinal)"
},
"osdElement_G_FORCE_Y": {
"message": "Lateral g force in body frame (Y)"
},
"osdElement_G_FORCE_Y_HELP": {
"message": "Shows the g force in the Y axis (lateral)"
},
"osdElement_G_FORCE_Z": {
"message": "Vertical g force in body frame (Z)"
},
"osdElement_G_FORCE_Z_HELP": {
"message": "Shows the g force in the Z axis (vertical)"
},
"osdElement_ROLL_PIDS": {
"message": "Roll PIDs"
},
@ -2575,6 +2714,21 @@
"osdElement_RTC_TIME_HELP": {
"message": "Shows the current time, as retrieved from the GPS or set via the radio."
},
"osdElement_RC_SOURCE": {
"message": "RC source"
},
"osdElement_RC_SOURCE_HELP": {
"message": "Shows the current RC source, STD or MSP (useful when using MSP override)"
},
"osdElement_VTX_POWER": {
"message": "Video TX power level"
},
"osdElement_VTX_POWER_HELP": {
"message": "Shows the current VTX power level. Blinks when the corresponding RC adjustment is selected"
},
"osdElement_ESC_RPM": {
"message": "Motor RPM from ESC telemetry"
},
"osdElement_VTX_CHANNEL": {
"message": "Video TX Band and Channel"
},
@ -2582,22 +2736,34 @@
"message": "Shows the current band and channel of the VTX. Requires either a VTX with SmartAudio or Tramp or either a VTX integrated in the flight controller."
},
"osdElement_MAP_NORTH": {
"message": "Map (North pointing up)"
"message": "Map (Up is north)"
},
"osdElement_MAP_TAKEOFF": {
"message": "Map (takeoff direction pointing up)"
"message": "Map (Up is the takeoff direction)"
},
"osdElement_RADAR": {
"message": "Radar"
},
"osdElement_MAP_SCALE": {
"message": "Map Scale"
},
"osdElement_MAP_SCALE_HELP": {
"message": "Scale of the currently shown map/radar."
},
"osdElement_MAP_REFERENCE": {
"message": "Map Reference"
},
"osdElement_MAP_REFERENCE_HELP": {
"message": "Reference (direction that points up) of the current map. N for North and T for takeoff direction."
},
"osdElement_WIND_SPEED_HORIZONTAL": {
"message": "Horizontal Wind Speed"
"message": "Horizontal wind speed"
},
"osdElement_WIND_SPEED_HORIZONTAL_HELP": {
"message": "Shows estimated horizontal wind speed and direction."
},
"osdElement_WIND_SPEED_VERTICAL": {
"message": "Vertical Wind Speed"
"message": "Vertical wind speed"
},
"osdElement_WIND_SPEED_VERTICAL_HELP": {
"message": "Shows estimated vertical wind speed and direction (up or down)."
@ -2635,14 +2801,44 @@
"osdElement_MC_POS_XYZ_P_OUTPUTS": {
"message": "MC Position XYZ P controllers outputs"
},
"osdElement_TEMPERATURE": {
"message": "Temperature"
"osdElement_IMU_TEMPERATURE": {
"message": "IMU Temperature"
},
"osdElement_IMU_TEMPERATURE_HELP": {
"message": "Temperature of the IMU"
},
"osdElement_BARO_TEMPERATURE": {
"message": "Baro Temperature"
},
"osdElement_BARO_TEMPERATURE_HELP": {
"message": "Temperature of the barometer"
},
"osdElement_SENSOR1_TEMPERATURE": {
"message": "Temperature sensor 1"
},
"osdElement_SENSOR2_TEMPERATURE": {
"message": "Temperature sensor 2"
},
"osdElement_TEMPERATURE_HELP": {
"message": "Temperature of the FC, obtained from the most accurate available source."
"osdElement_SENSOR3_TEMPERATURE": {
"message": "Temperature sensor 3"
},
"osdElement_SENSOR4_TEMPERATURE": {
"message": "Temperature sensor 4"
},
"osdElement_SENSOR5_TEMPERATURE": {
"message": "Temperature sensor 5"
},
"osdElement_SENSOR6_TEMPERATURE": {
"message": "Temperature sensor 6"
},
"osdElement_SENSOR7_TEMPERATURE": {
"message": "Temperature sensor 7"
},
"osdElement_SENSOR8_TEMPERATURE": {
"message": "Temperature sensor 8"
},
"osdSettingMainVoltageDecimals": {
"message": "Main Voltage Decimals"
"message": "Main voltage decimals"
},
"uploadingCharacters": {
"message": "Uploading..."
@ -2680,6 +2876,18 @@
"saveEepromMissionButton": {
"message": "Save Eeprom mission"
},
"loadFileMissionButton": {
"message": "Load file"
},
"saveFileMissionButton": {
"message": "Save file"
},
"missionSettingsSave": {
"message": "Save"
},
"missionSettingsCancel": {
"message": "Cancel"
},
"editPointHead": {
"message": "Edit point"
},
@ -2758,17 +2966,20 @@
"input": {
"message": "Input"
},
"fixedValue": {
"message": "Fixed Value (µs)"
},
"weight": {
"message": "Weight"
"message": "Weight (%)"
},
"speed": {
"message": "Speed"
"message": "Speed (10µs/s)"
},
"mixerPresetTitle": {
"message": "Mixer preset"
},
"fcFirmwareUpdateRequired": {
"message": "Flight Controller firmware has to be updated to latest version to use this function"
"message": "Flight controller firmware has to be updated to latest version to use this function"
},
"mixerNotConfigured": {
"message": "Mixer not configured. Use <u>Mixer</u> tab to set it up!"
@ -2798,10 +3009,10 @@
"message": "Altitude"
},
"GROUND_SPEED": {
"message": "Ground Speed"
"message": "Ground speed"
},
"HOME_DISTANCE": {
"message": "Distance to Home"
"message": "Distance to home"
},
"brakingSpeedThreshold": {
"message": "Min. speed threshold [cm/s]"
@ -2816,7 +3027,7 @@
"message": "Braking will end when speed goes below this value"
},
"brakingTimeout": {
"message": "Max. braking length [ms]"
"message": "Max. braking duration [ms]"
},
"brakingTimeoutTip": {
"message": "Safety measure. This is the longest period of time braking can be active."
@ -2825,10 +3036,10 @@
"message": "Boost factor [%]"
},
"brakingBoostFactorTip": {
"message": "Defines for strong braking boost will be. 100% means navigation engine is allowed to double banking speed and acceleration than normal"
"message": "Defines how strong the braking boost will be. 100% means the navigation engine is allowed to double the banking speed and acceleration"
},
"brakingBoostTimeout": {
"message": "Max. braking boost length [ms]"
"message": "Max. braking boost duration [ms]"
},
"brakingBoostTimeoutTip": {
"message": "Safety measure. This is the longest period of time braking boost can be active."
@ -2883,5 +3094,209 @@
},
"gyroStage2LpfCutoffFrequencyHelp": {
"message": "Second stage gyro low pass filter that is an equivalent of Betaflight not-Kalman stage2 filter. It has to be setup above first stage gyro LPF. For 5 and 6-inch miniquads, this usually means above 150Hz. 7-inch quads above 125Hz."
},
"escProtocolNotAdvised": {
"message": "This ESC protocol is not advised, use it at your own risk"
},
"escProtocolExperimental": {
"message": "Experimental ESC protocol, use at your own risk"
},
"looptimeNotAdvised": {
"message": "PID loop might be not stable if GPS is in use"
},
"gyroLpfSuggestedMessage": {
"message": "This is suggested setting for all multirotors with propeller size below 8 inches. Always check motor temperature after the first flight"
},
"gyroLpfNotAdvisedMessage": {
"message": "It is suggested to choose an higher cutoff frequency"
},
"gyroLpfNotFlyableMessage": {
"message": "This setting will probably make the UAV unflyable"
},
"gyroLpfWhyNotHigherMessage": {
"message": "If motors are not overheating, try to set 256Hz instead"
},
"gyroLpfWhyNotSlightlyHigherMessage": {
"message": "If there are no vibration problems and motors are not overheating, try to set 188Hz instead"
},
"tabLogicConditions": {
"message": "Logic conditions"
},
"logicId": {
"message": "#"
},
"logicEnabled": {
"message": "Enabled"
},
"logicOperation": {
"message": "Operation"
},
"logicOperandA": {
"message": "Operand A"
},
"logicOperandB": {
"message": "Operand B"
},
"logicFlags": {
"message": "Flags"
},
"logicSave": {
"message": "Save"
},
"logicClose": {
"message": "Close"
},
"active": {
"message": "Active"
},
"itermRelax": {
"message": "Iterm Relax"
},
"itermRelaxHelp": {
"message": "Defines Iterm relaxation algorithm activation. PR mean it's active on Roll and Pitch axis. PRY is active also on Yaw."
},
"itermRelaxType": {
"message": "Iterm Relax Type"
},
"itermRelaxTypeHelp": {
"message": "GYRO mode is more clinical and complete in suppressing iTerm, SETPOINT mode is a bit smoother with slightly softer landings after flips."
},
"itermRelaxCutoff": {
"message": "Iterm Relax Cutoff Frequency"
},
"itermRelaxCutoffHelp": {
"message": "Lower values open a longer time window for Iterm Relax to work on and stronger Iterm suppression. Higher values shortens the time windows and reduces suppression."
},
"gyro_lpf_type": {
"message": "Gyro LPF type"
},
"gyro_lpf_type_help": {
"message": "BIQUAD offers better noise attenuation for a price of higher delay. PT1 has lower attenuation but offers lower delay."
},
"gyro_stage2_lowpass_type": {
"message": "Gyro Stage 2 LPF type"
},
"gyro_stage2_lowpass_type_help": {
"message": "BIQUAD offers better noise attenuation for a price of higher delay. PT1 has lower attenuation but offers lower delay."
},
"dterm_lpf_type": {
"message": "D-term LPF type"
},
"dterm_lpf_type_help": {
"message": "BIQUAD offers better noise attenuation for a price of higher delay. PT1 has lower attenuation but offers lower delay."
},
"dterm_lpf2_type": {
"message": "D-term Stage 2 LPF type"
},
"dterm_lpf2_type_help": {
"message": "BIQUAD offers better noise attenuation for a price of higher delay. PT1 has lower attenuation but offers lower delay."
},
"dterm_lpf2_hz": {
"message": "D-term Stage 2 LPF cutoff frequency"
},
"dterm_lpf2_hz_help": {
"message": "Lowpass cutoff filter for D-term on ROLL and PITCH axises. 0 mean filter is disabled"
},
"tabFilteringAdvanced": {
"message": "Other filters"
},
"mainFilters": {
"message": "Gyro filters"
},
"rpmFilters": {
"message": "Gyro RPM filters"
},
"dtermFilters": {
"message": "D-term filters"
},
"rpm_gyro_filter_enabled": {
"message": "Gyro RPM filter (requires ESC telemetry)"
},
"rpm_gyro_min_hz": {
"message": "Gyro RPM filter min. frequency"
},
"acc_lpf_type": {
"message": "Accelerometer LPF type"
},
"acc_lpf_type_help": {
"message": "BIQUAD offers better noise attenuation for a price of higher delay. PT1 has lower attenuation but offers lower delay."
},
"dTermMechanics": {
"message": "D-term mechanics"
},
"d_boost_factor": {
"message": "D-Boost Factor"
},
"d_boost_factor_help": {
"message": "Defines the maximum Dterm boost when maximum angular acceleration is reached. 1.0 means D-Boost is disabled, 2.0 means Dterm is allowed to grow by 100%. Values between 1.5 and 1.7 are usually the sweet spot."
},
"d_boost_max_at_acceleration": {
"message": "Top D-Boost at acceleration [dps^2]"
},
"d_boost_max_at_acceleration_help": {
"message": "D-Boost is fully active when angular acceleration (either detected by gyro or rate target) reached given acceleration. Between 0 and this value, D-Boost factor is scaled lineary"
},
"d_boost_gyro_delta_lpf_hz": {
"message": "D-Boost gyro LPF"
},
"d_boost_gyro_delta_lpf_hz_help": {
"message": "Should be set to the frequency of propeller wash oscillations. 5-inch quads work best at around 80Hz, 7-inch quads at around 50Hz"
},
"iTermMechanics": {
"message": "I-term mechanics"
},
"mc_airmode_type": {
"message": "Airmode handling type"
},
"mc_airmode_type_help": {
"message": "Defines the Airmode state handling type for Multirotors. <br />Default STICK_CENTER is the classical approach in which Airmode is always active if enabled, but when the throttle is low and ROLL/PITCH/YAW sticks are centered, Iterms is not allowed to grow (ANTI_WINDUP). <br />THROTTLE_THRESHOLD is the Airmode behavior known from Betaflight. In this mode, Airmode is active as soon THROTTLE position is above <i>mc_airmode_threshold</i> and stays active until disarm. ANTI_WINDUP is never triggered. For small Multirotors (up to 7-inch propellers) it is suggested to switch to THROTTLE_THRESHOLD since it keeps full stabilization no matter what pilot does with the sticks. Fixed Wings always use STICK_CENTER mode."
},
"mc_airmode_threshold": {
"message": "Airmode Throttle threshold"
},
"mc_airmode_threshold_help": {
"message": "Defines airmode THROTTLE activation threshold when mc_airmode_type THROTTLE_THRESHOLD is used"
},
"gps_map_center": {
"message": "Center"
},
"antigravityGain": {
"message": "Antigravity Gain"
},
"antigravityAccelerator": {
"message": "Antigravity Accelerator"
},
"antigravityCutoff": {
"message": "Antigravity Cutoff Frequency"
},
"ouptputsConfiguration": {
"message": "Configuration"
},
"vtxDisclaimer": {
"message": "Use only bands, channels and power levels that are legal in a place you fly! Always refer to VTX user manual and local regulations!"
},
"defaultsDialogTitle": {
"message": "Default values"
},
"defaultsDialogInfo": {
"message": "INAV Configurator would like to know which kind of UAV you are configuring. Based on this information it will modify some default values to unlock the best flying performance. "
},
"throttleIdle": {
"message": "Motors IDLE power [%]"
},
"throttleIdleDigitalInfo": {
"message": "For digital protocols, IDLE can be lowered even down to 5-7% without motors stopping in the air. If a drone wobbles after pulling throttle low, try increasing IDLE to tune this behavior out."
},
"throttleIdleAnalogInfo": {
"message": "For analog protocols, IDLE can be lowered below 10% if motors are working smooth without stuttering. If a drone wobbles after pulling throttle low, try increasing IDLE to tune this behavior out."
},
"motor_poles": {
"message": "Number of motor poles (number of magnets)"
},
"motorStopWarning": {
"message": "Should be enabled on Airplanes, Rovers and Boats. Should not be enabled on Multirotors! On Multirotors, when Airmode is active, motors will not stop."
},
"dynamic_gyro_notch_enabled_help": {
"message": "Matrix Gyro Filter is the new generation of dynamic gyro notches available in INAV. It is recommended to enable it on all Multirotor builds on F4 and F7 flight controllers."
}
}

@ -1,5 +0,0 @@
<span>1.0.2</span>
<ul>
<li>PID scaling in Configurator removed</li>
<li>Improved anonymous tracking</li>
</ul>

@ -8,6 +8,7 @@ var minimist = require('minimist');
var archiver = require('archiver');
var del = require('del');
var NwBuilder = require('nw-builder');
var semver = require('semver');
var gulp = require('gulp');
var concat = require('gulp-concat');
@ -49,7 +50,9 @@ sources.css = [
'./src/css/dropdown-lists/css/style_lists.css',
'./js/libraries/switchery/switchery.css',
'./js/libraries/jbox/jBox.css',
'./node_modules/openlayers/dist/ol.css'
'./node_modules/openlayers/dist/ol.css',
'./src/css/logic.css',
'./src/css/defaults_dialog.css'
];
sources.js = [
@ -60,6 +63,8 @@ sources.js = [
'./js/libraries/d3.min.js',
'./js/libraries/jquery.nouislider.all.min.js',
'./node_modules/three/three.min.js',
'./js/libraries/nw-dialog.js',
'./js/libraries/bundle_xml2js.js',
'./js/libraries/Projector.js',
'./js/libraries/CanvasRenderer.js',
'./js/libraries/jquery.flightindicators.js',
@ -84,6 +89,7 @@ sources.js = [
'./js/serial.js',
'./js/servoMixRule.js',
'./js/motorMixRule.js',
'./js/logicCondition.js',
'./js/settings.js',
'./js/outputMapping.js',
'./js/model.js',
@ -95,11 +101,14 @@ sources.js = [
'./js/protocols/stm32usbdfu.js',
'./js/localization.js',
'./js/boards.js',
'./js/tasks.js',
'./js/servoMixerRuleCollection.js',
'./js/motorMixerRuleCollection.js',
'./js/logicConditionsCollection.js',
'./js/logicConditionsStatus.js',
'./js/vtx.js',
'./main.js',
'./js/tabs.js',
'./js/preset_definitions.js',
'./tabs/*.js',
'./js/eventFrequencyAnalyzer.js',
'./js/periodicStatusUpdater.js',
@ -108,6 +117,8 @@ sources.js = [
'./tabs/advanced_tuning.js',
'./js/peripherals.js',
'./js/appUpdater.js',
'./js/feature_framework.js',
'./js/defaults_dialog.js',
'./node_modules/openlayers/dist/ol.js'
];
@ -152,7 +163,7 @@ function get_task_name(key) {
}
function getPlatforms() {
var defaultPlatforms = ['win32', 'osx64', 'linux32', 'linux64'];
var defaultPlatforms = ['win32', 'win64', 'osx64', 'linux32', 'linux64'];
var argv = minimist(process.argv.slice(2));
if (argv.platform) {
if (defaultPlatforms.indexOf(argv.platform) < 0) {
@ -228,6 +239,7 @@ gulp.task('apps', gulp.series('dist', function(done) {
flavor: 'normal',
macIcns: './images/inav.icns',
winIco: './images/inav.ico',
version: get_nw_version()
});
builder.on('log', console.log);
builder.build(function (err) {
@ -241,6 +253,10 @@ gulp.task('apps', gulp.series('dist', function(done) {
});
}));
function get_nw_version() {
return semver.valid(semver.coerce(require('./package.json').dependencies.nw));
}
function get_release_filename(platform, ext) {
var pkg = require('./package.json');
return 'INAV-Configurator_' + platform + '_' + pkg.version + '.' + ext;
@ -260,6 +276,20 @@ gulp.task('release-win32', function() {
return archive.finalize();
});
gulp.task('release-win64', function() {
var pkg = require('./package.json');
var src = path.join(appsDir, pkg.name, 'win64');
var output = fs.createWriteStream(path.join(appsDir, get_release_filename('win64', 'zip')));
var archive = archiver('zip', {
zlib: { level: 9 }
});
archive.on('warning', function(err) { throw err; });
archive.on('error', function(err) { throw err; });
archive.pipe(output);
archive.directory(src, 'INAV Configurator');
return archive.finalize();
});
gulp.task('release-osx64', function() {
var pkg = require('./package.json');
var src = path.join(appsDir, pkg.name, 'osx64', pkg.name + '.app');
@ -284,9 +314,10 @@ function releaseLinux(bits) {
var dirname = 'linux' + bits;
var pkg = require('./package.json');
var src = path.join(appsDir, pkg.name, dirname);
var output = fs.createWriteStream(path.join(appsDir, get_release_filename(dirname, 'zip')));
var archive = archiver('zip', {
zlib: { level: 9 }
var output = fs.createWriteStream(path.join(appsDir, get_release_filename(dirname, 'tar.gz')));
var archive = archiver('tar', {
zlib: { level: 9 },
gzip: true
});
archive.on('warning', function(err) { throw err; });
archive.on('error', function(err) { throw err; });

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

@ -7,19 +7,15 @@ appUpdater.checkRelease = function (currVersion) {
$.get('https://api.github.com/repos/iNavFlight/inav-configurator/releases', function (releaseData) {
GUI.log('Loaded release information from GitHub.');
//Git return sorted list, 0 - last release
if (semver.gt(releaseData[0].tag_name, currVersion)) {
GUI.log(releaseData[0].tag_name, chrome.runtime.getManifest().version);
GUI.log(currVersion);
//For download zip
// releaseData[0].assets.forEach(function(item, i) {
// if (str.indexOf(item.name) !== -1) {
// console.log(item);
// downloadUrl = item.browser_download_url;
// }
// });
let newVersion = releaseData[0].tag_name;
let newPrerelase = releaseData[0].prerelease;
if (newPrerelase == false && semver.gt(newVersion, currVersion)) {
GUI.log(newVersion, chrome.runtime.getManifest().version);
GUI.log(currVersion);
GUI.log('New version aviable!');
GUI.log('New version available!');
modalStart = new jBox('Modal', {
width: 400,
height: 200,

@ -2,10 +2,6 @@
var BOARD_DEFINITIONS = [
{
name: "CC3D",
identifier: "CC3D",
vcp: true
}, {
name: "ChebuzzF3",
identifier: "CHF3",
vcp: false
@ -32,65 +28,30 @@ var BOARD_DEFINITIONS = [
name: "Port103R",
identifier: "103R",
vcp: false
}, {
name: "Sparky",
identifier: "SPKY",
vcp: true
}, {
name: "STM32F3Discovery",
identifier: "SDF3",
vcp: true
}, {
name: "Colibri Race",
identifier: "CLBR",
vcp: true
}, {
name: "SP Racing F3",
identifier: "SRF3",
vcp: false
}, {
name: "SP Racing F3 Mini",
identifier: "SRFM",
vcp: true
}, {
name: "MotoLab",
identifier: "MOTO",
vcp: true
}, {
name: "Omnibus",
identifier: "OMNI",
vcp: true
}, {
name: "Airbot F4",
identifier: "ABF4",
vcp: true
}, {
name: "Revolution",
identifier: "REVO",
vcp: true
}, {
name: "Omnibus F4",
identifier: "OBF4",
vcp: true
}, {
name: "Omnibus F4 Pro",
identifier: "OBSD",
vcp: true
}
];
var DEFAULT_BOARD_DEFINITION = {
name: "Unknown",
identifier: "????",
vcp: false
vcp: true
};
var BOARD = {
};
BOARD.find_board_definition = function (identifier) {
for (var i = 0; i < BOARD_DEFINITIONS.length; i++) {
var candidate = BOARD_DEFINITIONS[i];
BOARD.hasVcp = function (identifier) {
let board = BOARD.findDefinition(identifier);
return !!board.vcp;
}
BOARD.findDefinition = function (identifier) {
for (let i = 0; i < BOARD_DEFINITIONS.length; i++) {
let candidate = BOARD_DEFINITIONS[i];
if (candidate.identifier == identifier) {
return candidate;

@ -2,7 +2,8 @@
var CONFIGURATOR = {
// all versions are specified and compared using semantic versioning http://semver.org/
'firmwareVersionAccepted': '1.6.0',
'minfirmwareVersionAccepted': '2.4.0',
'maxFirmwareVersionAccepted': '2.6.0', // COndition is < (lt) so we accept all in 2.2 branch, not 2.3 actualy
'connectionValid': false,
'connectionValidCliOnly': false,
'cliActive': false,

@ -0,0 +1,279 @@
/*global mspHelper,$,GUI,MSP,BF_CONFIG,chrome*/
'use strict';
var helper = helper || {};
helper.defaultsDialog = (function() {
let publicScope = {},
privateScope = {};
let $container;
let data = [{
"title": 'Mini Quad with 3"-7" propellers',
"settings": [
{
key: "gyro_hardware_lpf",
value: "256HZ"
},
{
key: "looptime",
value: 500
},
{
key: "gyro_lpf_hz",
value: 100
},
{
key: "gyro_lpf_type",
value: "PT1"
},
{
key: "gyro_stage2_lowpass_hz",
value: 200
},
{
key: "dterm_lpf_hz",
value: 90
},
{
key: "use_dterm_fir_filter",
value: "OFF"
},
{
key: "mc_iterm_relax_type",
value: "SETPOINT"
},
{
key: "mc_iterm_relax",
value: "RP"
},
{
key: "d_boost_factor",
value: 1.5
},
{
key: "antigravity_gain",
value: 2
},
{
key: "antigravity_accelerator",
value: 5
},
{
key: "rc_yaw_expo",
value: 70
},
{
key: "rc_expo",
value: 70
},
{
key: "roll_rate",
value: 70
},
{
key: "pitch_rate",
value: 70
},
{
key: "yaw_rate",
value: 60
},
{
key: "mc_p_pitch",
value: 44
},
{
key: "mc_i_pitch",
value: 60
},
{
key: "mc_d_pitch",
value: 25
},
{
key: "mc_p_roll",
value: 40
},
{
key: "mc_i_roll",
value: 50
},
{
key: "mc_d_roll",
value: 25
},
{
key: "mc_p_yaw",
value: 45
},
{
key: "mc_i_yaw",
value: 70
},
{
key: "mc_airmode_type",
value: "THROTTLE_THRESHOLD"
},
{
key: "applied_defaults",
value: 2
}
],
"features":[
{
bit: 5, // Enable DYNAMIC_FILTERS
state: true
}
]
},
{
"title": 'Airplane',
"id": 3,
"settings": [
{
key: "rc_yaw_expo",
value: 70
},
{
key: "rc_expo",
value: 70
},
{
key: "roll_rate",
value: 30
},
{
key: "pitch_rate",
value: 20
},
{
key: "yaw_rate",
value: 10
},
{
key: "small_angle",
value: 180
},
{
key: "applied_defaults",
value: 3
}
],
"features":[
{
bit: 4, // Enable MOTOR_STOP
state: true
}
]
},
{
"title": 'Custom UAV - INAV legacy defaults',
"settings": [
{
key: "applied_defaults",
value: 1
}
]
},
{
"title": 'Keep current settings',
"settings": [
{
key: "applied_defaults",
value: 1
}
]
}
]
publicScope.init = function() {
mspHelper.getSetting("applied_defaults").then(privateScope.onInitSettingReturned);
$container = $("#defaults-wrapper");
};
privateScope.setFeaturesBits = function (selectedDefaultPreset) {
if (selectedDefaultPreset.features && selectedDefaultPreset.features.length > 0) {
helper.features.reset();
for (const feature of selectedDefaultPreset.features) {
if (feature.state) {
helper.features.set(feature.bit);
} else {
helper.features.unset(feature.bit);
}
}
helper.features.execute(function () {
privateScope.setSettings(selectedDefaultPreset);
});
} else {
privateScope.setSettings(selectedDefaultPreset);
}
};
privateScope.setSettings = function (selectedDefaultPreset) {
Promise.mapSeries(selectedDefaultPreset.settings, function (input, ii) {
return mspHelper.getSetting(input.key);
}).then(function () {
Promise.mapSeries(selectedDefaultPreset.settings, function (input, ii) {
return mspHelper.setSetting(input.key, input.value);
}).then(function () {
mspHelper.saveToEeprom(function () {
//noinspection JSUnresolvedVariable
GUI.log(chrome.i18n.getMessage('configurationEepromSaved'));
GUI.tab_switch_cleanup(function() {
MSP.send_message(MSPCodes.MSP_SET_REBOOT, false, false, function () {
//noinspection JSUnresolvedVariable
GUI.log(chrome.i18n.getMessage('deviceRebooting'));
GUI.handleReconnect();
});
});
});
})
});
};
privateScope.onPresetClick = function(event) {
$container.hide();
let selectedDefaultPreset = data[$(event.currentTarget).data("index")];
if (selectedDefaultPreset && selectedDefaultPreset.settings) {
mspHelper.loadBfConfig(function () {
privateScope.setFeaturesBits(selectedDefaultPreset)
});
}
};
privateScope.render = function() {
let $place = $container.find('.defaults-dialog__options');
$place.html("");
for (let i in data) {
if (data.hasOwnProperty(i)) {
let preset = data[i];
let $element = $("<div class='default_btn defaults_btn'>\
<a class='confirm' href='#'></a>\
</div>")
$element.find("a").html(preset.title);
$element.data("index", i).click(privateScope.onPresetClick)
$element.appendTo($place);
}
}
}
privateScope.onInitSettingReturned = function(promise) {
if (promise.value > 0) {
return; //Defaults were applied, we can just ignore
}
privateScope.render();
$container.show();
}
return publicScope;
})();

@ -19,6 +19,7 @@ var CONFIG,
SERVO_CONFIG,
SERVO_RULES,
MOTOR_RULES,
LOGIC_CONDITIONS,
SERIAL_CONFIG,
SENSOR_DATA,
MOTOR_DATA,
@ -29,7 +30,7 @@ var CONFIG,
ARMING_CONFIG,
FC_CONFIG,
MISC,
_3D,
REVERSIBLE_MOTORS,
DATAFLASH,
SDCARD,
BLACKBOX,
@ -61,8 +62,11 @@ var CONFIG,
var FC = {
MAX_SERVO_RATE: 125,
MIN_SERVO_RATE: 0,
isNewMixer: function () {
return !!(typeof CONFIG != "undefined" && semver.gte(CONFIG.flightControllerVersion, "2.0.0"));
isRpyFfComponentUsed: function () {
return MIXER_CONFIG.platformType == PLATFORM_AIRPLANE;
},
isRpyDComponentUsed: function () {
return MIXER_CONFIG.platformType != PLATFORM_AIRPLANE;
},
resetState: function () {
SENSOR_STATUS = {
@ -126,11 +130,7 @@ var FC = {
};
PID_names = [];
PIDs = new Array(10);
for (var i = 0; i < 10; i++) {
PIDs[i] = new Array(3);
}
PIDs = [];
RC_MAP = [];
// defaults
@ -168,6 +168,8 @@ var FC = {
SERVO_CONFIG = [];
SERVO_RULES = new ServoMixerRuleCollection();
MOTOR_RULES = new MotorMixerRuleCollection();
LOGIC_CONDITIONS = new LogicConditionsCollection();
LOGIC_CONDITIONS_STATUS = new LogicConditionsStatus();
MIXER_CONFIG = {
yawMotorDirection: 0,
@ -198,11 +200,12 @@ var FC = {
sonar: 0,
air_speed: 0,
kinematics: [0.0, 0.0, 0.0],
temperature: [0, 0, 0, 0, 0, 0, 0, 0],
debug: [0, 0, 0, 0]
};
MOTOR_DATA = new Array(8);
SERVO_DATA = new Array(8);
SERVO_DATA = new Array(16);
GPS_DATA = {
fix: 0,
@ -391,6 +394,9 @@ var FC = {
X: null,
Y: null,
Z: null
},
opflow: {
Scale: null
}
};
@ -409,11 +415,11 @@ var FC = {
emergencyDescentRate: null
};
_3D = {
deadband3d_low: 0,
deadband3d_high: 0,
neutral3d: 0,
deadband3d_throttle: 0
REVERSIBLE_MOTORS = {
deadband_low: 0,
deadband_high: 0,
neutral: 0,
deadband_throttle: 0
};
DATAFLASH = {
@ -538,80 +544,29 @@ var FC = {
getFeatures: function () {
var features = [
{bit: 1, group: 'batteryVoltage', name: 'VBAT'},
{bit: 4, group: 'esc', name: 'MOTOR_STOP'},
{bit: 4, group: 'other', name: 'MOTOR_STOP'},
{bit: 6, group: 'other', name: 'SOFTSERIAL', haveTip: true, showNameInTip: true},
{bit: 7, group: 'gps', name: 'GPS', haveTip: true},
{bit: 10, group: 'other', name: 'TELEMETRY', showNameInTip: true},
{bit: 11, group: 'batteryCurrent', name: 'CURRENT_METER'},
{bit: 12, group: 'other', name: '3D', showNameInTip: true},
{bit: 12, group: 'other', name: 'REVERSIBLE_MOTORS', showNameInTip: true},
{bit: 15, group: 'other', name: 'RSSI_ADC', haveTip: true, showNameInTip: true},
{bit: 16, group: 'other', name: 'LED_STRIP', showNameInTip: true},
{bit: 17, group: 'other', name: 'DASHBOARD', showNameInTip: true},
{bit: 19, group: 'other', name: 'BLACKBOX', haveTip: true, showNameInTip: true}
{bit: 19, group: 'other', name: 'BLACKBOX', haveTip: true, showNameInTip: true},
{bit: 28, group: 'other', name: 'PWM_OUTPUT_ENABLE', haveTip: true},
{bit: 26, group: 'other', name: 'SOFTSPI'},
{bit: 27, group: 'other', name: 'PWM_SERVO_DRIVER', haveTip: true, showNameInTip: true},
{bit: 29, group: 'other', name: 'OSD', haveTip: false, showNameInTip: false},
{bit: 22, group: 'other', name: 'AIRMODE', haveTip: false, showNameInTip: false},
{bit: 30, group: 'other', name: 'FW_LAUNCH', haveTip: false, showNameInTip: false},
{bit: 2, group: 'other', name: 'TX_PROF_SEL', haveTip: false, showNameInTip: false},
{bit: 0, group: 'other', name: 'THR_VBAT_COMP', haveTip: true, showNameInTip: true},
{bit: 3, group: 'other', name: 'BAT_PROFILE_AUTOSWITCH', haveTip: true, showNameInTip: true}
];
if (semver.lt(CONFIG.flightControllerVersion, "2.0.0")) {
features.push(
{bit: 20, group: 'other', name: 'CHANNEL_FORWARDING', showNameInTip: true},
{bit: 5, group: 'other', name: 'SERVO_TILT', showNameInTip: true}
);
}
if (semver.lt(CONFIG.flightControllerVersion, "1.6.0")) {
features.push(
{bit: 2, group: 'other', name: 'INFLIGHT_ACC_CAL', showNameInTip: true},
{bit: 9, group: 'other', name: 'SONAR', showNameInTip: true},
{bit: 8, group: 'rxFailsafe', name: 'FAILSAFE'}
);
}
features.push(
{bit: 28, group: 'esc-priority', name: 'PWM_OUTPUT_ENABLE', haveTip: true}
);
/*
* Transponder disabled until not implemented in firmware
*/
if (false && semver.gte(CONFIG.apiVersion, "1.16.0")) {
features.push(
{bit: 21, group: 'other', name: 'TRANSPONDER', haveTip: true, showNameInTip: true}
);
}
if (semver.gte(CONFIG.apiVersion, "1.21.0")) {
features.push(
{bit: 26, group: 'other', name: 'SOFTSPI'}
);
}
features.push(
{bit: 27, group: 'other', name: 'PWM_SERVO_DRIVER', haveTip: true, showNameInTip: true}
);
if (semver.gte(CONFIG.flightControllerVersion, '1.5.0')) {
features.push(
{bit: 29, group: 'other', name: 'OSD', haveTip: false, showNameInTip: false}
);
}
if (semver.gte(CONFIG.flightControllerVersion, '1.7.3')) {
features.push(
{bit: 22, group: 'other', name: 'AIRMODE', haveTip: false, showNameInTip: false}
);
}
if (semver.gte(CONFIG.flightControllerVersion, '1.8.1')) {
features.push(
{bit: 30, group: 'other', name: 'FW_LAUNCH', haveTip: false, showNameInTip: false},
{bit: 2, group: 'other', name: 'TX_PROF_SEL', haveTip: false, showNameInTip: false}
);
}
if (semver.gte(CONFIG.flightControllerVersion, '2.0.0')) {
features.push(
{bit: 0, group: 'other', name: 'THR_VBAT_COMP', haveTip: true, showNameInTip: true},
{bit: 3, group: 'other', name: 'BAT_PROFILE_AUTOSWITCH', haveTip: true, showNameInTip: true}
);
if (semver.gte(CONFIG.flightControllerVersion, "2.4.0") && semver.lt(CONFIG.flightControllerVersion, "2.5.0")) {
features.push({bit: 5, group: 'other', name: 'DYNAMIC_FILTERS', haveTip: true, showNameInTip: true});
}
return features.reverse();
@ -633,7 +588,7 @@ var FC = {
getLooptimes: function () {
return {
125: {
defaultLooptime: 2000,
defaultLooptime: 1000,
looptimes: {
4000: "250Hz",
3000: "334Hz",
@ -646,7 +601,7 @@ var FC = {
}
},
1000: {
defaultLooptime: 2000,
defaultLooptime: 1000,
looptimes: {
4000: "250Hz",
2000: "500Hz",
@ -715,22 +670,14 @@ var FC = {
];
},
getGpsProtocols: function () {
var data = [
return [
'NMEA',
'UBLOX',
'I2C-NAV',
'DJI NAZA'
'DJI NAZA',
'UBLOX7',
'MTK'
];
if (semver.gte(CONFIG.flightControllerVersion, "1.7.1")) {
data.push('UBLOX7')
}
if (semver.gte(CONFIG.flightControllerVersion, "1.7.2")) {
data.push('MTK')
}
return data;
},
getGpsBaudRates: function () {
return [
@ -751,117 +698,6 @@ var FC = {
'Disabled'
];
},
getRxTypes: function() {
// Keep value field in sync with rxReceiverType_e in rx.h
var rxTypes = [
{
name: 'RX_SERIAL',
bit: 3,
value: 3,
},
{
name: 'RX_PPM',
bit: 0,
value: 2,
},
{
name: 'RX_PWM',
bit: 13,
value: 1,
},
];
if (semver.gte(CONFIG.apiVersion, "1.21.0")) {
rxTypes.push({
name: 'RX_SPI',
bit: 25,
value: 5,
});
}
rxTypes.push({
name: 'RX_MSP',
bit: 14,
value: 4,
});
// Versions using feature bits don't allow not having an
// RX and fallback to RX_PPM.
if (semver.gt(CONFIG.flightControllerVersion, "1.7.3")) {
rxTypes.push({
name: 'RX_NONE',
value: 0,
});
}
return rxTypes;
},
isRxTypeEnabled: function(rxType) {
if (typeof rxType === 'string') {
var types = this.getRxTypes();
for (var ii = 0; ii < types.length; ii++) {
if (types[ii].name == rxType) {
rxType = types[ii];
break;
}
}
}
if (semver.gt(CONFIG.flightControllerVersion, "1.7.3")) {
return RX_CONFIG.receiver_type == rxType.value;
}
return bit_check(BF_CONFIG.features, rxType.bit);
},
setRxTypeEnabled: function(rxType) {
if (semver.gt(CONFIG.flightControllerVersion, "1.7.3")) {
RX_CONFIG.receiver_type = rxType.value;
} else {
// Clear other rx features before
var rxTypes = this.getRxTypes();
for (var ii = 0; ii < rxTypes.length; ii++) {
BF_CONFIG.features = bit_clear(BF_CONFIG.features, rxTypes[ii].bit);
}
// Set the feature for this rx type (if any, RX_NONE is set by clearing all)
if (rxType.bit !== undefined) {
BF_CONFIG.features = bit_set(BF_CONFIG.features, rxType.bit);
}
}
},
getSerialRxTypes: function () {
var data = [
'SPEKTRUM1024',
'SPEKTRUM2048',
'SBUS',
'SUMD',
'SUMH',
'XBUS_MODE_B',
'XBUS_MODE_B_RJ01',
'IBUS'
];
if (semver.gte(CONFIG.flightControllerVersion, "1.6.0")) {
data.push('JETI EXBUS');
data.push('TBS Crossfire');
}
if (semver.gte(CONFIG.flightControllerVersion, "1.9.1")) {
data.push('FPort');
}
return data;
},
getSPIProtocolTypes: function () {
return [
'V202 250Kbps',
'V202 1Mbps',
'Syma X',
'Syma X5C',
'Cheerson CX10',
'Cheerson CX10A',
'JJRC H8_3D',
'iNav Reference protocol',
'eLeReS'
];
},
getSensorAlignments: function () {
return [
'CW 0°',
@ -878,6 +714,7 @@ var FC = {
return {
0: {
name: "STANDARD",
message: null,
defaultRate: 400,
rates: {
50: "50Hz",
@ -886,6 +723,7 @@ var FC = {
},
1: {
name: "ONESHOT125",
message: null,
defaultRate: 1000,
rates: {
400: "400Hz",
@ -895,6 +733,7 @@ var FC = {
},
2: {
name: "ONESHOT42",
message: null,
defaultRate: 2000,
rates: {
400: "400Hz",
@ -906,6 +745,7 @@ var FC = {
},
3: {
name: "MULTISHOT",
message: null,
defaultRate: 2000,
rates: {
400: "400Hz",
@ -917,6 +757,7 @@ var FC = {
},
4: {
name: "BRUSHED",
message: null,
defaultRate: 8000,
rates: {
8000: "8kHz",
@ -926,6 +767,7 @@ var FC = {
},
5: {
name: "DSHOT150",
message: null,
defaultRate: 4000,
rates: {
4000: "4kHz"
@ -933,6 +775,7 @@ var FC = {
},
6: {
name: "DSHOT300",
message: null,
defaultRate: 8000,
rates: {
8000: "8kHz"
@ -940,6 +783,7 @@ var FC = {
},
7: {
name: "DSHOT600",
message: null,
defaultRate: 16000,
rates: {
16000: "16kHz"
@ -947,10 +791,19 @@ var FC = {
},
8: {
name: "DSHOT1200",
message: "escProtocolNotAdvised",
defaultRate: 16000,
rates: {
16000: "16kHz"
}
},
9: {
name: "SERIALSHOT",
message: "escProtocolExperimental",
defaultRate: 4000,
rates: {
4000: "4kHz"
}
}
};
},
@ -994,37 +847,23 @@ var FC = {
return [];
},
getAccelerometerNames: function () {
if (semver.gte(CONFIG.flightControllerVersion, "2.1.0")) {
return [ "NONE", "AUTO", "ADXL345", "MPU6050", "MMA845x", "BMA280", "LSM303DLHC", "MPU6000", "MPU6500", "MPU9250", "BMI160", "ICM20689", "FAKE"];
}
else if (semver.gte(CONFIG.flightControllerVersion, "2.0.0")) {
return [ "NONE", "AUTO", "ADXL345", "MPU6050", "MMA845x", "BMA280", "LSM303DLHC", "MPU6000", "MPU6500", "MPU9250", "BMI160", "FAKE"];
}
else {
return [ "NONE", "AUTO", "ADXL345", "MPU6050", "MMA845x", "BMA280", "LSM303DLHC", "MPU6000", "MPU6500", "MPU9250", "FAKE"];
}
return [ "NONE", "AUTO", "ADXL345", "MPU6050", "MMA845x", "BMA280", "LSM303DLHC", "MPU6000", "MPU6500", "MPU9250", "BMI160", "ICM20689", "FAKE"];
},
getMagnetometerNames: function () {
return ["NONE", "AUTO", "HMC5883", "AK8975", "GPSMAG", "MAG3110", "AK8963", "IST8310", "QMC5883", "MPU9250", "IST8308", "LIS3MDL", "FAKE"];
},
getBarometerNames: function () {
if (semver.gte(CONFIG.flightControllerVersion, "1.6.2")) {
return ["NONE", "AUTO", "BMP085", "MS5611", "BMP280", "MS5607", "FAKE"];
}
else {
return ["NONE", "AUTO", "BMP085", "MS5611", "BMP280", "FAKE"];
if (semver.gte(CONFIG.flightControllerVersion, "2.4.0")) {
return ["NONE", "AUTO", "BMP085", "MS5611", "BMP280", "MS5607", "LPS25H", "SPL06", "BMP388", "FAKE"];
} else {
return ["NONE", "AUTO", "BMP085", "MS5611", "BMP280", "MS5607", "LPS25H", "SPL06", "FAKE"];
}
},
getPitotNames: function () {
if (semver.gte(CONFIG.flightControllerVersion, "1.6.3")) {
return ["NONE", "AUTO", "MS4525", "ADC", "VIRTUAL", "FAKE"];
}
else {
return ["NONE", "AUTO", "MS4525", "FAKE"];
}
return ["NONE", "AUTO", "MS4525", "ADC", "VIRTUAL", "FAKE"];
},
getRangefinderNames: function () {
return [ "NONE", "HCSR04", "SRF10", "INAV_I2C", "VL53L0X", "MSP", "UIB"];
return [ "NONE", "HCSR04", "SRF10", "INAV_I2C", "VL53L0X", "MSP", "UIB", "Benewake TFmini"];
},
getOpticalFlowNames: function () {
return [ "NONE", "PMW3901", "CXOF", "MSP", "FAKE" ];
@ -1065,33 +904,27 @@ var FC = {
]
},
getPidNames: function () {
if (semver.lt(CONFIG.flightControllerVersion, "1.6.0")) {
return PID_names;
} else {
return [
'Roll',
'Pitch',
'Yaw',
'Position Z',
'Position XY',
'Velocity XY',
'Surface',
'Level',
'Heading',
'Velocity Z'
];
}
return [
'Roll',
'Pitch',
'Yaw',
'Position Z',
'Position XY',
'Velocity XY',
'Surface',
'Level',
'Heading',
'Velocity Z'
];
},
getRthAltControlMode: function () {
return ["Current", "Extra", "Fixed", "Max", "At Least"];
if (semver.gte(CONFIG.flightControllerVersion, '2.2.0'))
return ["Current", "Extra", "Fixed", "Max", "At least", "At least, linear descent"];
else
return ["Current", "Extra", "Fixed", "Max", "At least"];
},
getRthAllowLanding: function() {
var values = ["Never", "Always"];
if (semver.gt(CONFIG.flightControllerVersion, '1.7.3')) {
values.push("Only on failsafe");
}
return values;
return ["Never", "Always", "Only on failsafe"];
},
getFailsafeProcedure: function () {
return {
@ -1102,10 +935,7 @@ var FC = {
}
},
getRcMapLetters: function () {
if (semver.gte(CONFIG.flightControllerVersion, '1.9.1'))
return ['A', 'E', 'R', 'T'];
else
return ['A', 'E', 'R', 'T', '5', '6', '7', '8'];
return ['A', 'E', 'R', 'T'];
},
isRcMapValid: function (val) {
var strBuffer = val.split(''),
@ -1129,10 +959,10 @@ var FC = {
},
getServoMixInputNames: function () {
return [
'Stabilised Roll', // 0
'Stabilised Pitch', // 1
'Stabilised Yaw', // 2
'Stabilised Throttle', // 3
'Stabilized Roll', // 0
'Stabilized Pitch', // 1
'Stabilized Yaw', // 2
'Stabilized Throttle', // 3
'RC Roll', // 4
'RC Pitch', // 5
'RC Yaw', // 6
@ -1152,10 +982,17 @@ var FC = {
'RC Channel 14', // 20
'RC Channel 15', // 21
'RC Channel 16', // 22
'Stabilized Roll+', // 23
'Stabilized Roll-', // 24
'Stabilized Pitch+', // 25
'Stabilized Pitch-', // 26
'Stabilized Yaw+', // 27
'Stabilized Yaw-', // 28,
'ONE' // 29,
];
},
getServoMixInputName: function (input) {
return getServoMixInputNames()[input];
return this.getServoMixInputNames()[input];
},
getModeId: function (name) {
for (var i = 0; i < AUX_CONFIG.length; i++) {
@ -1168,6 +1005,139 @@ var FC = {
return bit_check(CONFIG.mode[Math.trunc(i / 32)], i % 32);
},
isModeEnabled: function (name) {
return FC.isModeBitSet(FC.getModeId(name));
return this.isModeBitSet(this.getModeId(name));
},
getLogicOperators: function () {
return {
0: {
name: "True",
hasOperand: [false, false]
},
1: {
name: "Equal",
hasOperand: [true, true]
},
2: {
name: "Greater Than",
hasOperand: [true, true]
},
3: {
name: "Lower Than",
hasOperand: [true, true]
},
4: {
name: "Low",
hasOperand: [true, false]
},
5: {
name: "Mid",
hasOperand: [true, false]
},
6: {
name: "High",
hasOperand: [true, false]
},
7: {
name: "AND",
hasOperand: [true, true]
},
8: {
name: "OR",
hasOperand: [true, true]
},
9: {
name: "XOR",
hasOperand: [true, true]
},
10: {
name: "NAND",
hasOperand: [true, true]
},
11: {
name: "NOR",
hasOperand: [true, true]
},
12: {
name: "NOT",
hasOperand: [true, false]
},
13: {
name: "STICKY",
hasOperand: [true, true]
}
}
},
getOperandTypes: function () {
return {
0: {
name: "Value",
type: "value",
min: -1000000,
max: 1000000,
step: 1,
default: 0
},
1: {
name: "RC Channel",
type: "range",
range: [1, 16],
default: 1
},
2: {
name: "Flight",
type: "dictionary",
default: 0,
values: {
0: "ARM timer [s]",
1: "Home distance [m]",
2: "Trip distance [m]",
3: "RSSI",
4: "Vbat [deci-Volt] [1V = 10]",
5: "Cell voltage [deci-Volt] [1V = 10]",
6: "Current [centi-Amp] [1A = 100]",
7: "Current drawn [mAh]",
8: "GPS Sats",
9: "Ground speed [cm/s]",
10: "3D speed [cm/s]",
11: "Air speed [cm/s]",
12: "Altitude [cm]",
13: "Vertical speed [cm/s]",
14: "Throttle position [%]",
15: "Roll [deg]",
16: "Pitch [deg]",
17: "Is Armed",
18: "Is Autolaunch",
19: "Is Controlling Altitude",
20: "Is Controlling Position",
21: "Is Emergency Landing",
22: "Is RTH",
23: "Is WP",
24: "Is Landing",
25: "Is Failsafe"
}
},
3: {
name: "Flight Mode",
type: "dictionary",
default: 0,
values: {
0: "Failsafe",
1: "Manual",
2: "RTH",
3: "Position Hold",
4: "Cruise",
5: "Altitude Hold",
6: "Angle",
7: "Horizon",
8: "Air"
}
},
4: {
name: "Logic Condition",
type: "range",
range: [0, 15],
default: 0
},
}
}
};

@ -0,0 +1,87 @@
/*global mspHelper,BF_CONFIG*/
'use strict';
var helper = helper || {};
/*
Helper to work with FEATURES via MSP
Usage:
1. Reset everything
helper.features.reset();
2. Push feature bits you want to set
helper.features.set(5);
3. Push feature bits you want to unset
helper.features.set(8);
4. Execute and provide a callback that will be executed after MSP is done
helper.features.execute(function () {
//Do things crap over here
});
*/
helper.features = (function() {
let publicScope = {},
privateScope = {};
let toSet = [],
toUnset = [],
exitPoint;
publicScope.reset = function () {
toSet = [];
toUnset = [];
};
publicScope.set = function (bit) {
toSet.push(bit);
};
publicScope.unset = function (bit) {
toUnset.push(bit);
};
publicScope.updateUI = function ($container, values) {
$container.find('[data-bit].feature').each(function () {
let $this = $(this);
$this.prop('checked', bit_check(values, $this.attr("data-bit")));
});
};
publicScope.fromUI = function ($container) {
$container.find('[data-bit].feature').each(function () {
let $this = $(this);
if ($this.is(":checked")) {
publicScope.set($this.attr("data-bit"));
} else {
publicScope.unset($this.attr("data-bit"));
}
});
};
publicScope.execute = function(callback) {
exitPoint = callback;
mspHelper.loadBfConfig(privateScope.setBits);
};
privateScope.setBits = function () {
for (const bit of toSet) {
BF_CONFIG.features = bit_set(BF_CONFIG.features, bit);
}
for (const bit of toUnset) {
BF_CONFIG.features = bit_clear(BF_CONFIG.features, bit);
}
mspHelper.saveBfConfig(exitPoint);
}
return publicScope;
})();

@ -4,7 +4,6 @@
var TABS = {}; // filled by individual tab js file
var GUI_control = function () {
this.auto_connect = false;
this.connecting_to = false;
this.connected_to = false;
this.connect_lock = false;
@ -14,6 +13,7 @@ var GUI_control = function () {
this.defaultAllowedTabsWhenDisconnected = [
'landing',
'firmware_flasher',
'mission_control',
'help'
];
this.defaultAllowedTabsWhenConnected = [
@ -28,12 +28,11 @@ var GUI_control = function () {
'logging',
'onboard_logging',
'modes',
'motors',
'outputs',
'pid_tuning',
'ports',
'receiver',
'sensors',
'servos',
'calibration',
'setup',
'osd',
@ -129,7 +128,7 @@ GUI_control.prototype.switchery = function() {
GUI_control.prototype.content_ready = function (callback) {
const content = $('#content').removeClass('loading');
$('.togglesmall').each(function(index, elem) {
var switchery = new Switchery(elem, {
size: 'small',
@ -191,7 +190,13 @@ GUI_control.prototype.content_ready = function (callback) {
});
});
if (callback) callback();
const duration = content.data('empty') ? 0 : 400;
$('#content .data-loading').fadeOut(duration, function() {
$(this).remove();
});
if (callback) {
callback();
}
};
GUI_control.prototype.updateStatusBar = function() {
@ -244,5 +249,15 @@ GUI_control.prototype.simpleBind = function () {
});
};
GUI_control.prototype.load = function(rel, callback) {
const content = $('#content').addClass('loading');
$.get(rel, function(data) {
$(data).appendTo(content);
if (callback) {
callback();
}
});
}
// initialize object into GUI variable
var GUI = new GUI_control();

@ -102,3 +102,14 @@ DataView.prototype.readString = function() {
}
return s;
};
DataView.prototype.asHex = function() {
let s = "";
for (let ii = 0; ii < this.byteLength; ii++) {
if (ii == this.offset) {
s += "/"
}
s += this.getUint8(ii).toString(16);
}
return s;
};

File diff suppressed because it is too large Load Diff

@ -0,0 +1,125 @@
'use strict';
var nwdialog = {
_context: (typeof global === 'undefined' || typeof global.DOMDocument === 'undefined') ? document : global.DOMDocument,
setContext: function(context) {
this._context = context;
},
openFileDialog: function(filter, multiple, workdir, callback) {
var fn = callback;
var node = this._context.createElement('input');
node.type = 'file';
node.id = 'open-file-dialog';
node.style = 'display: none';
if (typeof filter === 'function') {
fn = filter;
} else if (typeof filter === 'string') {
node.setAttribute('accept', filter);
} else if (typeof filter === 'boolean' && filter === true) {
node.setAttribute('multiple', '');
} else if (this.isArray(filter)) {
node.setAttribute('accept', filter.join(','));
}
if (typeof multiple === 'function') {
fn = multiple;
} else if (typeof multiple === 'string') {
node.setAttribute('nwworkingdir', multiple);
} else if (typeof multiple === 'boolean' && multiple === true) {
node.setAttribute('multiple', '');
}
if (typeof workdir === 'function') {
fn = workdir;
} else if (typeof workdir === 'string') {
node.setAttribute('nwworkingdir', workdir);
}
this._context.body.appendChild(node);
node.addEventListener('change', function(e) {
fn(node.value);
node.remove();
});
node.click();
},
saveFileDialog: function(name, accept, directory, callback) {
var fn = callback;
var node = this._context.createElement('input');
node.type = 'file';
node.id = 'save-file-dialog';
node.style = 'display: none';
node.setAttribute('nwsaveas', '');
if (typeof name === 'function') {
fn = name;
} else if (typeof name === 'string') {
node.setAttribute('nwsaveas', name);
}
if (typeof accept === 'function') {
fn = accept;
} else if (typeof accept === 'string') {
node.setAttribute('accept', accept);
} else if (this.isArray(accept)) {
node.setAttribute('accept', accept.join(','));
}
if (typeof directory === 'function') {
fn = directory;
} else if (typeof directory === 'string') {
node.setAttribute('nwworkingdir', directory);
}
this._context.body.appendChild(node);
node.addEventListener('change', function() {
fn(node.value);
node.remove();
});
node.click();
},
folderBrowserDialog: function(workdir, callback) {
var fn = callback;
var node = this._context.createElement('input');
node.type = 'file';
node.id = 'folder-browser-dialog';
node.style = 'display: none';
node.nwdirectory= true;
if (typeof workdir === 'function') {
fn = workdir
} else if (typeof workdir === 'string') {
node.setAttribute('nwworkingdir', workdir);
}
this._context.body.appendChild(node);
node.addEventListener('change', function() {
fn(node.value);
node.remove();
});
node.click();
},
isArray: function(value) {
return Object.prototype.toString.call(value) === '[object Array]';
}
}
if (typeof nw !== 'undefined') {
if (typeof exports == 'undefined') {
nw.Dialog = nwdialog;
window.dialog = nwdialog;
} else {
module.exports = nwdialog;
}
}

@ -19,8 +19,12 @@ function localize() {
$('[data-i18n]:not(.i18n-replaced)').each(function() {
var element = $(this);
element.html(translate(element.data('i18n')));
const translated = translate(element.data('i18n'));
element.html(translated);
element.addClass('i18n-replaced');
if (element.attr("title") !== "") {
element.attr("title", translated);
}
});
$('[i18n_title]:not(.i18n_title-replaced)').each(function() {

@ -0,0 +1,253 @@
/*global $,FC*/
'use strict';
let LogicCondition = function (enabled, operation, operandAType, operandAValue, operandBType, operandBValue, flags) {
let self = {};
let $row;
self.getEnabled = function () {
return !!enabled;
};
self.setEnabled = function (data) {
enabled = !!data;
};
self.getOperation = function () {
return operation;
};
self.setOperation = function (data) {
operation = data;
};
self.getOperandAType = function () {
return operandAType;
};
self.setOperandAType = function (data) {
operandAType = data;
};
self.getOperandAValue = function () {
return operandAValue;
};
self.setOperandAValue = function (data) {
operandAValue = data;
};
self.getOperandBType = function () {
return operandBType;
};
self.setOperandBType = function (data) {
operandBType = data;
};
self.getOperandBValue = function () {
return operandBValue;
};
self.setOperandBValue = function (data) {
operandBValue = data;
};
self.getFlags = function () {
return flags;
};
self.setFlags = function (data) {
flags = data;
};
self.onEnabledChange = function (event) {
let $cT = $(event.currentTarget);
self.setEnabled(!!$cT.prop('checked'));
};
self.getOperatorMetadata = function () {
return FC.getLogicOperators()[self.getOperation()];
};
self.hasOperand = function (val) {
return self.getOperatorMetadata().hasOperand[val];
};
self.onOperatorChange = function (event) {
let $cT = $(event.currentTarget);
self.setOperation($cT.val());
self.setOperandAType(0);
self.setOperandBType(0);
self.setOperandAValue(0);
self.setOperandBValue(0);
self.renderOperand(0);
self.renderOperand(1);
};
self.onOperatorTypeChange = function (event) {
let $cT = $(event.currentTarget),
operand = $cT.data("operand"),
$container = $cT.parent(),
operandMetadata = FC.getOperandTypes()[$cT.val()];
if (operand == 0) {
self.setOperandAType($cT.val());
self.setOperandAValue(operandMetadata.default);
} else {
self.setOperandBType($cT.val());
self.setOperandBValue(operandMetadata.default);
}
self.renderOperandValue($container, operandMetadata, operand, operandMetadata.default);
};
self.onOperatorValueChange = function (event) {
let $cT = $(event.currentTarget),
operand = $cT.data("operand");
if (operand == 0) {
self.setOperandAValue($cT.val());
} else {
self.setOperandBValue($cT.val());
}
};
self.renderOperandValue = function ($container, operandMetadata, operand, value) {
$container.find('.logic_element__operand--value').remove();
switch (operandMetadata.type) {
case "value":
$container.append('<input type="number" class="logic_element__operand--value" data-operand="' + operand + '" step="' + operandMetadata.step + '" min="' + operandMetadata.min + '" max="' + operandMetadata.max + '" value="' + value + '" />');
break;
case "range":
case "dictionary":
$container.append('<select class="logic_element__operand--value" data-operand="' + operand + '"></select>');
let $t = $container.find('.logic_element__operand--value');
if (operandMetadata.type == "range") {
for (let i = operandMetadata.range[0]; i <= operandMetadata.range[1]; i++) {
$t.append('<option value="' + i + '">' + i + '</option>');
}
} else if (operandMetadata.type == "dictionary") {
for (let k in operandMetadata.values) {
if (operandMetadata.values.hasOwnProperty(k)) {
$t.append('<option value="' + k + '">' + operandMetadata.values[k] + '</option>');
}
}
}
$t.val(value);
break;
}
$container.find('.logic_element__operand--value').change(self.onOperatorValueChange);
};
self.renderOperand = function (operand) {
let type, value, $container;
if (operand == 0) {
type = operandAType;
value = operandAValue;
$container = $row.find('.logic_cell__operandA');
} else {
type = operandBType;
value = operandBValue;
$container = $row.find('.logic_cell__operandB');
}
$container.html('');
if (self.hasOperand(operand)) {
$container.append('<select class="logic_element__operand--type" data-operand="' + operand + '"></select>');
let $t = $container.find('.logic_element__operand--type');
for (let k in FC.getOperandTypes()) {
if (FC.getOperandTypes().hasOwnProperty(k)) {
let op = FC.getOperandTypes()[k];
if (type == k) {
$t.append('<option value="' + k + '" selected>' + op.name + '</option>');
/*
* Render value element depending on type
*/
self.renderOperandValue($container, op, operand, value);
} else {
$t.append('<option value="' + k + '">' + op.name + '</option>');
}
}
}
/*
* Bind events
*/
$t.change(self.onOperatorTypeChange);
}
}
self.update = function (index, value, $container) {
if (typeof $row === 'undefined') {
return;
}
let $marker = $row.find('.logic_cell__active_marker');
if (!!value) {
$marker.addClass("logic_cell__active_marker--active");
$marker.removeClass("logic_cell__active_marker--inactive");
} else {
$marker.removeClass("logic_cell__active_marker--active");
$marker.addClass("logic_cell__active_marker--inactive");
}
}
self.render = function (index, $container) {
$container.find('tbody').append('<tr>\
<td class="logic_cell__index"></td>\
<td class="logic_cell__enabled"></td>\
<td class="logic_cell__operation"></td>\
<td class="logic_cell__operandA"></td>\
<td class="logic_cell__operandB"></td>\
<td class="logic_cell__flags"><div class="logic_cell__active_marker"></div></td>\
</tr>\
');
$row = $container.find('tr:last');
$row.find('.logic_cell__index').html(index);
$row.find('.logic_cell__enabled').html("<input type='checkbox' class='toggle logic_element__enabled' />");
$row.find('.logic_element__enabled').
prop('checked', self.getEnabled()).
change(self.onEnabledChange);
/*
* Operator select
*/
$row.find('.logic_cell__operation').html("<select class='logic_element__operation' ></select>");
let $t = $row.find('.logic_element__operation');
for (let k in FC.getLogicOperators()) {
if (FC.getLogicOperators().hasOwnProperty(k)) {
let o = FC.getLogicOperators()[k];
if (self.getOperation() == parseInt(k, 10)) {
$t.append('<option value="' + k + '" selected>' + o.name + '</option>');
} else {
$t.append('<option value="' + k + '">' + o.name + '</option>');
}
}
}
$t.change(self.onOperatorChange);
self.renderOperand(0);
self.renderOperand(1);
}
return self;
};

@ -0,0 +1,87 @@
'use strict';
let LogicConditionsCollection = function () {
let self = {},
data = [],
$container;
self.put = function (element) {
data.push(element);
};
self.get = function () {
return data;
};
self.flush = function () {
data = [];
};
self.getCount = function () {
return data.length
};
self.open = function () {
if (semver.lt(CONFIG.flightControllerVersion, "2.2.0")) {
return;
}
self.render();
$container.show();
};
self.render = function () {
let $table = $container.find(".logic__table")
$table.find("tbody tr").remove();
for (let k in self.get()) {
if (self.get().hasOwnProperty(k)) {
self.get()[k].render(k, $table);
}
}
GUI.switchery();
};
self.onSave = function () {
let chain = new MSPChainerClass()
chain.setChain([
mspHelper.sendLogicConditions,
mspHelper.saveToEeprom
]);
chain.execute();
};
self.onClose = function() {
$container.hide();
};
self.init = function ($element) {
if (semver.lt(CONFIG.flightControllerVersion, "2.2.0")) {
return;
}
$container = $element;
$container.find('.logic__save').click(self.onSave);
$container.find('.logic__close').click(self.onClose);
};
self.update = function(statuses) {
let $table = $container.find(".logic__table")
for (let k in self.get()) {
if (self.get().hasOwnProperty(k)) {
self.get()[k].update(k, statuses.get(k), $table);
}
}
}
return self;
};

@ -0,0 +1,25 @@
'use strict';
let LogicConditionsStatus = function () {
let self = {},
data = [];
self.set = function (condition, value) {
data[condition] = value;
}
self.get = function (condition) {
if (typeof data[condition] !== 'undefined') {
return data[condition];
} else {
return null;
}
}
self.getAll = function() {
return data;
}
return self;
};

@ -517,6 +517,52 @@ const mixerList = [
new ServoMixRule(3, INPUT_STABILIZED_YAW, 50, 0),
new ServoMixRule(4, INPUT_STABILIZED_YAW, 50, 0),
]
},
{
id: 31,
name: 'Rover',
model: 'custom',
image: 'custom',
enabled: true,
legacy: false,
platform: PLATFORM_ROVER,
motorMixer: [
new MotorMixRule(1.0, 0.0, 0.0, 0.0),
],
servoMixer: [
new ServoMixRule(3, INPUT_STABILIZED_YAW, 100, 0),
]
},
{
id: 32,
name: 'Boat',
model: 'custom',
image: 'custom',
enabled: true,
legacy: false,
platform: PLATFORM_BOAT,
motorMixer: [
new MotorMixRule(1.0, 0.0, 0.0, 0.0),
],
servoMixer: [
new ServoMixRule(3, INPUT_STABILIZED_YAW, 100, 0),
]
}
,
{
id: 33,
name: 'Other',
model: 'custom',
image: 'custom',
enabled: true,
legacy: false,
platform: PLATFORM_OTHER,
motorMixer: [
new MotorMixRule(1.0, 0.0, 0.0, 0.0),
],
servoMixer: [
new ServoMixRule(3, INPUT_STABILIZED_YAW, 100, 0),
]
}
];
@ -548,19 +594,19 @@ const platformList = [
{
id: 4,
name: "Rover",
enabled: false,
enabled: true,
flapsPossible: false
},
{
id: 5,
name: "Boat",
enabled: false,
enabled: true,
flapsPossible: false
},
{
id: 6,
name: "Other",
enabled: false,
enabled: true,
flapsPossible: false
}
];

@ -194,5 +194,23 @@ var MSPCodes = {
MSP2_INAV_SELECT_BATTERY_PROFILE: 0x2018,
MSP2_INAV_DEBUG: 0x2019
MSP2_INAV_DEBUG: 0x2019,
MSP2_BLACKBOX_CONFIG: 0x201A,
MSP2_SET_BLACKBOX_CONFIG: 0x201B,
MSP2_INAV_TEMP_SENSOR_CONFIG: 0x201C,
MSP2_INAV_SET_TEMP_SENSOR_CONFIG: 0x201D,
MSP2_INAV_TEMPERATURES: 0x201E,
MSP2_INAV_SERVO_MIXER: 0x2020,
MSP2_INAV_SET_SERVO_MIXER: 0x2021,
MSP2_INAV_LOGIC_CONDITIONS: 0x2022,
MSP2_INAV_SET_LOGIC_CONDITIONS: 0x2023,
MSP2_INAV_LOGIC_CONDITIONS_STATUS: 0x2026,
MSP2_PID: 0x2030,
MSP2_SET_PID: 0x2031,
MSP2_INAV_OPFLOW_CALIBRATION: 0x2032
};

File diff suppressed because it is too large Load Diff

@ -16,6 +16,66 @@ let OutputMappingCollection = function () {
const TIM_USE_LED = 24;
const TIM_USE_BEEPER = 25;
const OUTPUT_TYPE_MOTOR = 0;
const OUTPUT_TYPE_SERVO = 1;
function getTimerMap(isMR, motors, servos) {
let timerMap = [],
motorsToGo = motors,
servosToGo = servos;
for (let i = 0; i < data.length; i++) {
timerMap[i] = null;
if (isMR) {
if (servosToGo > 0 && bit_check(data[i], TIM_USE_MC_SERVO)) {
servosToGo--;
timerMap[i] = OUTPUT_TYPE_SERVO;
} else if (motorsToGo > 0 && bit_check(data[i], TIM_USE_MC_MOTOR)) {
motorsToGo--;
timerMap[i] = OUTPUT_TYPE_MOTOR;
}
} else {
if (servosToGo > 0 && bit_check(data[i], TIM_USE_FW_SERVO)) {
servosToGo--;
timerMap[i] = OUTPUT_TYPE_SERVO;
} else if (motorsToGo > 0 && bit_check(data[i], TIM_USE_FW_MOTOR)) {
motorsToGo--;
timerMap[i] = OUTPUT_TYPE_MOTOR;
}
}
}
return timerMap;
};
self.getOutputTable = function (isMR, motors, servos) {
let currentMotorIndex = 1,
currentServoIndex = 0,
timerMap = getTimerMap(isMR, motors, servos.length),
outputMap = [],
offset = getFirstOutputOffset();
for (let i = 0; i < self.getOutputCount(); i++) {
let assignment = timerMap[i + offset];
if (assignment === null) {
outputMap[i] = "-";
} else if (assignment == OUTPUT_TYPE_MOTOR) {
outputMap[i] = "Motor " + currentMotorIndex;
currentMotorIndex++;
} else if (assignment == OUTPUT_TYPE_SERVO) {
outputMap[i] = "Servo " + servos[currentServoIndex];
currentServoIndex++;
}
}
return outputMap;
};
self.flush = function () {
data = [];
};
@ -78,14 +138,6 @@ let OutputMappingCollection = function () {
return getOutput(servoIndex, TIM_USE_FW_SERVO);
};
self.getFwMotorOutput = function (index) {
return getOutput(index, TIM_USE_FW_MOTOR);
};
self.getMrMotorOutput = function (index) {
return getOutput(index, TIM_USE_MC_MOTOR);
};
self.getMrServoOutput = function (index) {
return getOutput(index, TIM_USE_MC_SERVO);
};

@ -19,15 +19,11 @@ helper.periodicStatusUpdater = (function () {
}
if (baudSpeed >= 115200) {
return 200;
return 300;
} else if (baudSpeed >= 57600) {
return 400;
} else if (baudSpeed >= 38400) {
return 500;
} else if (baudSpeed >= 19200) {
return 600;
} else if (baudSpeed >= 9600) {
return 750;
} else if (baudSpeed >= 38400) {
return 800;
} else {
return 1000;
}
@ -57,29 +53,15 @@ helper.periodicStatusUpdater = (function () {
if (ANALOG != undefined) {
var nbCells;
if (semver.gte(CONFIG.flightControllerVersion, '1.8.1')) {
nbCells = ANALOG.cell_count;
} else {
nbCells = Math.floor(ANALOG.voltage / MISC.vbatmaxcellvoltage) + 1;
if (ANALOG.voltage == 0)
nbCells = 1;
}
nbCells = ANALOG.cell_count;
var min = MISC.vbatmincellvoltage * nbCells;
var max = MISC.vbatmaxcellvoltage * nbCells;
var warn = MISC.vbatwarningcellvoltage * nbCells;
if (semver.gte(CONFIG.flightControllerVersion, '1.8.1')) {
$(".battery-status").css({
width: ANALOG.battery_percentage + "%",
display: 'inline-block'
});
} else {
$(".battery-status").css({
width: ((ANALOG.voltage - min) / (max - min) * 100) + "%",
display: 'inline-block'
});
}
$(".battery-status").css({
width: ANALOG.battery_percentage + "%",
display: 'inline-block'
});
if (active) {
$(".linkicon").css({
@ -91,7 +73,7 @@ helper.periodicStatusUpdater = (function () {
});
}
if (((semver.gte(CONFIG.flightControllerVersion, '1.8.1')) && (((ANALOG.use_capacity_thresholds) && (ANALOG.battery_remaining_capacity <= (MISC.battery_capacity_warning - MISC.battery_capacity_critical))) || ((!ANALOG.use_capacity_thresholds) && (ANALOG.voltage < warn))) || (ANALOG.voltage < min)) || ((semver.lt(CONFIG.flightControllerVersion, '1.8.1')) && (ANALOG.voltage < warn))) {
if (((ANALOG.use_capacity_thresholds && ANALOG.battery_remaining_capacity <= MISC.battery_capacity_warning - MISC.battery_capacity_critical) || (!ANALOG.use_capacity_thresholds && ANALOG.voltage < warn)) || ANALOG.voltage < min) {
$(".battery-status").css('background-color', '#D42133');
} else {
$(".battery-status").css('background-color', '#59AA29');
@ -119,23 +101,10 @@ helper.periodicStatusUpdater = (function () {
return;
}
if (semver.gte(CONFIG.flightControllerVersion, "1.5.0")) {
MSP.send_message(MSPCodes.MSP_SENSOR_STATUS, false, false);
}
if (semver.gte(CONFIG.flightControllerVersion, "2.0.0")) {
MSP.send_message(MSPCodes.MSPV2_INAV_STATUS, false, false);
} else {
MSP.send_message(MSPCodes.MSP_STATUS_EX, false, false);
}
MSP.send_message(MSPCodes.MSP_SENSOR_STATUS, false, false);
MSP.send_message(MSPCodes.MSPV2_INAV_STATUS, false, false);
MSP.send_message(MSPCodes.MSP_ACTIVEBOXES, false, false);
if (semver.gte(CONFIG.flightControllerVersion, '1.8.1')) {
MSP.send_message(MSPCodes.MSPV2_INAV_ANALOG, false, false);
} else {
MSP.send_message(MSPCodes.MSP_ANALOG, false, false);
}
MSP.send_message(MSPCodes.MSPV2_INAV_ANALOG, false, false);
privateScope.updateView();
}

@ -121,16 +121,6 @@ PortHandler.check = function () {
$('div#port-picker #port').val(GUI.connected_to);
}
// start connect procedure (if statement is valid)
if (GUI.auto_connect && !GUI.connecting_to && !GUI.connected_to) {
// we need firmware flasher protection over here
if (GUI.active_tab != 'firmware_flasher') {
helper.timeout.add('auto-connect_timeout', function () {
$('div#port-picker a.connect').click();
}, 100); // timeout so bus have time to initialize after being detected by the system
}
}
// trigger callbacks
for (var i = (self.port_detected_callbacks.length - 1); i >= 0; i--) {
var obj = self.port_detected_callbacks[i];

File diff suppressed because it is too large Load Diff

@ -100,25 +100,45 @@ STM32_protocol.prototype.connect = function (port, baud, hex, options, callback)
serial.send(bufferOut, function () {
serial.disconnect(function (result) {
if (result) {
// delay to allow board to boot in bootloader mode
// required to detect if a DFU device appears
setTimeout(function() {
// refresh device list
var intervalMs = 200;
var retries = 0;
var maxRetries = 50; // timeout after intervalMs * 50
var interval = setInterval(function() {
var tryFailed = function() {
retries++;
if (retries > maxRetries) {
clearInterval(interval);
GUI.log('<span style="color: red">Failed</span> to flash ' + port);
}
}
// Check for DFU devices
PortHandler.check_usb_devices(function(dfu_available) {
if(dfu_available) {
if (dfu_available) {
clearInterval(interval);
STM32DFU.connect(usbDevices.STM32DFU, hex, options);
} else {
serial.connect(port, {bitrate: self.baud, parityBit: 'even', stopBits: 'one'}, function (openInfo) {
if (openInfo) {
self.initialize();
} else {
GUI.connect_lock = false;
GUI.log('<span style="color: red">Failed</span> to open serial port');
}
});
return;
}
// Check for the serial port
serial.getDevices(function(devices) {
if (devices && devices.includes(port)) {
// Serial port might briefly reappear on DFU devices while
// the FC is rebooting, so we don't clear the interval
// until we succesfully connect.
serial.connect(port, {bitrate: self.baud, parityBit: 'even', stopBits: 'one'}, function (openInfo) {
if (openInfo) {
clearInterval(interval);
self.initialize();
} else {
GUI.connect_lock = false;
tryFailed();
}
});
return;
}
tryFailed();
});
});
}, 1000);
}, intervalMs);
} else {
GUI.connect_lock = false;
}

@ -300,9 +300,9 @@ var serial = {
*/
getTimeout: function () {
if (serial.bitrate >= 57600) {
return 1500;
return 3000;
} else {
return 2500;
return 4000;
}
}

@ -22,7 +22,18 @@ $(document).ready(function () {
GUI.handleReconnect = function ($tabElement) {
if (BOARD.find_board_definition(CONFIG.boardIdentifier).vcp) { // VCP-based flight controls may crash old drivers, we catch and reconnect
let modal;
if (BOARD.hasVcp(CONFIG.boardIdentifier)) { // VCP-based flight controls may crash old drivers, we catch and reconnect
modal = new jBox('Modal', {
width: 400,
height: 100,
animation: false,
closeOnClick: false,
closeOnEsc: false,
content: $('#modal-reconnect')
}).open();
/*
Disconnect
@ -35,6 +46,7 @@ $(document).ready(function () {
Connect again
*/
setTimeout(function start_connection() {
modal.close();
$('a.connect').click();
/*
@ -46,7 +58,7 @@ $(document).ready(function () {
}, 500);
}
}, 5000);
}, 7000);
} else {
helper.timeout.add('waiting_for_bootup', function waiting_for_bootup() {
@ -141,9 +153,7 @@ $(document).ready(function () {
// unlock port select & baud
$port.prop('disabled', false);
if (!GUI.auto_connect) {
$baud.prop('disabled', false);
}
$baud.prop('disabled', false);
// reset connect / disconnect button
$('div.connect_controls a.connect').removeClass('active');
@ -165,45 +175,6 @@ $(document).ready(function () {
}
});
// auto-connect
chrome.storage.local.get('auto_connect', function (result) {
if (result.auto_connect === 'undefined' || result.auto_connect) {
// default or enabled by user
GUI.auto_connect = true;
$('input.auto_connect').prop('checked', true);
$('input.auto_connect, span.auto_connect').prop('title', chrome.i18n.getMessage('autoConnectEnabled'));
$baud.val(115200).prop('disabled', true);
} else {
// disabled by user
GUI.auto_connect = false;
$('input.auto_connect').prop('checked', false);
$('input.auto_connect, span.auto_connect').prop('title', chrome.i18n.getMessage('autoConnectDisabled'));
}
// bind UI hook to auto-connect checkbos
$('input.auto_connect').change(function () {
GUI.auto_connect = $(this).is(':checked');
// update title/tooltip
if (GUI.auto_connect) {
$('input.auto_connect, span.auto_connect').prop('title', chrome.i18n.getMessage('autoConnectEnabled'));
$baud.val(115200).prop('disabled', true);
} else {
$('input.auto_connect, span.auto_connect').prop('title', chrome.i18n.getMessage('autoConnectDisabled'));
if (!GUI.connected_to && !GUI.connecting_to) $('select#baud').prop('disabled', false);
}
chrome.storage.local.set({'auto_connect': GUI.auto_connect});
});
});
PortHandler.initialize();
});
@ -228,6 +199,10 @@ function onValidFirmware()
GUI.allowedTabs = GUI.defaultAllowedTabsWhenConnected.slice();
onConnect();
if (semver.gte(CONFIG.flightControllerVersion, "2.3.0")) {
helper.defaultsDialog.init();
}
$('#tabs ul.mode-connected .tab_setup a').click();
});
});
@ -245,7 +220,7 @@ function onInvalidFirmwareVariant()
function onInvalidFirmwareVersion()
{
GUI.log(chrome.i18n.getMessage('firmwareVersionNotSupported', [CONFIGURATOR.firmwareVersionAccepted]));
GUI.log(chrome.i18n.getMessage('firmwareVersionNotSupported', [CONFIGURATOR.minfirmwareVersionAccepted, CONFIGURATOR.maxFirmwareVersionAccepted]));
CONFIGURATOR.connectionValid = true; // making it possible to open the CLI tab
GUI.allowedTabs = ['cli'];
onConnect();
@ -305,7 +280,7 @@ function onOpen(openInfo) {
MSP.send_message(MSPCodes.MSP_FC_VERSION, false, false, function () {
googleAnalytics.sendEvent('Firmware', 'Variant', CONFIG.flightControllerIdentifier + ',' + CONFIG.flightControllerVersion);
GUI.log(chrome.i18n.getMessage('fcInfoReceived', [CONFIG.flightControllerIdentifier, CONFIG.flightControllerVersion]));
if (semver.gte(CONFIG.flightControllerVersion, CONFIGURATOR.firmwareVersionAccepted)) {
if (semver.gte(CONFIG.flightControllerVersion, CONFIGURATOR.minfirmwareVersionAccepted) && semver.lt(CONFIG.flightControllerVersion, CONFIGURATOR.maxFirmwareVersionAccepted)) {
mspHelper.getCraftName(function(name) {
if (name) {
CONFIG.name = name;
@ -356,6 +331,19 @@ function onConnect() {
*/
MSP.send_message(MSPCodes.MSP_BOXNAMES, false, false);
/*
* Init PIDs bank with a length that depends on the version
*/
let pidCount;
if (semver.gte(CONFIG.flightControllerVersion, "2.5.0")) {
pidCount = 11;
} else {
pidCount = 10;
}
for (let i = 0; i < pidCount; i++) {
PIDs.push(new Array(4));
}
helper.interval.add('msp-load-update', function () {
$('#msp-version').text("MSP version: " + MSP.protocolVersion.toFixed(0));
$('#msp-load').text("MSP load: " + helper.mspQueue.getLoad().toFixed(1));

@ -1,7 +1,7 @@
/*global $*/
'use strict';
var ServoMixRule = function (target, input, rate, speed) {
let ServoMixRule = function (target, input, rate, speed, condition) {
var self = {};
@ -41,5 +41,13 @@ var ServoMixRule = function (target, input, rate, speed) {
return rate !== 0;
};
self.getConditionId = function () {
return (condition == undefined) ? -1 : condition;
};
self.setConditionId = function (data) {
condition = data;
};
return self;
};

@ -1,11 +1,11 @@
/*global ServoMixRule*/
'use strict';
var ServoMixerRuleCollection = function () {
let ServoMixerRuleCollection = function () {
let self = {},
data = [],
maxServoCount = 8;
maxServoCount = 16;
self.setServoCount = function (value) {
maxServoCount = value;
@ -70,6 +70,31 @@ var ServoMixerRuleCollection = function () {
}
}
return false;
};
self.getNumberOfConfiguredServos = function () {
let count = 0;
for (let i = 0; i < self.getServoCount(); i ++) {
if (self.isServoConfigured(i)) {
count++;
}
}
return count;
};
self.getUsedServoIndexes = function () {
let out = [];
for (let ruleIndex in data) {
if (data.hasOwnProperty(ruleIndex)) {
let rule = data[ruleIndex];
out.push(rule.getTarget());
}
}
return jQuery.unique(out).sort(function(a, b){
return a-b;
});
}
return self;

@ -50,6 +50,20 @@ var Settings = (function () {
}
} else if (s.setting.type == 'string') {
input.val(s.value);
} else if (s.setting.type == 'float') {
input.attr('type', 'number');
let dataStep = input.data("step");
if (dataStep !== undefined) {
input.attr('step', dataStep);
} else {
input.attr('step', "0.01");
}
input.attr('min', s.setting.min);
input.attr('max', s.setting.max);
input.val(s.value.toFixed(2));
} else {
var multiplier = parseFloat(input.data('setting-multiplier') || 1);
input.attr('type', 'number');
@ -72,6 +86,11 @@ var Settings = (function () {
var settingName = input.data('setting');
var setting = input.data('setting-info');
var value;
if (typeof setting == 'undefined') {
return null;
}
if (setting.table) {
if (input.attr('type') == 'checkbox') {
value = input.prop('checked') ? 1 : 0;

@ -0,0 +1,27 @@
'use strict';
var helper = helper || {};
helper.tabs = (function () {
let self = {},
$container;
function onHeaderClick(event) {
let $cT = $(event.currentTarget),
attrFor = $cT.attr("for");
$container.find('.subtab__header_label').removeClass("subtab__header_label--current");
$cT.addClass("subtab__header_label--current");
$container.find(".subtab__content--current").removeClass("subtab__content--current");
$container.find("#" + attrFor).addClass("subtab__content--current");
};
self.init = function ($dom) {
$container = $dom;
$container.find(".subtab__header_label").click(onHeaderClick);
};
return self;
})();

@ -15,9 +15,7 @@ helper.task = (function () {
publicScope.statusPullStart = function () {
helper.interval.add('status_pull', function () {
MSP.send_message(MSPCodes.MSP_STATUS, false, false, function () {
if (semver.gte(CONFIG.flightControllerVersion, "1.5.0")) {
MSP.send_message(MSPCodes.MSP_SENSOR_STATUS);
}
MSP.send_message(MSPCodes.MSP_SENSOR_STATUS);
});
}, privateScope.getStatusPullInterval(), true);

@ -24,10 +24,10 @@ var VTX = (function() {
}
self.getMaxPower = function(vtxDev) {
if (vtxDev == self.DEV_SMARTAUDIO) {
return 4;
if ((vtxDev == self.DEV_SMARTAUDIO) || (vtxDev == self.DEV_TRAMP)) {
return 5;
}
return 5;
return 3;
}
self.LOW_POWER_DISARM_MIN = 0;

@ -101,6 +101,14 @@ input[type="number"]::-webkit-inner-spin-button {
height: calc(100% - 7px);
}
.mt1em {
margin-top: 1em !important;
}
.mb1em {
margin-bottom: 1em !important;
}
.margin-top {
margin-top: 20px;
}
@ -228,10 +236,6 @@ input[type="number"]::-webkit-inner-spin-button {
width: 136px;
}
#port-picker .auto_connect {
color: #ddd;
}
#header_dataflash {
display: none;
}
@ -981,6 +985,14 @@ li.active .ic_mixer {
/* Cause the height to shrink to contain its floated contents while log is open */
}
#content.loading {
overflow-y: hidden;
}
#content.loading > * {
opacity: 0;
}
#status-bar {
position: fixed;
bottom: 0;
@ -1011,9 +1023,17 @@ li.active .ic_mixer {
}
.data-loading {
z-index: 10000;
position: absolute;
top: 0;
width: 100%;
height: 100%;
background: url('../images/loading-bars.svg') no-repeat center 45%;
background-color: #FFF;
}
#content.loading .data-loading {
opacity: 1;
}
.data-loading p {
@ -1046,6 +1066,15 @@ dialog {
margin-bottom: 15px;
}
.tab_subtitle {
border-bottom: 1px solid #37a8db;
font-size: 1.5em;
line-height: 1.5em;
height: 25px;
font-family: 'open_sanslight', Arial, serif;
margin-bottom: 8px;
}
/* Note */
.note {
background-color: #fff7cd;
@ -1284,7 +1313,6 @@ dialog {
width: 100%;
height: 27px;
padding-bottom: 0;
float: left;
margin-bottom: 7px;
font-family: 'open_sanssemibold', Arial, serif;
}
@ -1446,15 +1474,16 @@ dialog {
transition: all ease 0.2s;
}
.red a {
/* background-color: #37a8db; */
.btn.red a,
.btn.red a:active {
background-color: #fafafa;
text-shadow: 0 1px rgba(0, 0, 0, 0.25);
color: #ff1e1e;
border: 1px solid #a00000;
transition: all ease 0.2s;
}
.red a:hover {
.btn.red a:hover {
background-color: #f86975;
border: 1px solid #a00000;
text-shadow: 0 1px rgba(0, 0, 0, 0.25);
@ -2049,3 +2078,73 @@ select {
.text-center {
text-align: center;
}
.warning-box {
background-color: red;
color: white;
font-weight: bold;
margin: 0.4em 0;
padding: 1em;
clear: both;
}
.info-box {
background-color: darkgoldenrod;
color: white;
font-weight: bold;
margin: 0.4em 0;
padding: 1em;
clear: both;
}
.ok-box {
background-color: green;
color: white;
font-weight: bold;
margin: 0.4em 0;
padding: 1em;
clear: both;
}
#modal-reconnect {
/* width: 100%; */
height: 90px;
background: url(../images/loading-bars.svg) no-repeat center 100%;
}
#modal-reconnect div {
text-align: center;
}
.subtab__header {
padding: 0;
height: auto;
}
.subtab__header_label {
display: inline-block;
padding: 0 1em;
background-color: #eee;
min-width: 7em;
height: 1.5em;
line-height: 1.5em;
cursor: pointer;
font-size: 18px;
}
.subtab__header_label--current {
font-weight: bold;
background-color: #ccc;
}
.subtab__header_label:hover {
background-color: #c5c5c5;
}
.subtab__content {
display: none;
}
.subtab__content--current {
display: block;
}

@ -1,56 +1,57 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<link type="text/css" rel="stylesheet" href="./build/styles.css" media="all"/>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link type="text/css" rel="stylesheet" href="./build/styles.css" media="all" />
<script type="text/javascript" src="./build/script.js"></script>
<title></title>
</head>
<body>
<div id="main-wrapper">
<div id="appUpdateNotification" class="is-hidden">
<div class="modal__content">
<h1 class="modal__title modal__title" data-i18n="appUpdateNotificationHeader"></h1>
<div class="modal__text" data-i18n="appUpdateNotificationDescription"></div>
</div>
<div class="modal__buttons modal__buttons--upbottom">
<a href="https://github.com/iNavFlight/inav-configurator/releases" target="_blank" id="update-notification-download"
class="modal__button modal__button--main modal__button--main--inline" data-i18n="downloadUpdatesBtn"></a>
<a id="update-notification-close" class="modal__button modal__button--main modal__button--main--inline" data-i18n="closeUpdateBtn"></a>
</div>
</div>
<div class="headerbar">
<div id="logo">
<div class="logo_text">
CONFIGURATOR
<div class="version"></div>
<div id="main-wrapper">
<div id="appUpdateNotification" class="is-hidden">
<div class="modal__content">
<h1 class="modal__title modal__title" data-i18n="appUpdateNotificationHeader"></h1>
<div class="modal__text" data-i18n="appUpdateNotificationDescription"></div>
</div>
<div class="modal__buttons modal__buttons--upbottom">
<a href="https://github.com/iNavFlight/inav-configurator/releases" target="_blank" id="update-notification-download" class="modal__button modal__button--main modal__button--main--inline" data-i18n="downloadUpdatesBtn"></a>
<a id="update-notification-close" class="modal__button modal__button--main modal__button--main--inline" data-i18n="closeUpdateBtn"></a>
</div>
</div>
<a id="options" href="#" data-i18n_title="options_title"></a>
<div id="port-picker">
<div class="connect_controls" id="connectbutton">
<div class="connect_b">
<a class="connect" href="#"></a>
<div class="headerbar">
<div id="logo">
<div class="logo_text">
CONFIGURATOR
<div class="version"></div>
</div>
<a class="connect_state" data-i18n="connect"></a>
</div>
<div id="portsinput">
<div class="portsinput__row">
<div id="port-override-option" class="portsinput__top-element portsinput__top-element--port-override">
<label for="port-override">Port: </label>
<input id="port-override" type="text" value="/dev/rfcomm0"/>
<a id="options" href="#" data-i18n_title="options_title"></a>
<div id="port-picker">
<div class="connect_controls" id="connectbutton">
<div class="connect_b">
<a class="connect" href="#"></a>
</div>
<div class="dropdown dropdown-dark portsinput__top-element">
<!--suppress HtmlFormInputWithoutLabel -->
<select class="dropdown-select" id="port" title="Port">
<a class="connect_state" data-i18n="connect"></a>
</div>
<div id="portsinput">
<div class="portsinput__row">
<div id="port-override-option" class="portsinput__top-element portsinput__top-element--port-override">
<label for="port-override">Port: </label>
<input id="port-override" type="text" value="/dev/rfcomm0" />
</div>
<div class="dropdown dropdown-dark portsinput__top-element">
<!--suppress HtmlFormInputWithoutLabel -->
<select class="dropdown-select" id="port" title="Port">
<option value="manual">Manual</option>
<!-- port list gets generated here -->
</select>
</div>
<div class="dropdown dropdown-dark portsinput__top-element">
<!--suppress HtmlFormInputWithoutLabel -->
<select class="dropdown-select" id="baud" title="Baud Rate">
</div>
<div class="dropdown dropdown-dark portsinput__top-element">
<!--suppress HtmlFormInputWithoutLabel -->
<select class="dropdown-select" id="baud" title="Baud Rate">
<option value="115200" selected="selected">115200</option>
<option value="57600">57600</option>
<option value="38400">38400</option>
@ -62,202 +63,243 @@
<option value="2400">2400</option>
<option value="1200">1200</option>
</select>
</div>
</div>
</div>
<div class="portsinput__row">
<div class="portsinput__top-element portsinput__top-element--inline">
<label for="wireless-mode">
<div class="portsinput__row">
<div class="portsinput__top-element portsinput__top-element--inline">
<label for="wireless-mode">
<span class="" data-i18n="wirelessModeSwitch"></span>
</label>
<input id="wireless-mode" class=" togglesmall" type="checkbox"/>
</div>
<div class="portsinput__top-element portsinput__top-element--inline">
<label for="auto-connect">
<span class="auto_connect" data-i18n="autoConnect"></span>
</label>
<input id="auto-connect" class="auto_connect togglesmall" type="checkbox"/>
<input id="wireless-mode" class=" togglesmall" type="checkbox" />
</div>
</div>
</div>
</div>
</div>
<div class="header-wrapper">
<div id="dataflash_wrapper_global">
<div class="noflash_global" align="center">No dataflash <br>chip found</div>
<ul class="dataflash-contents_global">
<li class="dataflash-free_global">
<div class="legend">Dataflash: free space</div>
</li>
</ul>
<div id="profile_change">
<div class="dropdown dropdown-dark">
<form name="profile-change" id="profile-change">
<!--suppress HtmlFormInputWithoutLabel -->
<select class="dropdown-select" id="profilechange">
<div class="header-wrapper">
<div id="dataflash_wrapper_global">
<div class="noflash_global" align="center">No dataflash <br>chip found</div>
<ul class="dataflash-contents_global">
<li class="dataflash-free_global">
<div class="legend">Dataflash: free space</div>
</li>
</ul>
<div id="profile_change">
<div class="dropdown dropdown-dark">
<form name="profile-change" id="profile-change">
<!--suppress HtmlFormInputWithoutLabel -->
<select class="dropdown-select" id="profilechange">
<option value="0">Profile 1</option>
<option value="1">Profile 2</option>
<option value="2">Profile 3</option>
</select>
</form>
</form>
</div>
</div>
</div>
<div id="battery_profile_change">
<div class="dropdown dropdown-dark">
<form name="battery-profile-change" id="battery-profile-change">
<!--suppress HtmlFormInputWithoutLabel -->
<select class="dropdown-select" id="batteryprofilechange">
<div id="battery_profile_change">
<div class="dropdown dropdown-dark">
<form name="battery-profile-change" id="battery-profile-change">
<!--suppress HtmlFormInputWithoutLabel -->
<select class="dropdown-select" id="batteryprofilechange">
<option value="0">Battery profile 1</option>
<option value="1">Battery profile 2</option>
<option value="2">Battery profile 3</option>
</select>
</form>
</form>
</div>
</div>
</div>
<div id="sensor-status" class="sensor_state mode-connected">
<ul>
<li class="gyro" title="Gyroscope">
<div class="gyroicon">Gyro</div>
</li>
<li class="accel" title="Accelerometer">
<div class="accicon">Accel</div>
</li>
<li class="mag" title="Magnetometer">
<div class="magicon">Mag</div>
</li>
<li class="baro" title="Barometer">
<div class="baroicon">Baro</div>
</li>
<li class="gps" title="GPS">
<div class="gpsicon">GPS</div>
</li>
<li class="opflow" title="Optical flow">
<div class="opflowicon">Flow</div>
</li>
<li class="sonar" title="Sonar / Range finder">
<div class="sonaricon">Sonar</div>
</li>
<li class="airspeed" title="Airspeed">
<div class="airspeedicon">Speed</div>
</li>
</ul>
</div>
<div id="quad-status_wrapper">
<div class="battery-icon">
<div class="quad-status-contents">
<div class="battery-status"></div>
</div>
</div>
<div class="battery-legend">Battery voltage</div>
<div class="bottomStatusIcons">
<div class="armedicon cf_tip" data-i18n_title="mainHelpArmed"></div>
<div class="failsafeicon cf_tip" data-i18n_title="mainHelpFailsafe"></div>
<div class="linkicon cf_tip" data-i18n_title="mainHelpLink"></div>
</div>
</div>
</div>
<div id="sensor-status" class="sensor_state mode-connected">
<ul>
<li class="gyro" title="Gyroscope">
<div class="gyroicon">Gyro</div>
</div>
<div class="clear-both"></div>
<div id="log">
<div class="logswitch">
<a href="#" id="showlog">Show Log</a>
</div>
<div id="scrollicon"></div>
<div class="wrapper"></div>
</div>
<div class="tab_container">
<div id="tabs">
<ul class="mode-disconnected">
<li class="tab_landing">
<a href="#" data-i18n="tabLanding" class="tabicon ic_welcome" title="Welcome"></a>
</li>
<li class="tab_help">
<a href="https://github.com/iNavFlight/inav/wiki" target="_blank" data-i18n="tabHelp" class="tabicon ic_help" title="Documentation &amp; Support"></a>
</li>
<li class="tab_mission_control">
<a href="#" data-i18n="tabMissionControl" class="tabicon ic_mission" title="Mission Control"></a>
</li>
<li class="tab_firmware_flasher">
<a href="#" data-i18n="tabFirmwareFlasher" class="tabicon ic_flasher" title="Firmware Flasher"></a>
</li>
</ul>
<ul class="mode-connected">
<li class="tab_setup">
<a href="#" data-i18n="tabSetup" class="tabicon ic_setup" title="Setup"></a>
</li>
<li class="tab_calibration">
<a href="#" data-i18n="tabCalibration" class="tabicon ic_calibration" title="Calibration"></a>
</li>
<li class="tab_mixer">
<a href="#" data-i18n="tabMixer" class="tabicon ic_mixer" title="Mixer"></a>
</li>
<li class="tab_outputs">
<a href="#" data-i18n="tabOutputs" class="tabicon ic_motor" title="Outputs"></a>
</li>
<li class="tab_profiles">
<a href="#" data-i18n="tabPresets" class="tabicon ic_wizzard" title="Presets"></a>
</li>
<li class="tab_ports">
<a href="#" data-i18n="tabPorts" class="tabicon ic_ports" title="Ports"></a>
</li>
<li class="tab_configuration">
<a href="#" data-i18n="tabConfiguration" class="tabicon ic_config" title="Configuration"></a>
</li>
<li class="accel" title="Accelerometer">
<div class="accicon">Accel</div>
<li class="tab_failsafe">
<a href="#" data-i18n="tabFailsafe" class="tabicon ic_failsafe" title="Failsafe"></a>
</li>
<li class="mag" title="Magnetometer">
<div class="magicon">Mag</div>
<li class="tab_pid_tuning">
<a href="#" data-i18n="tabPidTuning" class="tabicon ic_pid" title="PID Tuning"></a>
</li>
<li class="baro" title="Barometer">
<div class="baroicon">Baro</div>
<li class="tab_advanced_tuning">
<a href="#" data-i18n="tabAdvancedTuning" class="tabicon ic_advanced" title="Advanced Tuning"></a>
</li>
<li class="gps" title="GPS">
<div class="gpsicon">GPS</div>
<li class="tab_receiver">
<a href="#" data-i18n="tabReceiver" class="tabicon ic_rx" title="Receiver"></a>
</li>
<li class="tab_auxiliary">
<a href="#" data-i18n="tabAuxiliary" class="tabicon ic_modes" title="Modes"></a>
</li>
<li class="tab_adjustments">
<a href="#" data-i18n="tabAdjustments" class="tabicon ic_adjust" title="Adjustments"></a>
</li>
<li class="tab_gps">
<a href="#" data-i18n="tabGPS" class="tabicon ic_gps" title="GPS"></a>
</li>
<li class="tab_mission_control">
<a href="#" data-i18n="tabMissionControl" class="tabicon ic_mission" title="Mission Control"></a>
</li>
<li class="tab_osd">
<a href="#" data-i18n="tabOSD" class="tabicon ic_osd" title="OSD"></a>
</li>
<li class="opflow" title="Optical flow">
<div class="opflowicon">Flow</div>
<!--<li class="tab_transponder"><a href="#" data-i18n="tabTransponder" class="tabicon ic_transponder" title="Transponder"></a></li>-->
<li class="tab_led_strip">
<a href="#" data-i18n="tabLedStrip" class="tabicon ic_led" title="LED Strip"></a>
</li>
<li class="sonar" title="Sonar / Range finder">
<div class="sonaricon">Sonar</div>
<li class="tab_sensors">
<a href="#" data-i18n="tabRawSensorData" class="tabicon ic_sensors" title="Sensors"></a>
</li>
<li class="airspeed" title="Airspeed">
<div class="airspeedicon">Speed</div>
<li class="tab_logging">
<a href="#" data-i18n="tabLogging" class="tabicon ic_log" title="Tethered Logging"></a>
</li>
<li class="tab_onboard_logging">
<a href="#" data-i18n="tabOnboardLogging" class="tabicon ic_data" title="Onboard Logging"></a>
</li>
<li class="tab_cli">
<a href="#" data-i18n="tabCLI" class="tabicon ic_cli" title="CLI"></a>
</li>
<!--<li class=""><a href="#" class="tabicon ic_advanced">Advanced (spare icon)</a></li>-->
<!--<li class=""><a href="#" class="tabicon ic_wizzard">Wizzard (spare icon)</a></li>-->
</ul>
</div>
<div id="quad-status_wrapper">
<div class="battery-icon">
<div class="quad-status-contents">
<div class="battery-status"></div>
</div>
</div>
<div class="battery-legend">Battery voltage</div>
<div class="bottomStatusIcons">
<div class="armedicon cf_tip" data-i18n_title="mainHelpArmed"></div>
<div class="failsafeicon cf_tip" data-i18n_title="mainHelpFailsafe"></div>
<div class="linkicon cf_tip" data-i18n_title="mainHelpLink"></div>
</div>
</div>
<div class="clear-both"></div>
</div>
</div>
<div class="clear-both"></div>
<div id="log">
<div class="logswitch">
<a href="#" id="showlog">Show Log</a>
<div id="content"></div>
<div id="status-bar">
<div>
<span data-i18n="statusbar_packet_error"></span> <span class="packet-error">0</span>
</div>
<div>
<span data-i18n="statusbar_i2c_error"></span> <span class="i2c-error">0</span>
</div>
<div>
<span data-i18n="statusbar_cycle_time"></span> <span class="cycle-time">0</span>
</div>
<div>
<span class="cpu-load"> </span>
</div>
<div>
<span id="msp-version"> </span>
</div>
<div>
<span id="msp-load"> </span>
</div>
<div>
<span id="msp-roundtrip"> </span>
</div>
<div>
<span id="hardware-roundtrip"> </span>
</div>
<div>
<span id="drop-rate"> </span>
</div>
<div class="version">
<!-- configuration version generated here -->
</div>
</div>
<div id="scrollicon"></div>
<div class="wrapper"></div>
</div>
<div class="tab_container">
<div id="tabs">
<ul class="mode-disconnected">
<li class="tab_landing"><a href="#" data-i18n="tabLanding" class="tabicon ic_welcome"
title="Welcome"></a></li>
<li class="tab_help"><a href="#" data-i18n="tabHelp" class="tabicon ic_help"
title="Documentation &amp; Support"></a></li>
<li class="tab_firmware_flasher"><a href="#" data-i18n="tabFirmwareFlasher" class="tabicon ic_flasher"
title="Firmware Flasher"></a></li>
</ul>
<ul class="mode-connected">
<li class="tab_setup"><a href="#" data-i18n="tabSetup" class="tabicon ic_setup" title="Setup"></a></li>
<li class="tab_calibration"><a href="#" data-i18n="tabCalibration" class="tabicon ic_calibration" title="Calibration"></a></li>
<li class="tab_mixer"><a href="#" data-i18n="tabMixer" class="tabicon ic_mixer" title="Mixer"></a></li>
<li class="tab_profiles"><a href="#" data-i18n="tabPresets" class="tabicon ic_wizzard"
title="Presets"></a></li>
<li class="tab_ports"><a href="#" data-i18n="tabPorts" class="tabicon ic_ports" title="Ports"></a></li>
<li class="tab_configuration"><a href="#" data-i18n="tabConfiguration" class="tabicon ic_config"
title="Configuration"></a></li>
<li class="tab_failsafe"><a href="#" data-i18n="tabFailsafe" class="tabicon ic_failsafe"
title="Failsafe"></a></li>
<li class="tab_pid_tuning"><a href="#" data-i18n="tabPidTuning" class="tabicon ic_pid"
title="PID Tuning"></a></li>
<li class="tab_advanced_tuning"><a href="#" data-i18n="tabAdvancedTuning" class="tabicon ic_advanced" title="Advanced Tuning"></a></li>
<li class="tab_receiver"><a href="#" data-i18n="tabReceiver" class="tabicon ic_rx" title="Receiver"></a>
</li>
<li class="tab_auxiliary"><a href="#" data-i18n="tabAuxiliary" class="tabicon ic_modes"
title="Modes"></a></li>
<li class="tab_adjustments"><a href="#" data-i18n="tabAdjustments" class="tabicon ic_adjust"
title="Adjustments"></a></li>
<li class="tab_servos"><a href="#" data-i18n="tabServos" class="tabicon ic_servo" title="Servos"></a>
</li>
<li class="tab_gps"><a href="#" data-i18n="tabGPS" class="tabicon ic_gps" title="GPS"></a></li>
<li class="tab_mission_control"><a href="#" data-i18n="tabMissionControl" class="tabicon ic_mission" title="Mission Control"></a></li>
<li class="tab_motors"><a href="#" data-i18n="tabMotorTesting" class="tabicon ic_motor"
title="Motors"></a></li>
<li class="tab_osd"><a href="#" data-i18n="tabOSD" class="tabicon ic_osd" title="OSD"></a></li>
<!--<li class="tab_transponder"><a href="#" data-i18n="tabTransponder" class="tabicon ic_transponder" title="Transponder"></a></li>-->
<li class="tab_led_strip"><a href="#" data-i18n="tabLedStrip" class="tabicon ic_led"
title="LED Strip"></a></li>
<li class="tab_sensors"><a href="#" data-i18n="tabRawSensorData" class="tabicon ic_sensors"
title="Sensors"></a></li>
<li class="tab_logging"><a href="#" data-i18n="tabLogging" class="tabicon ic_log"
title="Tethered Logging"></a></li>
<li class="tab_onboard_logging"><a href="#" data-i18n="tabOnboardLogging" class="tabicon ic_data"
title="Onboard Logging"></a></li>
<li class="tab_cli"><a href="#" data-i18n="tabCLI" class="tabicon ic_cli" title="CLI"></a></li>
<!--<li class=""><a href="#" class="tabicon ic_advanced">Advanced (spare icon)</a></li>-->
<!--<li class=""><a href="#" class="tabicon ic_wizzard">Wizzard (spare icon)</a></li>-->
</ul>
<div id="cache">
<div class="data-loading">
<p>Waiting for data ...</p>
</div>
</div>
<div class="clear-both"></div>
</div>
<div id="content"></div>
<div id="status-bar">
<div>
<span data-i18n="statusbar_packet_error"></span> <span class="packet-error">0</span>
</div>
<div>
<span data-i18n="statusbar_i2c_error"></span> <span class="i2c-error">0</span>
</div>
<div>
<span data-i18n="statusbar_cycle_time"></span> <span class="cycle-time">0</span>
</div>
<div>
<span class="cpu-load"> </span>
</div>
<div>
<span id="msp-version"> </span>
</div>
<div>
<span id="msp-load"> </span>
</div>
<div>
<span id="msp-roundtrip"> </span>
</div>
<div>
<span id="hardware-roundtrip"> </span>
</div>
<div>
<span id="drop-rate"> </span>
</div>
<div class="version">
<!-- configuration version generated here -->
</div>
<div id="modal-reconnect" class="is-hidden">
<div data-i18n="deviceRebooting"></div>
</div>
<div id="cache">
<div class="data-loading">
<p>Waiting for data ...</p>
<div id="defaults-wrapper" style="display: none">
<div class="defaults-dialog__background"></div>
<div class="defaults-dialog__content">
<div class="tab_title" data-i18n="defaultsDialogTitle"></div>
<div class="defaults-dialog__content--wrapper">
<p class="defaults-dialog__info" data-i18n="defaultsDialogInfo"></p>
<div class="defaults-dialog__options"></div>
</div>
</div>
</div>
</div>
</body>
</html>

@ -91,20 +91,10 @@ $(document).ready(function () {
}
});
win.setMinimumSize(1024, 800);
win.setMinimumSize(800, 600);
win.on('close', function () {
//Save window size and position
// var height = win.height;
// var width = win.width;
//
// if (height < 400) {
// height = 400
// }
// if (width < 512) {
// width = 512
// }
chrome.storage.local.set({'windowSize': {height: win.height, width: win.width, x: win.x, y: win.y}}, function () {
// Notify that we saved.
console.log('Settings saved');
@ -123,7 +113,6 @@ $(document).ready(function () {
}
});
//set '1.8.0' for test
appUpdater.checkRelease(chrome.runtime.getManifest().version);
// log library versions in console to make version tracking easier
@ -132,6 +121,11 @@ $(document).ready(function () {
// Tabs
var ui_tabs = $('#tabs > ul');
$('a', ui_tabs).click(function () {
if ($(this).parent().hasClass("tab_help")) {
return;
}
if ($(this).parent().hasClass('active') == false && !GUI.tab_switch_in_progress) { // only initialize when the tab isn't already active
var self = this,
tabClass = $(self).parent().prop('class');
@ -141,12 +135,6 @@ $(document).ready(function () {
var tab = tabClass.substring(4);
var tabName = $(self).text();
if (CONFIGURATOR.connectionValid && semver.lt(CONFIG.flightControllerVersion, "2.0.0")) {
$('#battery_profile_change').hide();
$('#profile_change').css('width', '125px');
$('#dataflash_wrapper_global').css('width', '125px');
}
if (tabRequiresConnection && !CONFIGURATOR.connectionValid) {
GUI.log(chrome.i18n.getMessage('tabSwitchConnectionRequired'));
return;
@ -173,6 +161,7 @@ $(document).ready(function () {
// detach listeners and remove element data
var content = $('#content');
content.data('empty', !!content.is(':empty'));
content.empty();
// display loading screen
@ -189,10 +178,6 @@ $(document).ready(function () {
case 'firmware_flasher':
TABS.firmware_flasher.initialize(content_ready);
break;
case 'help':
TABS.help.initialize(content_ready);
break;
case 'auxiliary':
TABS.auxiliary.initialize(content_ready);
break;
@ -244,8 +229,8 @@ $(document).ready(function () {
case 'mixer':
TABS.mixer.initialize(content_ready);
break;
case 'motors':
TABS.motors.initialize(content_ready);
case 'outputs':
TABS.outputs.initialize(content_ready);
break;
case 'osd':
TABS.osd.initialize(content_ready);

@ -1,7 +1,7 @@
{
"manifest_version": 2,
"minimum_chrome_version": "38",
"version": "2.1.0",
"version": "2.5.0",
"author": "Several",
"name": "INAV - Configurator",
"short_name": "INAV",

2418
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -1,11 +1,13 @@
{
"name": "inav-configurator",
"description": "INAV Configurator",
"version": "2.1.0",
"version": "2.5.0",
"main": "main.html",
"default_locale": "en",
"scripts": {
"start": "node_modules/gulp/bin/gulp.js build && node_modules/nw/bin/nw ."
"start": "node node_modules/gulp/bin/gulp.js build && node node_modules/nw/bin/nw .",
"gulp": "gulp",
"nw": "nw"
},
"window": {
"title": "INAV Configurator",
@ -24,18 +26,24 @@
"archiver": "^2.0.3",
"bluebird": "3.4.1",
"del": "^3.0.0",
"graceful-fs": "^4.1.11",
"gulp": "^4.0.0",
"fs": "0.0.1-security",
"graceful-fs": "^4.2.0",
"gulp": "^4.0.2",
"gulp-concat": "^2.6.1",
"inflection": "1.12.0",
"jquery": "2.1.4",
"jquery-ui-npm": "1.12.0",
"marked": "^0.3.17",
"minimist": "^1.2.0",
"nw": "^0.31.4-sdk",
"nw-builder": "^3.5.4",
"nw": "^0.42.2-sdk",
"nw-dialog": "^1.0.7",
"openlayers": "^4.6.5",
"temp": "^0.8.3",
"three": "0.72.0"
"three": "0.72.0",
"xml2js": "^0.4.19"
},
"devDependencies": {
"nw-builder": "^3.5.7",
"semver": "6.3.0"
}
}

@ -4,7 +4,7 @@
FONT_VERSION = 1
FONTS = default vision vision-alt clarity clarity_medium bold large
FONTS = default vision impact impact_mini clarity clarity_medium bold large
CHARMAPS = $(addsuffix .mcm, $(FONTS))
PREVIEWS = $(addsuffix .png, $(FONTS))

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 248 B

After

Width:  |  Height:  |  Size: 229 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 123 B

After

Width:  |  Height:  |  Size: 198 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 136 B

After

Width:  |  Height:  |  Size: 205 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 127 B

After

Width:  |  Height:  |  Size: 200 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 121 B

After

Width:  |  Height:  |  Size: 195 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 133 B

After

Width:  |  Height:  |  Size: 205 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 131 B

After

Width:  |  Height:  |  Size: 201 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 126 B

After

Width:  |  Height:  |  Size: 198 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 132 B

After

Width:  |  Height:  |  Size: 204 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 201 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 102 B

After

Width:  |  Height:  |  Size: 240 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 204 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 219 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 208 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 237 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 236 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 236 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 253 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 247 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 214 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 259 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 253 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 253 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 261 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 258 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 225 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 184 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 201 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 208 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 215 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 248 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 260 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 277 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 272 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 271 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 248 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 194 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 209 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 213 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 210 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 215 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 216 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 202 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 221 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 B

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 177 B

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 123 B

After

Width:  |  Height:  |  Size: 198 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 136 B

After

Width:  |  Height:  |  Size: 205 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 127 B

After

Width:  |  Height:  |  Size: 200 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 121 B

After

Width:  |  Height:  |  Size: 195 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 133 B

After

Width:  |  Height:  |  Size: 205 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 131 B

After

Width:  |  Height:  |  Size: 201 B

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save