mirror of
https://github.com/betaflight/betaflight-configurator.git
synced 2025-07-20 06:45:12 +03:00
...restoring some files
This commit is contained in:
parent
6c9c64de31
commit
87e9bfd3d9
31 changed files with 1043 additions and 471 deletions
81
README.md
Normal file
81
README.md
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
# Cleanflight Configurator
|
||||||
|
|
||||||
|
Cleanflight Configurator is a crossplatform configuration tool for the [Cleanflight](http://cleanflight.com/) flight control system.
|
||||||
|
|
||||||
|
It runs as an app within Google Chrome and allows you to configure the Cleanflight software running on any [supported Cleanflight target](https://github.com/cleanflight/cleanflight/blob/master/docs/Boards.md).
|
||||||
|
|
||||||
|
Various types of aircraft are supported by the tool and by cleanflight, e.g. quadcopters, hexacopters, octocopters and fixed-wing aircraft.
|
||||||
|
|
||||||
|
[](https://chrome.google.com/webstore/detail/cleanflight-configurator/enacoimjcgeinfnnnpajinjgmkahmfgb)
|
||||||
|
|
||||||
|
## Authors
|
||||||
|
|
||||||
|
Dominic Clifton/hydra - maintainer of the Cleanflight firmware and configurator.
|
||||||
|
|
||||||
|
Cleanflight Configurator was originally a [fork](#credits) of Baseflight Configurator with support for Cleanflight instead of Baseflight.
|
||||||
|
|
||||||
|
This configurator is the only configurator with support for Cleanflight specific features. It will likely require that you run the latest firmware on the flight controller.
|
||||||
|
If you are experiencing any problems please make sure you are running the [latest firmware version](https://github.com/cleanflight/cleanflight/releases/latest).
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
### Via chrome webstore
|
||||||
|
|
||||||
|
1. Visit [Chrome web store](https://chrome.google.com/webstore/detail/cleanflight-configurator/enacoimjcgeinfnnnpajinjgmkahmfgb)
|
||||||
|
2. Click **+ Free**
|
||||||
|
|
||||||
|
Please note - the application will automatically update itself when new versions are released. Please ensure you maintain configuration backups as described in the Cleanflight documentation.
|
||||||
|
|
||||||
|
### Alternative way
|
||||||
|
|
||||||
|
1. Clone the repo to any local directory or download it as zip
|
||||||
|
2. Start Chromium or Google Chrome and go to tools -> extension
|
||||||
|
3. Check the "Developer mode" checkbox
|
||||||
|
4. Click on load unpacked extension and point it to the Cleanflight Configurator directory (for example D:/cleanflight-configurator)
|
||||||
|
|
||||||
|
## How to use
|
||||||
|
|
||||||
|
You can find the Cleanflight Configurator icon in your application tab "Apps"
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
### WebGL
|
||||||
|
|
||||||
|
Make sure Settings -> System -> "User hardware acceleration when available" is checked to achieve the best performance
|
||||||
|
|
||||||
|
### Linux users
|
||||||
|
|
||||||
|
1. Dont forget to add your user into dialout group "sudo usermod -aG dialout YOUR_USERNAME" for serial access
|
||||||
|
2. If you have 3D model animation problems, enable "Override software rendering list" in Chrome flags chrome://flags/#ignore-gpu-blacklist
|
||||||
|
|
||||||
|
## Support
|
||||||
|
|
||||||
|
If you need help your please use the multiwii or rcgroups forums or visit the IRC channel before raising issues in the issue trackers.
|
||||||
|
|
||||||
|
### Issue trackers
|
||||||
|
|
||||||
|
For Cleanflight configurator issues raise them here
|
||||||
|
|
||||||
|
https://github.com/cleanflight/cleanflight-configurator/issues
|
||||||
|
|
||||||
|
For Cleanflight firmware issues raise them here
|
||||||
|
|
||||||
|
https://github.com/cleanflight/cleanflight/issues
|
||||||
|
|
||||||
|
### IRC Channel
|
||||||
|
|
||||||
|
There is an IRC channel for Cleanflight, here: irc://irc.freenode.net/#cleanflight
|
||||||
|
|
||||||
|
Support for Baseflight Configurator can also be found on IRC, here: irc://irc.freenode.net/#multiwii
|
||||||
|
|
||||||
|
## Technical details
|
||||||
|
|
||||||
|
The configurator is based on chrome.serial API running on Google Chrome/Chromium core.
|
||||||
|
|
||||||
|
## Developers
|
||||||
|
|
||||||
|
We accept clean and reasonable patches, submit them!
|
||||||
|
|
||||||
|
## Credits
|
||||||
|
|
||||||
|
ctn - primary author and maintainer of Baseflight Configurator from which this project was forked.
|
|
@ -211,7 +211,7 @@
|
||||||
"message": "Request Optional Permissions"
|
"message": "Request Optional Permissions"
|
||||||
},
|
},
|
||||||
"defaultWelcomeText": {
|
"defaultWelcomeText": {
|
||||||
"message": "Welcome to <strong>Cleanflight - Configurator</strong>, a utility designed to simplify updating, configuring and tuning of your flight controller.<br /><br />The application supports all hardware that can run cleanflight (<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=\"https://www.openpilot.org/product/coptercontrol/\" target=\"_blank\">CC3D/EVO</a>, <a href=\"http://www.multiwiicopter.com/products/paris-air-hero-32-naze\" target=\"_blank\">Air Hero 32</a>, <a href=\"http://www.readytoflyquads.com/flight-controllers/flip-series\" target=\"_blank\">Flip32/+/Deluxe</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/PrestaShop/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/cleanflight/cleanflight\" title=\"www.github.com\" target=\"_blank\">here</a><br />The newest binary firmware image is available <a href=\"https://github.com/cleanflight/cleanflight/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 />"
|
"message": "Welcome to <strong>Cleanflight - Configurator</strong>, a utility designed to simplify updating, configuring and tuning of your flight controller.<br /><br />The application supports all hardware that can run cleanflight (<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.multiwiicopter.com/products/paris-air-hero-32-naze\" target=\"_blank\">Air Hero 32</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/PrestaShop/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/cleanflight/cleanflight\" title=\"www.github.com\" target=\"_blank\">here</a><br />The newest binary firmware image is available <a href=\"https://github.com/cleanflight/cleanflight/releases\" title=\"www.github.com\" target=\"_blank\">here</a>, development builds available <a href=\"http://cleanflight.memoryleaks.org/builds/\" 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 />"
|
||||||
},
|
},
|
||||||
"defaultContributingHead": {
|
"defaultContributingHead": {
|
||||||
"message": "Contributing"
|
"message": "Contributing"
|
||||||
|
@ -253,7 +253,7 @@
|
||||||
"message": "Calibrate Accelerometer"
|
"message": "Calibrate Accelerometer"
|
||||||
},
|
},
|
||||||
"initialSetupCalibrateAccelText": {
|
"initialSetupCalibrateAccelText": {
|
||||||
"message": "Place board or frame on <strong>leveled</strong> surface, proceed with calibration, ensure platform is not moving during calibration"
|
"message": "Place board or frame on <strong>leveled</strong> surface, proceed with calibration, ensure platform is not moving during calibration period"
|
||||||
},
|
},
|
||||||
"initialSetupButtonCalibrateMag": {
|
"initialSetupButtonCalibrateMag": {
|
||||||
"message": "Calibrate Magnetometer"
|
"message": "Calibrate Magnetometer"
|
||||||
|
@ -372,8 +372,8 @@
|
||||||
"initialSetupModel": {
|
"initialSetupModel": {
|
||||||
"message": "Model: $1"
|
"message": "Model: $1"
|
||||||
},
|
},
|
||||||
"initialSetupHeading": {
|
"initialSetupAttitude": {
|
||||||
"message": "Heading: $1 deg"
|
"message": "$1 deg"
|
||||||
},
|
},
|
||||||
"initialSetupAccelCalibStarted": {
|
"initialSetupAccelCalibStarted": {
|
||||||
"message": "Accelerometer calibration started"
|
"message": "Accelerometer calibration started"
|
||||||
|
@ -427,6 +427,10 @@
|
||||||
"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."
|
"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> Rememer to configure a Serial Port (via Ports tab) and choose a Serial Receiver Provider when using RX_SERIAL feature."
|
||||||
|
},
|
||||||
|
|
||||||
"configurationBoardAlignment": {
|
"configurationBoardAlignment": {
|
||||||
"message": "Board Alignment"
|
"message": "Board Alignment"
|
||||||
},
|
},
|
||||||
|
@ -478,9 +482,6 @@
|
||||||
"configurationBatteryMinimum": {
|
"configurationBatteryMinimum": {
|
||||||
"message": "Minimum Cell Voltage"
|
"message": "Minimum Cell Voltage"
|
||||||
},
|
},
|
||||||
"configurationBatteryWarning": {
|
|
||||||
"message": "Warning Cell Voltage"
|
|
||||||
},
|
|
||||||
"configurationBatteryMaximum": {
|
"configurationBatteryMaximum": {
|
||||||
"message": "Maximum Cell Voltage"
|
"message": "Maximum Cell Voltage"
|
||||||
},
|
},
|
||||||
|
@ -502,6 +503,18 @@
|
||||||
"configurationBatteryMultiwiiCurrent": {
|
"configurationBatteryMultiwiiCurrent": {
|
||||||
"message": "Enable support for legacy Multiwii MSP current output"
|
"message": "Enable support for legacy Multiwii MSP current output"
|
||||||
},
|
},
|
||||||
|
"configurationSystem": {
|
||||||
|
"message": "System configuration"
|
||||||
|
},
|
||||||
|
"configurationLoopTime": {
|
||||||
|
"message": "Flight Controller Loop Time"
|
||||||
|
},
|
||||||
|
"configurationCalculatedCyclesSec": {
|
||||||
|
"message": "Cycles/Sec (Hz)"
|
||||||
|
},
|
||||||
|
"configurationLoopTimeHelp": {
|
||||||
|
"message": "<strong>Note:</strong> Changing this may require PID re-tuning."
|
||||||
|
},
|
||||||
"configurationGPS": {
|
"configurationGPS": {
|
||||||
"message": "GPS"
|
"message": "GPS"
|
||||||
},
|
},
|
||||||
|
@ -514,6 +527,10 @@
|
||||||
"configurationGPSubxSbas": {
|
"configurationGPSubxSbas": {
|
||||||
"message": "Ground Assistance Type"
|
"message": "Ground Assistance Type"
|
||||||
},
|
},
|
||||||
|
"configurationGPSHelp": {
|
||||||
|
"message": "<strong>Note:</strong> Remember to configure a Serial Port (via Ports tab) when using GPS feature."
|
||||||
|
},
|
||||||
|
|
||||||
"configurationSerialRX": {
|
"configurationSerialRX": {
|
||||||
"message": "Serial Receiver Provider"
|
"message": "Serial Receiver Provider"
|
||||||
},
|
},
|
||||||
|
@ -525,7 +542,10 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
"portsHelp": {
|
"portsHelp": {
|
||||||
"message": "Configure serial ports. <strong>Note:</strong> not all combinations are valid. When the flight controller firmware detects this the serial port configuration will be reset."
|
"message": "<strong>Note:</strong> not all combinations are valid. When the flight controller firmware detects this the serial port configuration will be reset."
|
||||||
|
},
|
||||||
|
"portsMSPHelp": {
|
||||||
|
"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": {
|
"portsFirmwareUpgradeRequired": {
|
||||||
"message": "Firmware upgrade <span style=\"color: red\">required</span>. Serial port configurations of firmware < 1.8.0 is not supported."
|
"message": "Firmware upgrade <span style=\"color: red\">required</span>. Serial port configurations of firmware < 1.8.0 is not supported."
|
||||||
|
@ -616,6 +636,9 @@
|
||||||
"message": "EEPROM <span style=\"color: green\">saved</span>"
|
"message": "EEPROM <span style=\"color: green\">saved</span>"
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"receiverHelp": {
|
||||||
|
"message": "Please read receiver chapter of the documentation. Configure serial port (if required), receiver mode (serial/ppm/pwm), provider (for serial receivers), bind receiver, set channel map, configure channel endpoints/range on TX so that all channels go from ~1000 to ~2000. Set midpoint (default 1500), trim channels to 1500, configure stick deadband, verify behaviour when TX is off or out of range.<br /><span style=\"color: red\">IMPORTANT:</span> Before flying read failsafe chapter of documentation and configure failsafe."
|
||||||
|
},
|
||||||
"receiverThrottleMid": {
|
"receiverThrottleMid": {
|
||||||
"message": "Throttle MID"
|
"message": "Throttle MID"
|
||||||
},
|
},
|
||||||
|
@ -649,6 +672,9 @@
|
||||||
"receiverButtonRefresh": {
|
"receiverButtonRefresh": {
|
||||||
"message": "Refresh"
|
"message": "Refresh"
|
||||||
},
|
},
|
||||||
|
"receiverButtonSticks": {
|
||||||
|
"message": "Control sticks"
|
||||||
|
},
|
||||||
"receiverDataRefreshed": {
|
"receiverDataRefreshed": {
|
||||||
"message": "RC Tuning data <strong>refreshed</strong>"
|
"message": "RC Tuning data <strong>refreshed</strong>"
|
||||||
},
|
},
|
||||||
|
@ -794,15 +820,13 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
"servosModel": {
|
"servosFirmwareUpgradeRequired": {
|
||||||
"message": "Model:"
|
"message": "Servos requires firmware >= 1.10.0."
|
||||||
},
|
},
|
||||||
|
|
||||||
"servosChangeDirection": {
|
"servosChangeDirection": {
|
||||||
"message": "Change Direction in TX To Match"
|
"message": "Change Direction in TX To Match"
|
||||||
},
|
},
|
||||||
"servosGyroAccelDirection": {
|
|
||||||
"message": "Gyroscope / Accelerometer Direction"
|
|
||||||
},
|
|
||||||
"servosName": {
|
"servosName": {
|
||||||
"message": "Name"
|
"message": "Name"
|
||||||
},
|
},
|
||||||
|
@ -815,8 +839,14 @@
|
||||||
"servosMax": {
|
"servosMax": {
|
||||||
"message": "MAX"
|
"message": "MAX"
|
||||||
},
|
},
|
||||||
"servosDirection": {
|
"servosAngleAtMin": {
|
||||||
"message": "Direction"
|
"message": "Angle at min"
|
||||||
|
},
|
||||||
|
"servosAngleAtMax": {
|
||||||
|
"message": "Angle at max"
|
||||||
|
},
|
||||||
|
"servosDirectionAndRate": {
|
||||||
|
"message": "Direction and rate"
|
||||||
},
|
},
|
||||||
"servosLiveMode": {
|
"servosLiveMode": {
|
||||||
"message": "Enable Live mode:"
|
"message": "Enable Live mode:"
|
||||||
|
@ -824,9 +854,6 @@
|
||||||
"servosButtonSave": {
|
"servosButtonSave": {
|
||||||
"message": "Save"
|
"message": "Save"
|
||||||
},
|
},
|
||||||
"servosModelNoSupport": {
|
|
||||||
"message": "This model doesn't support servos"
|
|
||||||
},
|
|
||||||
"servosNormal": {
|
"servosNormal": {
|
||||||
"message": "Normal"
|
"message": "Normal"
|
||||||
},
|
},
|
||||||
|
@ -1045,7 +1072,7 @@
|
||||||
"message": "Attempt to flash the board automatically (triggered by newly detected serial port)"
|
"message": "Attempt to flash the board automatically (triggered by newly detected serial port)"
|
||||||
},
|
},
|
||||||
"firmwareFlasherFullChipErase": {
|
"firmwareFlasherFullChipErase": {
|
||||||
"message": "Full Chip Erase"
|
"message": "Full chip erase"
|
||||||
},
|
},
|
||||||
"firmwareFlasherFullChipEraseDescription": {
|
"firmwareFlasherFullChipEraseDescription": {
|
||||||
"message": "Wipes all configuration data currently stored on the board"
|
"message": "Wipes all configuration data currently stored on the board"
|
||||||
|
@ -1057,7 +1084,7 @@
|
||||||
"message": "Flash most recent (untested) development firmware"
|
"message": "Flash most recent (untested) development firmware"
|
||||||
},
|
},
|
||||||
"firmwareFlasherManualBaud": {
|
"firmwareFlasherManualBaud": {
|
||||||
"message": "Manual Baud Rate"
|
"message": "Manual baud rate"
|
||||||
},
|
},
|
||||||
"firmwareFlasherManualBaudDescription": {
|
"firmwareFlasherManualBaudDescription": {
|
||||||
"message": "Manual selection of baud rate for boards that don't support the default speed or for flashing via bluetooth."
|
"message": "Manual selection of baud rate for boards that don't support the default speed or for flashing via bluetooth."
|
||||||
|
@ -1102,7 +1129,7 @@
|
||||||
"message": "Warning"
|
"message": "Warning"
|
||||||
},
|
},
|
||||||
"firmwareFlasherWarningText": {
|
"firmwareFlasherWarningText": {
|
||||||
"message": "Please do not try to flash <strong>non-cleanflight</strong> hardware with this firmware flasher (it wont work).<br />Do not <strong>disconnect</strong> the board or <strong>turn off</strong> your computer while flashing.<br /><br />Note: <strong>STM32</strong> bootloader is stored in <strong>ROM</strong>, it cannot be bricked.<br />Note: <strong>Auto-Connect</strong> is always disabled while you are inside firmware flasher.<br />Note: This can wipe your configuration including but not limited to PIDs, Auxiliary, and FEATURES. Make sure you have a backup.<br />"
|
"message": "Please do <span style=\"color: red\">not</span> try to flash <strong>non-cleanflight</strong> hardware with this firmware flasher.<br />Do <span style=\"color: red\">not</span> <strong>disconnect</strong> the board or <strong>turn off</strong> your computer while flashing.<br /><br /><span style=\"color: green\">Note: </span>STM32 bootloader is stored in ROM, it cannot be bricked.<br />Note: <strong>Auto-Connect</strong> is always disabled while you are inside firmware flasher.<br /><span style=\"color: red\">Note: </span>Make sure you have a backup; some upgrades/downgrades will wipe your configuration.<br /><span style=\"color: green\">Note:</span> If you have problems flashing try disconnecting all cables from your FC.<br /><br /><span style=\"color: green\">Note: </span>If you have lost comminication with your board then power off the board, jumper the bootloader pins, power on, enable 'No reboot sequence', enable 'Full chip erase', re-flash, then power off, remove bootloader jumper, power on and connect (For all firmware except OPBL firmware)."
|
||||||
},
|
},
|
||||||
"firmwareFlasherButtonLeave": {
|
"firmwareFlasherButtonLeave": {
|
||||||
"message": "Leave Firmware Flasher"
|
"message": "Leave Firmware Flasher"
|
||||||
|
@ -1128,5 +1155,41 @@
|
||||||
},
|
},
|
||||||
"ledStripEepromSaved": {
|
"ledStripEepromSaved": {
|
||||||
"message": "EEPROM <span style=\"color: green\">saved</span>"
|
"message": "EEPROM <span style=\"color: green\">saved</span>"
|
||||||
|
},
|
||||||
|
"controlAxisRoll": {
|
||||||
|
"message": "Roll"
|
||||||
|
},
|
||||||
|
"controlAxisPitch": {
|
||||||
|
"message": "Pitch"
|
||||||
|
},
|
||||||
|
"controlAxisYaw": {
|
||||||
|
"message": "Yaw"
|
||||||
|
},
|
||||||
|
"controlAxisThrottle": {
|
||||||
|
"message": "Throttle"
|
||||||
|
},
|
||||||
|
"controlAxisAux1": {
|
||||||
|
"message": "AUX 1"
|
||||||
|
},
|
||||||
|
"controlAxisAux2": {
|
||||||
|
"message": "AUX 2"
|
||||||
|
},
|
||||||
|
"controlAxisAux3": {
|
||||||
|
"message": "AUX 3"
|
||||||
|
},
|
||||||
|
"controlAxisAux4": {
|
||||||
|
"message": "AUX 4"
|
||||||
|
},
|
||||||
|
"controlAxisAux5": {
|
||||||
|
"message": "AUX 5"
|
||||||
|
},
|
||||||
|
"controlAxisAux6": {
|
||||||
|
"message": "AUX 6"
|
||||||
|
},
|
||||||
|
"controlAxisAux7": {
|
||||||
|
"message": "AUX 7"
|
||||||
|
},
|
||||||
|
"controlAxisAux8": {
|
||||||
|
"message": "AUX 8"
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,3 +1,10 @@
|
||||||
|
<span>2015.10.02 - 0.66.0 - cleanflight</span>
|
||||||
|
<p>
|
||||||
|
- Update servo configuration (requires firmware >= 1.10.0).<br />
|
||||||
|
- Add some notes and help messages for common issues.<br />
|
||||||
|
- Update sponsors panel and add links to new boards.<br />
|
||||||
|
- Upgrade some JS libraries to latest versions (Three, JQuery/UI, D3)<br />
|
||||||
|
</p>
|
||||||
<span>2015.05.23 - 0.65.0 - cleanflight</span>
|
<span>2015.05.23 - 0.65.0 - cleanflight</span>
|
||||||
<p>
|
<p>
|
||||||
- Support flashing of the SPRacingF3.<br />
|
- Support flashing of the SPRacingF3.<br />
|
||||||
|
@ -23,10 +30,10 @@
|
||||||
</p>
|
</p>
|
||||||
<span>2015.03.29 - 0.63.0 - cleanflight</span>
|
<span>2015.03.29 - 0.63.0 - cleanflight</span>
|
||||||
<p>
|
<p>
|
||||||
- Configuration tab supports auto_disarm_delay and disarm_kill_switch - Requires 1.8.0 firmware.<br />
|
- Configuration tab supports auto_disarm_delay and disarm_kill_switch (requires firmware >= 1.8.0).<br />
|
||||||
- PID Tuning tab allows TPA Breakpoint changes - Requires 1.8.0 firmware.<br />
|
- PID Tuning tab allows TPA Breakpoint changes (requires firmware >= 1.8.0).<br />
|
||||||
- Corrected Artificial Horizon Pitch/Roll views.<br />
|
- Correct Artificial Horizon Pitch/Roll views.<br />
|
||||||
- Changed logging time stamp to include date stamp.<br />
|
- Change logging time stamp to include date stamp.<br />
|
||||||
- Support new firmware 1.8 serial port configuration.<br />
|
- Support new firmware 1.8 serial port configuration.<br />
|
||||||
- Move documentation and help to new tab.<br />
|
- Move documentation and help to new tab.<br />
|
||||||
- Add contributing section to welcome tab.<br />
|
- Add contributing section to welcome tab.<br />
|
||||||
|
@ -38,7 +45,7 @@
|
||||||
<span>2015.02.26 - 0.62.0 - cleanflight</span>
|
<span>2015.02.26 - 0.62.0 - cleanflight</span>
|
||||||
<p>
|
<p>
|
||||||
- Add flight indicators to setup screen tab.<br />
|
- Add flight indicators to setup screen tab.<br />
|
||||||
- Add dataflash tab. Requires 1.8.0 firmware.<br />
|
- Add dataflash tab (requires firmware >= 1.8.0)..<br />
|
||||||
- Add Cleanflight logos.<br />
|
- Add Cleanflight logos.<br />
|
||||||
- Fix loading online flash files - github moved them to amazon aws.<br />
|
- Fix loading online flash files - github moved them to amazon aws.<br />
|
||||||
- Fix to fallback 3D model.<br />
|
- Fix to fallback 3D model.<br />
|
||||||
|
@ -46,7 +53,7 @@
|
||||||
</p>
|
</p>
|
||||||
<span>2015.02.03 - 0.61.0 - cleanflight</span>
|
<span>2015.02.03 - 0.61.0 - cleanflight</span>
|
||||||
<p>
|
<p>
|
||||||
- Support changing PID controller - there new PID controllers in 1.7.0 firmware.<br />
|
- Support changing PID controller - three new PID controllers in 1.7.0 firmware.<br />
|
||||||
- Support for LED thrust ring.<br />
|
- Support for LED thrust ring.<br />
|
||||||
- Support for LED colors.<br />
|
- Support for LED colors.<br />
|
||||||
- Support for displaying sonar sensor reading on the sensors tab.<br />
|
- Support for displaying sonar sensor reading on the sensors tab.<br />
|
||||||
|
@ -54,21 +61,21 @@
|
||||||
- New Logo. (Tom McCullough)<br />
|
- New Logo. (Tom McCullough)<br />
|
||||||
- New 3D models (AkFreak).<br />
|
- New 3D models (AkFreak).<br />
|
||||||
- Update presentation of LEDs that have multiple functions.<br />
|
- Update presentation of LEDs that have multiple functions.<br />
|
||||||
- Added Documentation and Support panels to welcome tab.<br />
|
- Add Documentation and Support panels to welcome tab.<br />
|
||||||
- Add support for backup and restore of LED strip configuration.<br />
|
- Add support for backup and restore of LED strip configuration.<br />
|
||||||
- Fix for disappearing tabs in chrome 41 beta.<br />
|
- Fix for disappearing tabs in chrome 41 beta.<br />
|
||||||
- Various other minor improvements.<br />
|
- Various other minor improvements.<br />
|
||||||
</p>
|
</p>
|
||||||
<span>2015.01.08 - 0.60.0 - cleanflight</span>
|
<span>2015.01.08 - 0.60.0 - cleanflight</span>
|
||||||
<p>
|
<p>
|
||||||
- Add LED strip tab for LED configuration - requires v1.6.0 firmware to save.<br />
|
- Add LED strip tab for LED configuration (requires firmware >= 1.6.0)..<br />
|
||||||
- Replace motor order images (stronnag)<br />
|
- Replace motor order images (stronnag)<br />
|
||||||
</p>
|
</p>
|
||||||
<span>2015.01.08 - 0.59.1 - cleanflight</span>
|
<span>2015.01.08 - 0.59.1 - cleanflight</span>
|
||||||
<p>
|
<p>
|
||||||
- Add support for Blackbox flight recorder feature (requires v1.5.0 firmware).<br />
|
- Add support for Blackbox flight recorder feature (requires firmware >= 1.5.0).<br />
|
||||||
- Update RSSI channel section to allow any channel.<br />
|
- Update RSSI channel section to allow any channel.<br />
|
||||||
- Implemented configuration migration to aid with backwards compatibility.<br />
|
- Implement configuration migration to aid with backwards compatibility.<br />
|
||||||
- Allow CLI access when connecting firmware with an out-of-date API.<br />
|
- Allow CLI access when connecting firmware with an out-of-date API.<br />
|
||||||
- Support 'release candidate' and 'stable' releases.
|
- Support 'release candidate' and 'stable' releases.
|
||||||
</p>
|
</p>
|
||||||
|
@ -88,7 +95,7 @@
|
||||||
<span>2014.12.06 - 0.57.1 - cleanflight</span>
|
<span>2014.12.06 - 0.57.1 - cleanflight</span>
|
||||||
<p>
|
<p>
|
||||||
- Latest firmware <strong>required</strong>.<br />
|
- Latest firmware <strong>required</strong>.<br />
|
||||||
- Merged latest baseflight configurator changes.<br />
|
- Merge latest baseflight configurator changes.<br />
|
||||||
- Added support for choosing and downloading firmware via the github relases API.<br />
|
- Added support for choosing and downloading firmware via the github relases API.<br />
|
||||||
- Added Armattan Quads as a sponsor.<br />
|
- Added Armattan Quads as a sponsor.<br />
|
||||||
- Various UI tweaks.<br />
|
- Various UI tweaks.<br />
|
||||||
|
@ -96,17 +103,17 @@
|
||||||
<span>2014.12.06 - 0.57</span>
|
<span>2014.12.06 - 0.57</span>
|
||||||
<p>
|
<p>
|
||||||
- Firmware flasher now contains firmware builds picker<br />
|
- Firmware flasher now contains firmware builds picker<br />
|
||||||
- Implemented new and experimental review mechanism<br />
|
- Implement new and experimental review mechanism<br />
|
||||||
- Support for new A-tail Quad craft type<br />
|
- Support for new A-tail Quad craft type<br />
|
||||||
- Firmware flasher flashing speed optimizations<br />
|
- Firmware flasher flashing speed optimizations<br />
|
||||||
- Added specific 3D models for atail/vtail quad (norem)<br />
|
- Add specific 3D models for atail/vtail quad (norem)<br />
|
||||||
- Major bugfix for stuck UI after delayed port open procedure<br />
|
- Major bugfix for stuck UI after delayed port open procedure<br />
|
||||||
- Bugfix for GPS distance to home not displaying<br />
|
- Bugfix for GPS distance to home not displaying<br />
|
||||||
- Bugfix for backup/restore misbehaving (mostly on OSX)<br />
|
- Bugfix for backup/restore misbehaving (mostly on OSX)<br />
|
||||||
</p>
|
</p>
|
||||||
<span>2014.11.04 - 0.56</span>
|
<span>2014.11.04 - 0.56</span>
|
||||||
<p>
|
<p>
|
||||||
- Added hex plus, hex X, tri, y4, y6 3D models (jef79m)<br />
|
- Add hex plus, hex X, tri, y4, y6 3D models (jef79m)<br />
|
||||||
- Bugfix for battery voltage saving sequence<br />
|
- Bugfix for battery voltage saving sequence<br />
|
||||||
- Bugfix for fetching development firmware<br />
|
- Bugfix for fetching development firmware<br />
|
||||||
</p>
|
</p>
|
||||||
|
@ -116,9 +123,9 @@
|
||||||
- Minimum accepted firmware version set to 2.31<br />
|
- Minimum accepted firmware version set to 2.31<br />
|
||||||
- Support for flashing development firmware<br />
|
- Support for flashing development firmware<br />
|
||||||
- Setup tab performance improvements, faster 3D model<br />
|
- Setup tab performance improvements, faster 3D model<br />
|
||||||
- Strongly improved amount of data stored in backups<br />
|
- Strongly improve amount of data stored in backups<br />
|
||||||
- Improved flash on connect in firmware flasher<br />
|
- Improve flash on connect in firmware flasher<br />
|
||||||
- Rearranged texts and options in firmware flasher<br />
|
- Rearrange texts and options in firmware flasher<br />
|
||||||
- Bugfix for corrupted minimum window size on Windows 7<br />
|
- Bugfix for corrupted minimum window size on Windows 7<br />
|
||||||
- Bugfix for incorrect date & time in firmware flasher<br />
|
- Bugfix for incorrect date & time in firmware flasher<br />
|
||||||
- Bugfix for port handler firing before port being initialized<br />
|
- Bugfix for port handler firing before port being initialized<br />
|
||||||
|
|
|
@ -30,12 +30,21 @@ function configuration_backup(callback) {
|
||||||
MSP_codes.MSP_PID,
|
MSP_codes.MSP_PID,
|
||||||
MSP_codes.MSP_RC_TUNING,
|
MSP_codes.MSP_RC_TUNING,
|
||||||
MSP_codes.MSP_ACC_TRIM,
|
MSP_codes.MSP_ACC_TRIM,
|
||||||
MSP_codes.MSP_SERVO_CONF,
|
MSP_codes.MSP_SERVO_CONFIGURATIONS,
|
||||||
MSP_codes.MSP_CHANNEL_FORWARDING,
|
|
||||||
MSP_codes.MSP_MODE_RANGES,
|
MSP_codes.MSP_MODE_RANGES,
|
||||||
MSP_codes.MSP_ADJUSTMENT_RANGES
|
MSP_codes.MSP_ADJUSTMENT_RANGES
|
||||||
];
|
];
|
||||||
|
|
||||||
|
function update_profile_specific_data_list() {
|
||||||
|
if (semver.lt(CONFIG.apiVersion, "1.12.0")) {
|
||||||
|
profileSpecificData.push(MSP_codes.MSP_CHANNEL_FORWARDING);
|
||||||
|
} else {
|
||||||
|
profileSpecificData.push(MSP_codes.MSP_SERVO_MIX_RULES);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
update_profile_specific_data_list();
|
||||||
|
|
||||||
function fetch_specific_data() {
|
function fetch_specific_data() {
|
||||||
var fetchingProfile = 0,
|
var fetchingProfile = 0,
|
||||||
codeKey = 0;
|
codeKey = 0;
|
||||||
|
@ -54,6 +63,7 @@ function configuration_backup(callback) {
|
||||||
'RC': jQuery.extend(true, {}, RC_tuning),
|
'RC': jQuery.extend(true, {}, RC_tuning),
|
||||||
'AccTrim': jQuery.extend(true, [], CONFIG.accelerometerTrims),
|
'AccTrim': jQuery.extend(true, [], CONFIG.accelerometerTrims),
|
||||||
'ServoConfig': jQuery.extend(true, [], SERVO_CONFIG),
|
'ServoConfig': jQuery.extend(true, [], SERVO_CONFIG),
|
||||||
|
'ServoRules': jQuery.extend(true, [], SERVO_RULES),
|
||||||
'ModeRanges': jQuery.extend(true, [], MODE_RANGES),
|
'ModeRanges': jQuery.extend(true, [], MODE_RANGES),
|
||||||
'AdjustmentRanges': jQuery.extend(true, [], ADJUSTMENT_RANGES)
|
'AdjustmentRanges': jQuery.extend(true, [], ADJUSTMENT_RANGES)
|
||||||
});
|
});
|
||||||
|
@ -428,6 +438,38 @@ function configuration_restore(callback) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (semver.lt(migratedVersion, '0.66.0')) {
|
||||||
|
// api 1.12 updated servo configuration protocol and added servo mixer rules
|
||||||
|
for (var profileIndex = 0; i < configuration.profiles.length; i++) {
|
||||||
|
|
||||||
|
if (semver.eq(configuration.apiVersion, '1.10.0')) {
|
||||||
|
// drop two unused servo configurations
|
||||||
|
while (configuration.profiles[profileIndex].ServoConfig.length > 8) {
|
||||||
|
configuration.profiles[profileIndex].ServoConfig.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < configuration.profiles[profileIndex].ServoConfig.length; i++) {
|
||||||
|
var servoConfig = profiles[profileIndex].ServoConfig;
|
||||||
|
|
||||||
|
servoConfig[i].angleAtMin = 90;
|
||||||
|
servoConfig[i].angleAtMax = 90;
|
||||||
|
servoConfig[i].reversedInputSources = 0;
|
||||||
|
|
||||||
|
// set the rate to 0 if an invalid value is detected.
|
||||||
|
if (servoConfig[i].rate < -100 || servoConfig[i].rate > 100) {
|
||||||
|
servoConfig[i].rate = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
configuration.profiles[profileIndex].ServoRules = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
migratedVersion = '0.66.0';
|
||||||
|
|
||||||
|
appliedMigrationsCount++;
|
||||||
|
}
|
||||||
|
|
||||||
if (appliedMigrationsCount > 0) {
|
if (appliedMigrationsCount > 0) {
|
||||||
GUI.log(chrome.i18n.getMessage('configMigrationSuccessful', [appliedMigrationsCount]));
|
GUI.log(chrome.i18n.getMessage('configMigrationSuccessful', [appliedMigrationsCount]));
|
||||||
}
|
}
|
||||||
|
@ -444,9 +486,7 @@ function configuration_restore(callback) {
|
||||||
MSP_codes.MSP_SET_PID_CONTROLLER,
|
MSP_codes.MSP_SET_PID_CONTROLLER,
|
||||||
MSP_codes.MSP_SET_PID,
|
MSP_codes.MSP_SET_PID,
|
||||||
MSP_codes.MSP_SET_RC_TUNING,
|
MSP_codes.MSP_SET_RC_TUNING,
|
||||||
MSP_codes.MSP_SET_ACC_TRIM,
|
MSP_codes.MSP_SET_ACC_TRIM
|
||||||
MSP_codes.MSP_SET_SERVO_CONF,
|
|
||||||
MSP_codes.MSP_SET_CHANNEL_FORWARDING
|
|
||||||
];
|
];
|
||||||
|
|
||||||
MSP.send_message(MSP_codes.MSP_STATUS, false, false, function () {
|
MSP.send_message(MSP_codes.MSP_STATUS, false, false, function () {
|
||||||
|
@ -472,6 +512,7 @@ function configuration_restore(callback) {
|
||||||
RC_tuning = configuration.profiles[profile].RC;
|
RC_tuning = configuration.profiles[profile].RC;
|
||||||
CONFIG.accelerometerTrims = configuration.profiles[profile].AccTrim;
|
CONFIG.accelerometerTrims = configuration.profiles[profile].AccTrim;
|
||||||
SERVO_CONFIG = configuration.profiles[profile].ServoConfig;
|
SERVO_CONFIG = configuration.profiles[profile].ServoConfig;
|
||||||
|
SERVO_RULES = configuration.profiles[profile].ServoRules;
|
||||||
MODE_RANGES = configuration.profiles[profile].ModeRanges;
|
MODE_RANGES = configuration.profiles[profile].ModeRanges;
|
||||||
ADJUSTMENT_RANGES = configuration.profiles[profile].AdjustmentRanges;
|
ADJUSTMENT_RANGES = configuration.profiles[profile].AdjustmentRanges;
|
||||||
}
|
}
|
||||||
|
@ -501,6 +542,14 @@ function configuration_restore(callback) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function upload_servo_mix_rules() {
|
||||||
|
MSP.sendServoMixRules(upload_servo_configuration);
|
||||||
|
}
|
||||||
|
|
||||||
|
function upload_servo_configuration() {
|
||||||
|
MSP.sendServoConfigurations(upload_mode_ranges);
|
||||||
|
}
|
||||||
|
|
||||||
function upload_mode_ranges() {
|
function upload_mode_ranges() {
|
||||||
MSP.sendModeRanges(upload_adjustment_ranges);
|
MSP.sendModeRanges(upload_adjustment_ranges);
|
||||||
}
|
}
|
||||||
|
@ -510,7 +559,7 @@ function configuration_restore(callback) {
|
||||||
}
|
}
|
||||||
// start uploading
|
// start uploading
|
||||||
load_objects(0);
|
load_objects(0);
|
||||||
upload_mode_ranges();
|
upload_servo_configuration();
|
||||||
}
|
}
|
||||||
|
|
||||||
function upload_unique_data() {
|
function upload_unique_data() {
|
||||||
|
|
37
js/boards.js
37
js/boards.js
|
@ -3,58 +3,43 @@
|
||||||
var BOARD_DEFINITIONS = [
|
var BOARD_DEFINITIONS = [
|
||||||
{
|
{
|
||||||
name: "CC3D",
|
name: "CC3D",
|
||||||
identifier: "CC3D",
|
identifier: "CC3D"
|
||||||
vcp: true
|
|
||||||
}, {
|
}, {
|
||||||
name: "ChebuzzF3",
|
name: "ChebuzzF3",
|
||||||
identifier: "CHF3",
|
identifier: "CHF3"
|
||||||
vcp: false
|
|
||||||
}, {
|
}, {
|
||||||
name: "CJMCU",
|
name: "CJMCU",
|
||||||
identifier: "CJM1",
|
identifier: "CJM1"
|
||||||
vcp: false
|
|
||||||
}, {
|
}, {
|
||||||
name: "EUSTM32F103RB",
|
name: "EUSTM32F103RB",
|
||||||
identifier: "EUF1",
|
identifier: "EUF1"
|
||||||
vcp: false
|
|
||||||
}, {
|
}, {
|
||||||
name: "Naze/Flip32+",
|
name: "Naze/Flip32+",
|
||||||
identifier: "AFNA",
|
identifier: "AFNA"
|
||||||
vcp: false
|
|
||||||
}, {
|
}, {
|
||||||
name: "Naze32Pro",
|
name: "Naze32Pro",
|
||||||
identifier: "AFF3",
|
identifier: "AFF3"
|
||||||
vcp: false
|
|
||||||
}, {
|
}, {
|
||||||
name: "Olimexino",
|
name: "Olimexino",
|
||||||
identifier: "OLI1"
|
identifier: "OLI1"
|
||||||
}, {
|
}, {
|
||||||
name: "Port103R",
|
name: "Port103R",
|
||||||
identifier: "103R",
|
identifier: "103R"
|
||||||
vcp: false
|
|
||||||
}, {
|
}, {
|
||||||
name: "Sparky",
|
name: "Sparky",
|
||||||
identifier: "SPKY",
|
identifier: "SPKY"
|
||||||
vcp: true
|
|
||||||
}, {
|
}, {
|
||||||
name: "STM32F3Discovery",
|
name: "STM32F3Discovery",
|
||||||
identifier: "SDF3",
|
identifier: "SDF3"
|
||||||
vcp: true
|
|
||||||
}, {
|
|
||||||
name: "Colibri Race",
|
|
||||||
identifier: "CLBR",
|
|
||||||
vcp: true
|
|
||||||
}, {
|
}, {
|
||||||
name: "SP Racing F3",
|
name: "SP Racing F3",
|
||||||
identifier: "SRF3",
|
identifier: "SRF3"
|
||||||
vcp: false
|
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
var DEFAULT_BOARD_DEFINITION = {
|
var DEFAULT_BOARD_DEFINITION = {
|
||||||
name: "Unknown",
|
name: "Unknown",
|
||||||
identifier: "????",
|
identifier: "????"
|
||||||
vcp: false
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var BOARD = {
|
var BOARD = {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var CONFIGURATOR = {
|
var CONFIGURATOR = {
|
||||||
'releaseDate': 1432389468227, // new Date().getTime() - Sat May 23 2015 14:57:54 GMT+0100 (BST)
|
'releaseDate': 1443815435720, // new Date().getTime() - Fri Oct 02 2015 20:50:49 GMT+0100 (GMT Daylight Time)
|
||||||
|
|
||||||
// all versions are specified and compared using semantic versioning http://semver.org/
|
// all versions are specified and compared using semantic versioning http://semver.org/
|
||||||
'apiVersionAccepted': '1.2.0',
|
'apiVersionAccepted': '1.2.0',
|
||||||
|
@ -86,6 +86,7 @@ var MODE_RANGES = [];
|
||||||
var ADJUSTMENT_RANGES = [];
|
var ADJUSTMENT_RANGES = [];
|
||||||
|
|
||||||
var SERVO_CONFIG = [];
|
var SERVO_CONFIG = [];
|
||||||
|
var SERVO_RULES = [];
|
||||||
|
|
||||||
var SERIAL_CONFIG = {
|
var SERIAL_CONFIG = {
|
||||||
ports: [],
|
ports: [],
|
||||||
|
|
4
js/libraries/jquery-2.1.4.min.js
vendored
Normal file
4
js/libraries/jquery-2.1.4.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
js/libraries/jquery-2.1.4.min.map
Normal file
1
js/libraries/jquery-2.1.4.min.map
Normal file
File diff suppressed because one or more lines are too long
13
js/libraries/jquery-ui-1.11.4.min.js
vendored
Normal file
13
js/libraries/jquery-ui-1.11.4.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
|
@ -24,5 +24,8 @@ var mixerList = [
|
||||||
{name: 'Dualcopter', model: 'custom', image: 'custom'},
|
{name: 'Dualcopter', model: 'custom', image: 'custom'},
|
||||||
{name: 'Singlecopter', model: 'custom', image: 'custom'},
|
{name: 'Singlecopter', model: 'custom', image: 'custom'},
|
||||||
{name: 'A-tail Quad', model: 'quad_atail', image: 'atail_quad'},
|
{name: 'A-tail Quad', model: 'quad_atail', image: 'atail_quad'},
|
||||||
{name: 'Custom', model: 'custom', image: 'custom'}
|
{name: 'Custom', model: 'custom', image: 'custom'},
|
||||||
|
{name: 'Custom Airplane', model: 'custom', image: 'custom'},
|
||||||
|
{name: 'Custom Tricopter', model: 'custom', image: 'custom'}
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
|
@ -238,21 +238,10 @@ function onConnect() {
|
||||||
$('#tabs ul.mode-connected').show();
|
$('#tabs ul.mode-connected').show();
|
||||||
|
|
||||||
if ("CLFL" == CONFIG.flightControllerIdentifier){
|
if ("CLFL" == CONFIG.flightControllerIdentifier){
|
||||||
|
|
||||||
/* placing this elsewhere
|
|
||||||
var documentationButton = $('#button-documentation');
|
var documentationButton = $('#button-documentation');
|
||||||
documentationButton.show();
|
documentationButton.show();
|
||||||
documentationButton.html("Documentation for "+CONFIG.flightControllerVersion);
|
documentationButton.html("Documentation for "+CONFIG.flightControllerVersion);
|
||||||
documentationButton.attr("href","https://github.com/cleanflight/cleanflight/tree/v{0}/docs".format(CONFIG.flightControllerVersion));
|
documentationButton.attr("href","https://github.com/cleanflight/cleanflight/tree/v{0}/docs".format(CONFIG.flightControllerVersion));
|
||||||
*/
|
|
||||||
|
|
||||||
/* just a thought
|
|
||||||
var sensor_state = $('#sensor-status');
|
|
||||||
sensor_state.show();
|
|
||||||
*/
|
|
||||||
|
|
||||||
var flashstate = $('#header_dataflash');
|
|
||||||
flashstate.show();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -266,14 +255,8 @@ function onClosed(result) {
|
||||||
$('#tabs ul.mode-connected').hide();
|
$('#tabs ul.mode-connected').hide();
|
||||||
$('#tabs ul.mode-disconnected').show();
|
$('#tabs ul.mode-disconnected').show();
|
||||||
|
|
||||||
|
var documentationButton = $('#button-documentation');
|
||||||
var flashstate = $('#header_dataflash');
|
documentationButton.hide();
|
||||||
flashstate.hide();
|
|
||||||
|
|
||||||
/* just a thought
|
|
||||||
var sensor_state = $('#sensor-status');
|
|
||||||
sensor_state.hide();
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function read_serial(info) {
|
function read_serial(info) {
|
||||||
|
|
|
@ -141,6 +141,13 @@ TABS.cli.read = function (readInfo) {
|
||||||
text += "<br />";
|
text += "<br />";
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 60:
|
||||||
|
text += '<';
|
||||||
|
break;
|
||||||
|
case 62:
|
||||||
|
text += '>';
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
text += String.fromCharCode(data[i]);
|
text += String.fromCharCode(data[i]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -99,6 +99,13 @@
|
||||||
|
|
||||||
border: 1px solid silver;
|
border: 1px solid silver;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tab-configuration .number input.disabled {
|
||||||
|
width: 50px;
|
||||||
|
padding: 0px 5px;
|
||||||
|
background-color: #ececec;
|
||||||
|
}
|
||||||
|
|
||||||
.tab-configuration .number span {
|
.tab-configuration .number span {
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
line-height: 20px;
|
line-height: 20px;
|
||||||
|
@ -154,7 +161,6 @@
|
||||||
.tab-configuration .disarm .checkbox span {
|
.tab-configuration .disarm .checkbox span {
|
||||||
margin-left: 15px;
|
margin-left: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tab-configuration .save {
|
.tab-configuration .save {
|
||||||
display: block;
|
display: block;
|
||||||
float: right;
|
float: right;
|
||||||
|
|
|
@ -127,19 +127,10 @@
|
||||||
<!-- list generated here -->
|
<!-- list generated here -->
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<div class="groupTitle" i18n="configurationRSSI"></div>
|
<div class="help">
|
||||||
<table>
|
<p i18n="configurationSerialRXHelp"></p>
|
||||||
<thead>
|
</div>
|
||||||
<tr>
|
|
||||||
<th i18n="configurationFeatureEnabled"></th>
|
|
||||||
<th i18n="configurationFeatureName"></th>
|
|
||||||
<th i18n="configurationFeatureDescription"></th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody class="features rssi">
|
|
||||||
<!-- table generated here -->
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
<div class="groupTitle" i18n="configurationFailsafe"></div>
|
<div class="groupTitle" i18n="configurationFailsafe"></div>
|
||||||
<table>
|
<table>
|
||||||
<thead>
|
<thead>
|
||||||
|
@ -159,8 +150,6 @@
|
||||||
<span i18n="configurationThrottleFailsafe"></span>
|
<span i18n="configurationThrottleFailsafe"></span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="rightWrapper current voltage">
|
<div class="rightWrapper current voltage">
|
||||||
<div class="groupTitle" i18n="configurationBatteryVoltage"></div>
|
<div class="groupTitle" i18n="configurationBatteryVoltage"></div>
|
||||||
|
@ -183,12 +172,6 @@
|
||||||
<span i18n="configurationBatteryMinimum"></span>
|
<span i18n="configurationBatteryMinimum"></span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="number">
|
|
||||||
<label>
|
|
||||||
<input type="number" name="warningcellvoltage" step="0.1" min="1" max="5" />
|
|
||||||
<span i18n="configurationBatteryWarning"></span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="number">
|
<div class="number">
|
||||||
<label>
|
<label>
|
||||||
<input type="number" name="maxcellvoltage" step="0.1" min="1" max="5" />
|
<input type="number" name="maxcellvoltage" step="0.1" min="1" max="5" />
|
||||||
|
@ -241,6 +224,40 @@
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="clear-both"></div>
|
||||||
|
|
||||||
|
<div class="leftWrapper rssi">
|
||||||
|
<div class="groupTitle" i18n="configurationRSSI"></div>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th i18n="configurationFeatureEnabled"></th>
|
||||||
|
<th i18n="configurationFeatureName"></th>
|
||||||
|
<th i18n="configurationFeatureDescription"></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody class="features rssi">
|
||||||
|
<!-- table generated here -->
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div class="rightWrapper system">
|
||||||
|
<div class="groupTitle" i18n="configurationSystem"></div>
|
||||||
|
<div class="number">
|
||||||
|
<label>
|
||||||
|
<input type="number" name="looptime" step="100" min="0" max="9000"/>
|
||||||
|
<span i18n="configurationLoopTime"></span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="number">
|
||||||
|
<label>
|
||||||
|
<input type="text" name="looptimehz" readonly="readonly" class="disabled"/>
|
||||||
|
<span i18n="configurationCalculatedCyclesSec"></span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<p class="help" i18n="configurationLoopTimeHelp"></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="clear-both"></div>
|
<div class="clear-both"></div>
|
||||||
<div class="leftWrapper gps">
|
<div class="leftWrapper gps">
|
||||||
<div class="groupTitle" i18n="configurationGPS"></div>
|
<div class="groupTitle" i18n="configurationGPS"></div>
|
||||||
|
@ -281,6 +298,11 @@
|
||||||
<span i18n="configurationMagDeclination"></span>
|
<span i18n="configurationMagDeclination"></span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="help">
|
||||||
|
<p i18n="configurationGPSHelp"></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="rightWrapper">
|
<div class="rightWrapper">
|
||||||
<div class="groupTitle" i18n="configurationFeatures"></div>
|
<div class="groupTitle" i18n="configurationFeatures"></div>
|
||||||
|
@ -297,6 +319,7 @@
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="clear-both"></div>
|
<div class="clear-both"></div>
|
||||||
<div class="buttons">
|
<div class="buttons">
|
||||||
<a class="save" href="#" i18n="configurationButtonSave"></a>
|
<a class="save" href="#" i18n="configurationButtonSave"></a>
|
||||||
|
|
55
tabs/configuration.js
Executable file → Normal file
55
tabs/configuration.js
Executable file → Normal file
|
@ -36,7 +36,11 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function load_arming_config() {
|
function load_arming_config() {
|
||||||
MSP.send_message(MSP_codes.MSP_ARMING_CONFIG, false, false, load_html);
|
MSP.send_message(MSP_codes.MSP_ARMING_CONFIG, false, false, load_loop_time);
|
||||||
|
}
|
||||||
|
|
||||||
|
function load_loop_time() {
|
||||||
|
MSP.send_message(MSP_codes.MSP_LOOP_TIME, false, false, load_html);
|
||||||
}
|
}
|
||||||
|
|
||||||
function load_html() {
|
function load_html() {
|
||||||
|
@ -45,6 +49,17 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
|
||||||
|
|
||||||
MSP.send_message(MSP_codes.MSP_IDENT, false, false, load_config);
|
MSP.send_message(MSP_codes.MSP_IDENT, false, false, load_config);
|
||||||
|
|
||||||
|
function recalculate_cycles_sec() {
|
||||||
|
var looptime = $('input[name="looptime"]').val();
|
||||||
|
|
||||||
|
var message = 'Max';
|
||||||
|
if (looptime > 0) {
|
||||||
|
message = parseFloat((1 / looptime) * 1000 * 1000).toFixed(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
$('input[name="looptimehz"]').val(message);
|
||||||
|
}
|
||||||
|
|
||||||
function process_html() {
|
function process_html() {
|
||||||
// translate to user-selected language
|
// translate to user-selected language
|
||||||
localize();
|
localize();
|
||||||
|
@ -73,7 +88,7 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
|
||||||
{bit: 3, group: 'rxMode', mode: 'group', name: 'RX_SERIAL', description: 'Serial-based receiver (SPEKSAT, SBUS, SUMD)'},
|
{bit: 3, group: 'rxMode', mode: 'group', name: 'RX_SERIAL', description: 'Serial-based receiver (SPEKSAT, SBUS, SUMD)'},
|
||||||
{bit: 4, group: 'esc', name: 'MOTOR_STOP', description: 'Don\'t spin the motors when armed'},
|
{bit: 4, group: 'esc', name: 'MOTOR_STOP', description: 'Don\'t spin the motors when armed'},
|
||||||
{bit: 5, group: 'other', name: 'SERVO_TILT', description: 'Servo gimbal'},
|
{bit: 5, group: 'other', name: 'SERVO_TILT', description: 'Servo gimbal'},
|
||||||
{bit: 6, group: 'other', name: 'SOFTSERIAL', description: 'Enable CPU based serial ports (configure port scenario first)'},
|
{bit: 6, group: 'other', name: 'SOFTSERIAL', description: 'Enable CPU based serial ports'},
|
||||||
{bit: 7, group: 'gps', name: 'GPS', description: 'GPS (configure port scenario first)'},
|
{bit: 7, group: 'gps', name: 'GPS', description: 'GPS (configure port scenario first)'},
|
||||||
{bit: 8, group: 'rxFailsafe', name: 'FAILSAFE', description: 'Failsafe settings on RX signal loss'},
|
{bit: 8, group: 'rxFailsafe', name: 'FAILSAFE', description: 'Failsafe settings on RX signal loss'},
|
||||||
{bit: 9, group: 'other', name: 'SONAR', description: 'Sonar'},
|
{bit: 9, group: 'other', name: 'SONAR', description: 'Sonar'},
|
||||||
|
@ -89,6 +104,12 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
|
||||||
{bit: 19, group: 'other', name: 'BLACKBOX', description: 'Blackbox flight data recorder'}
|
{bit: 19, group: 'other', name: 'BLACKBOX', description: 'Blackbox flight data recorder'}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
if (semver.gte(CONFIG.apiVersion, "1.12.0")) {
|
||||||
|
features.push(
|
||||||
|
{bit: 20, group: 'other', name: 'CHANNEL_FORWARDING', description: 'Forward aux channels to remaining servo outputs'}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
var radioGroups = [];
|
var radioGroups = [];
|
||||||
|
|
||||||
var features_e = $('.features');
|
var features_e = $('.features');
|
||||||
|
@ -256,7 +277,7 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
|
||||||
// fill magnetometer
|
// fill magnetometer
|
||||||
$('input[name="mag_declination"]').val(MISC.mag_declination);
|
$('input[name="mag_declination"]').val(MISC.mag_declination);
|
||||||
|
|
||||||
//fill motor disarm params
|
//fill motor disarm params and FC loop time
|
||||||
if(semver.gte(CONFIG.apiVersion, "1.8.0")) {
|
if(semver.gte(CONFIG.apiVersion, "1.8.0")) {
|
||||||
$('input[name="autodisarmdelay"]').val(ARMING_CONFIG.auto_disarm_delay);
|
$('input[name="autodisarmdelay"]').val(ARMING_CONFIG.auto_disarm_delay);
|
||||||
$('input[name="disarmkillswitch"]').prop('checked', ARMING_CONFIG.disarm_kill_switch);
|
$('input[name="disarmkillswitch"]').prop('checked', ARMING_CONFIG.disarm_kill_switch);
|
||||||
|
@ -265,6 +286,13 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
|
||||||
$('div.disarmdelay').show();
|
$('div.disarmdelay').show();
|
||||||
else
|
else
|
||||||
$('div.disarmdelay').hide();
|
$('div.disarmdelay').hide();
|
||||||
|
|
||||||
|
// fill FC loop time
|
||||||
|
$('input[name="looptime"]').val(FC_CONFIG.loopTime);
|
||||||
|
|
||||||
|
recalculate_cycles_sec();
|
||||||
|
|
||||||
|
$('div.cycles').show();
|
||||||
}
|
}
|
||||||
|
|
||||||
// fill throttle
|
// fill throttle
|
||||||
|
@ -276,7 +304,6 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
|
||||||
|
|
||||||
// fill battery
|
// fill battery
|
||||||
$('input[name="mincellvoltage"]').val(MISC.vbatmincellvoltage);
|
$('input[name="mincellvoltage"]').val(MISC.vbatmincellvoltage);
|
||||||
$('input[name="warningcellvoltage"]').val(MISC.vbatwarningcellvoltage);
|
|
||||||
$('input[name="maxcellvoltage"]').val(MISC.vbatmaxcellvoltage);
|
$('input[name="maxcellvoltage"]').val(MISC.vbatmaxcellvoltage);
|
||||||
$('input[name="warningcellvoltage"]').val(MISC.vbatwarningcellvoltage);
|
$('input[name="warningcellvoltage"]').val(MISC.vbatwarningcellvoltage);
|
||||||
$('input[name="voltagescale"]').val(MISC.vbatscale);
|
$('input[name="voltagescale"]').val(MISC.vbatscale);
|
||||||
|
@ -288,6 +315,10 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
|
||||||
|
|
||||||
|
|
||||||
// UI hooks
|
// UI hooks
|
||||||
|
$('input[name="looptime"]').change(function() {
|
||||||
|
recalculate_cycles_sec();
|
||||||
|
});
|
||||||
|
|
||||||
$('input[type="checkbox"].feature', features_e).change(function () {
|
$('input[type="checkbox"].feature', features_e).change(function () {
|
||||||
var element = $(this),
|
var element = $(this),
|
||||||
index = element.data('bit'),
|
index = element.data('bit'),
|
||||||
|
@ -339,6 +370,7 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
|
||||||
if(semver.gte(CONFIG.apiVersion, "1.8.0")) {
|
if(semver.gte(CONFIG.apiVersion, "1.8.0")) {
|
||||||
ARMING_CONFIG.auto_disarm_delay = parseInt($('input[name="autodisarmdelay"]').val());
|
ARMING_CONFIG.auto_disarm_delay = parseInt($('input[name="autodisarmdelay"]').val());
|
||||||
ARMING_CONFIG.disarm_kill_switch = ~~$('input[name="disarmkillswitch"]').is(':checked'); // ~~ boolean to decimal conversion
|
ARMING_CONFIG.disarm_kill_switch = ~~$('input[name="disarmkillswitch"]').is(':checked'); // ~~ boolean to decimal conversion
|
||||||
|
FC_CONFIG.loopTime = parseInt($('input[name="looptime"]').val());
|
||||||
}
|
}
|
||||||
|
|
||||||
MISC.minthrottle = parseInt($('input[name="minthrottle"]').val());
|
MISC.minthrottle = parseInt($('input[name="minthrottle"]').val());
|
||||||
|
@ -348,7 +380,6 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
|
||||||
MISC.mincommand = parseInt($('input[name="mincommand"]').val());
|
MISC.mincommand = parseInt($('input[name="mincommand"]').val());
|
||||||
|
|
||||||
MISC.vbatmincellvoltage = parseFloat($('input[name="mincellvoltage"]').val());
|
MISC.vbatmincellvoltage = parseFloat($('input[name="mincellvoltage"]').val());
|
||||||
MISC.vbatwarningcellvoltage = parseFloat($('input[name="warningcellvoltage"]').val());
|
|
||||||
MISC.vbatmaxcellvoltage = parseFloat($('input[name="maxcellvoltage"]').val());
|
MISC.vbatmaxcellvoltage = parseFloat($('input[name="maxcellvoltage"]').val());
|
||||||
MISC.vbatwarningcellvoltage = parseFloat($('input[name="warningcellvoltage"]').val());
|
MISC.vbatwarningcellvoltage = parseFloat($('input[name="warningcellvoltage"]').val());
|
||||||
MISC.vbatscale = parseInt($('input[name="voltagescale"]').val());
|
MISC.vbatscale = parseInt($('input[name="voltagescale"]').val());
|
||||||
|
@ -375,7 +406,11 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function save_arming_config() {
|
function save_arming_config() {
|
||||||
MSP.send_message(MSP_codes.MSP_SET_ARMING_CONFIG, MSP.crunch(MSP_codes.MSP_SET_ARMING_CONFIG), false, save_to_eeprom);
|
MSP.send_message(MSP_codes.MSP_SET_ARMING_CONFIG, MSP.crunch(MSP_codes.MSP_SET_ARMING_CONFIG), false, save_looptime_config);
|
||||||
|
}
|
||||||
|
|
||||||
|
function save_looptime_config() {
|
||||||
|
MSP.send_message(MSP_codes.MSP_SET_LOOP_TIME, MSP.crunch(MSP_codes.MSP_SET_LOOP_TIME), false, save_to_eeprom);
|
||||||
}
|
}
|
||||||
|
|
||||||
function save_to_eeprom() {
|
function save_to_eeprom() {
|
||||||
|
@ -393,13 +428,6 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
|
||||||
function reinitialize() {
|
function reinitialize() {
|
||||||
GUI.log(chrome.i18n.getMessage('deviceRebooting'));
|
GUI.log(chrome.i18n.getMessage('deviceRebooting'));
|
||||||
|
|
||||||
if (BOARD.find_board_definition(CONFIG.boardIdentifier).vcp) { // VCP-based flight controls may crash old drivers, we catch and reconnect
|
|
||||||
$('a.connect').click();
|
|
||||||
GUI.timeout_add('start_connection',function start_connection() {
|
|
||||||
$('a.connect').click();
|
|
||||||
},2000);
|
|
||||||
} else {
|
|
||||||
|
|
||||||
GUI.timeout_add('waiting_for_bootup', function waiting_for_bootup() {
|
GUI.timeout_add('waiting_for_bootup', function waiting_for_bootup() {
|
||||||
MSP.send_message(MSP_codes.MSP_IDENT, false, false, function () {
|
MSP.send_message(MSP_codes.MSP_IDENT, false, false, function () {
|
||||||
GUI.log(chrome.i18n.getMessage('deviceReady'));
|
GUI.log(chrome.i18n.getMessage('deviceReady'));
|
||||||
|
@ -407,7 +435,6 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
|
||||||
});
|
});
|
||||||
},1500); // 1500 ms seems to be just the right amount of delay to prevent data request timeouts
|
},1500); // 1500 ms seems to be just the right amount of delay to prevent data request timeouts
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
MSP.send_message(MSP_codes.MSP_SET_BF_CONFIG, MSP.crunch(MSP_codes.MSP_SET_BF_CONFIG), false, save_serial_config);
|
MSP.send_message(MSP_codes.MSP_SET_BF_CONFIG, MSP.crunch(MSP_codes.MSP_SET_BF_CONFIG), false, save_serial_config);
|
||||||
});
|
});
|
||||||
|
|
|
@ -59,7 +59,7 @@ TABS.dataflash.initialize = function (callback) {
|
||||||
display: 'block'
|
display: 'block'
|
||||||
});
|
});
|
||||||
|
|
||||||
$(".tab-dataflash .dataflash-used div").text('Used space: ' + formatFilesize(DATAFLASH.usedSize));
|
$(".tab-dataflash .dataflash-used div").text('Used space ' + formatFilesize(DATAFLASH.usedSize));
|
||||||
} else {
|
} else {
|
||||||
$(".tab-dataflash .dataflash-used").css({
|
$(".tab-dataflash .dataflash-used").css({
|
||||||
display: 'none'
|
display: 'none'
|
||||||
|
@ -71,7 +71,7 @@ TABS.dataflash.initialize = function (callback) {
|
||||||
width: ((DATAFLASH.totalSize - DATAFLASH.usedSize) / DATAFLASH.totalSize * 100) + "%",
|
width: ((DATAFLASH.totalSize - DATAFLASH.usedSize) / DATAFLASH.totalSize * 100) + "%",
|
||||||
display: 'block'
|
display: 'block'
|
||||||
});
|
});
|
||||||
$(".tab-dataflash .dataflash-free div").text('Free space: ' + formatFilesize(DATAFLASH.totalSize - DATAFLASH.usedSize));
|
$(".tab-dataflash .dataflash-free div").text('Free space ' + formatFilesize(DATAFLASH.totalSize - DATAFLASH.usedSize));
|
||||||
} else {
|
} else {
|
||||||
$(".tab-dataflash .dataflash-free").css({
|
$(".tab-dataflash .dataflash-free").css({
|
||||||
display: 'none'
|
display: 'none'
|
||||||
|
@ -146,11 +146,23 @@ TABS.dataflash.initialize = function (callback) {
|
||||||
$(".dataflash-saving").addClass("done");
|
$(".dataflash-saving").addClass("done");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function flash_update_summary(onDone) {
|
||||||
|
MSP.send_message(MSP_codes.MSP_DATAFLASH_SUMMARY, false, false, function() {
|
||||||
|
update_html();
|
||||||
|
|
||||||
|
if (onDone) {
|
||||||
|
onDone();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function flash_save_begin() {
|
function flash_save_begin() {
|
||||||
|
if (GUI.connected_to) {
|
||||||
|
// Begin by refreshing the occupied size in case it changed while the tab was open
|
||||||
|
flash_update_summary(function() {
|
||||||
var
|
var
|
||||||
maxBytes = DATAFLASH.usedSize;
|
maxBytes = DATAFLASH.usedSize;
|
||||||
|
|
||||||
if (GUI.connected_to) {
|
|
||||||
prepare_file(function(fileWriter) {
|
prepare_file(function(fileWriter) {
|
||||||
var
|
var
|
||||||
nextAddress = 0;
|
nextAddress = 0;
|
||||||
|
@ -194,6 +206,7 @@ TABS.dataflash.initialize = function (callback) {
|
||||||
// Fetch the initial block
|
// Fetch the initial block
|
||||||
MSP.dataflashRead(nextAddress, onChunkRead);
|
MSP.dataflashRead(nextAddress, onChunkRead);
|
||||||
});
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,8 +259,7 @@ TABS.dataflash.initialize = function (callback) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function poll_for_erase_completion() {
|
function poll_for_erase_completion() {
|
||||||
MSP.send_message(MSP_codes.MSP_DATAFLASH_SUMMARY, false, false, function() {
|
flash_update_summary(function() {
|
||||||
update_html();
|
|
||||||
if (!eraseCancelled) {
|
if (!eraseCancelled) {
|
||||||
if (DATAFLASH.ready) {
|
if (DATAFLASH.ready) {
|
||||||
$(".dataflash-confirm-erase")[0].close();
|
$(".dataflash-confirm-erase")[0].close();
|
||||||
|
|
|
@ -39,7 +39,7 @@ TABS.firmware_flasher.initialize = function (callback) {
|
||||||
var showDevReleases = ($('input.show_development_releases').is(':checked'));
|
var showDevReleases = ($('input.show_development_releases').is(':checked'));
|
||||||
releases_e.append($("<option value='0'>{0}</option>".format(chrome.i18n.getMessage('firmwareFlasherOptionLabelSelectFirmware'))));
|
releases_e.append($("<option value='0'>{0}</option>".format(chrome.i18n.getMessage('firmwareFlasherOptionLabelSelectFirmware'))));
|
||||||
|
|
||||||
var releaseDescritpors = [];
|
var releaseDescriptors = [];
|
||||||
TABS.firmware_flasher.releases.forEach(function(release){
|
TABS.firmware_flasher.releases.forEach(function(release){
|
||||||
release.assets.forEach(function(asset){
|
release.assets.forEach(function(asset){
|
||||||
var targetFromFilenameExpression = /.*_(.*)\.(.*)/;
|
var targetFromFilenameExpression = /.*_(.*)\.(.*)/;
|
||||||
|
@ -81,11 +81,11 @@ TABS.firmware_flasher.initialize = function (callback) {
|
||||||
"status" : release.prerelease ? "release-candidate" : "stable"
|
"status" : release.prerelease ? "release-candidate" : "stable"
|
||||||
};
|
};
|
||||||
|
|
||||||
releaseDescritpors.push(descriptor);
|
releaseDescriptors.push(descriptor);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
releaseDescritpors.sort(function(o1,o2){
|
releaseDescriptors.sort(function(o1,o2){
|
||||||
// compare versions descending
|
// compare versions descending
|
||||||
var cmpVal = semver(o2.version).compare(semver(o1.version));
|
var cmpVal = semver(o2.version).compare(semver(o1.version));
|
||||||
if (cmpVal == 0){
|
if (cmpVal == 0){
|
||||||
|
@ -96,7 +96,7 @@ TABS.firmware_flasher.initialize = function (callback) {
|
||||||
});
|
});
|
||||||
|
|
||||||
var optionIndex = 1;
|
var optionIndex = 1;
|
||||||
releaseDescritpors.forEach(function(descriptor){
|
releaseDescriptors.forEach(function(descriptor){
|
||||||
var select_e =
|
var select_e =
|
||||||
$("<option value='{0}'>{1} {2} {3} ({4})</option>".format(
|
$("<option value='{0}'>{1} {2} {3} ({4})</option>".format(
|
||||||
optionIndex++,
|
optionIndex++,
|
||||||
|
|
|
@ -272,7 +272,7 @@ TABS.motors.initialize = function (callback) {
|
||||||
');
|
');
|
||||||
|
|
||||||
servos_wrapper.append('\
|
servos_wrapper.append('\
|
||||||
<div class="m-block servo-' + i + '">\
|
<div class="m-block servo-' + (7 - i) + '">\
|
||||||
<div class="meter-bar">\
|
<div class="meter-bar">\
|
||||||
<div class="label"></div>\
|
<div class="label"></div>\
|
||||||
<div class="indicator">\
|
<div class="indicator">\
|
||||||
|
|
|
@ -71,13 +71,13 @@
|
||||||
border: 1px dashed silver;
|
border: 1px dashed silver;
|
||||||
margin-bottom: 8px;
|
margin-bottom: 8px;
|
||||||
}
|
}
|
||||||
.require-support {
|
.tab-ports .require-support {
|
||||||
display:none;
|
display:none;
|
||||||
}
|
}
|
||||||
.tab-ports.supported .require-support {
|
.tab-ports.supported .require-support {
|
||||||
display:block;
|
display:block;
|
||||||
}
|
}
|
||||||
.require-upgrade {
|
.tab-ports .require-upgrade {
|
||||||
display:block;
|
display:block;
|
||||||
}
|
}
|
||||||
.tab-ports.supported .require-upgrade {
|
.tab-ports.supported .require-upgrade {
|
||||||
|
|
|
@ -18,6 +18,11 @@
|
||||||
<tbody>
|
<tbody>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
<div class="help">
|
||||||
|
<p i18n="portsMSPHelp"></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="clear-both"></div>
|
<div class="clear-both"></div>
|
||||||
<div class="buttons">
|
<div class="buttons">
|
||||||
<a class="save" href="#" i18n="portsButtonSave"></a>
|
<a class="save" href="#" i18n="portsButtonSave"></a>
|
||||||
|
|
17
tabs/ports.js
Executable file → Normal file
17
tabs/ports.js
Executable file → Normal file
|
@ -239,9 +239,12 @@ TABS.ports.initialize = function (callback, scrollPosition) {
|
||||||
blackbox_baudrate: $(portConfiguration_e).find('.blackbox_baudrate').val(),
|
blackbox_baudrate: $(portConfiguration_e).find('.blackbox_baudrate').val(),
|
||||||
identifier: oldSerialPort.identifier
|
identifier: oldSerialPort.identifier
|
||||||
};
|
};
|
||||||
|
|
||||||
|
console.log(serialPort);
|
||||||
SERIAL_CONFIG.ports.push(serialPort);
|
SERIAL_CONFIG.ports.push(serialPort);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
MSP.send_message(MSP_codes.MSP_SET_CF_SERIAL_CONFIG, MSP.crunch(MSP_codes.MSP_SET_CF_SERIAL_CONFIG), false, save_to_eeprom);
|
MSP.send_message(MSP_codes.MSP_SET_CF_SERIAL_CONFIG, MSP.crunch(MSP_codes.MSP_SET_CF_SERIAL_CONFIG), false, save_to_eeprom);
|
||||||
|
|
||||||
function save_to_eeprom() {
|
function save_to_eeprom() {
|
||||||
|
@ -259,22 +262,14 @@ TABS.ports.initialize = function (callback, scrollPosition) {
|
||||||
function on_reboot_success_handler() {
|
function on_reboot_success_handler() {
|
||||||
GUI.log(chrome.i18n.getMessage('deviceRebooting'));
|
GUI.log(chrome.i18n.getMessage('deviceRebooting'));
|
||||||
|
|
||||||
if (BOARD.find_board_definition(CONFIG.boardIdentifier).vcp) { // VCP-based flight controls may crash old drivers, we catch and reconnect
|
var rebootTimeoutDelay = 1500; // seems to be just the right amount of delay to prevent data request timeouts
|
||||||
$('a.connect').click();
|
|
||||||
GUI.timeout_add('start_connection',function start_connection() {
|
|
||||||
$('a.connect').click();
|
|
||||||
},2000);
|
|
||||||
} else {
|
|
||||||
GUI.timeout_add('waiting_for_bootup', function waiting_for_bootup() {
|
GUI.timeout_add('waiting_for_bootup', function waiting_for_bootup() {
|
||||||
MSP.send_message(MSP_codes.MSP_IDENT, false, false, function () {
|
MSP.send_message(MSP_codes.MSP_IDENT, false, false, function () {
|
||||||
GUI.log(chrome.i18n.getMessage('deviceReady'));
|
GUI.log(chrome.i18n.getMessage('deviceReady'));
|
||||||
TABS.ports.initialize(false, $('#content').scrollTop());
|
TABS.ports.initialize(false, $('#content').scrollTop());
|
||||||
});
|
});
|
||||||
}, 1500); // seems to be just the right amount of delay to prevent data request timeouts
|
}, rebootTimeoutDelay);
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,6 +3,12 @@
|
||||||
.tab-receiver input[type="number"]::-webkit-inner-spin-button {
|
.tab-receiver input[type="number"]::-webkit-inner-spin-button {
|
||||||
border: 0;
|
border: 0;
|
||||||
}
|
}
|
||||||
|
.tab-receiver .help {
|
||||||
|
padding: 10px;
|
||||||
|
background-color: #ffcb18;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
.tab-receiver .bars {
|
.tab-receiver .bars {
|
||||||
float: left;
|
float: left;
|
||||||
width: 45%;
|
width: 45%;
|
||||||
|
@ -218,7 +224,7 @@
|
||||||
margin: 0 10px 10px 0;
|
margin: 0 10px 10px 0;
|
||||||
|
|
||||||
width: 220px;
|
width: 220px;
|
||||||
height: 58px;
|
height: 120px;
|
||||||
|
|
||||||
border: 1px solid silver;
|
border: 1px solid silver;
|
||||||
}
|
}
|
||||||
|
@ -226,7 +232,7 @@
|
||||||
margin: 0 10px 0 0;
|
margin: 0 10px 0 0;
|
||||||
|
|
||||||
width: 220px;
|
width: 220px;
|
||||||
height: 58px;
|
height: 120px;
|
||||||
|
|
||||||
border: 1px solid silver;
|
border: 1px solid silver;
|
||||||
}
|
}
|
||||||
|
@ -293,6 +299,7 @@
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 10px;
|
bottom: 10px;
|
||||||
}
|
}
|
||||||
|
.tab-receiver .sticks,
|
||||||
.tab-receiver .update,
|
.tab-receiver .update,
|
||||||
.tab-receiver .refresh {
|
.tab-receiver .refresh {
|
||||||
display: block;
|
display: block;
|
||||||
|
@ -311,6 +318,7 @@
|
||||||
border: 1px solid silver;
|
border: 1px solid silver;
|
||||||
background-color: #ececec;
|
background-color: #ececec;
|
||||||
}
|
}
|
||||||
|
.tab-receiver .sticks,
|
||||||
.tab-receiver .refresh {
|
.tab-receiver .refresh {
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
<div id="content-watermark"></div>
|
<div id="content-watermark"></div>
|
||||||
<div class="tab-receiver">
|
<div class="tab-receiver">
|
||||||
|
<div class="help">
|
||||||
|
<p i18n="receiverHelp"></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="bars">
|
<div class="bars">
|
||||||
</div>
|
</div>
|
||||||
<div class="tunings">
|
<div class="tunings">
|
||||||
|
@ -53,10 +57,10 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="curves">
|
<div class="curves">
|
||||||
<div class="throttle_curve">
|
<div class="throttle_curve">
|
||||||
<canvas width="220" height="58"></canvas>
|
<canvas width="220" height="120"></canvas>
|
||||||
</div>
|
</div>
|
||||||
<div class="pitch_roll_curve">
|
<div class="pitch_roll_curve">
|
||||||
<canvas width="220" height="58"></canvas>
|
<canvas width="220" height="120"></canvas>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="clear-both"></div>
|
<div class="clear-both"></div>
|
||||||
|
@ -82,5 +86,6 @@
|
||||||
<div class="buttons">
|
<div class="buttons">
|
||||||
<a class="update" href="#" i18n="receiverButtonSave"></a>
|
<a class="update" href="#" i18n="receiverButtonSave"></a>
|
||||||
<a class="refresh" href="#" i18n="receiverButtonRefresh"></a>
|
<a class="refresh" href="#" i18n="receiverButtonRefresh"></a>
|
||||||
|
<a class="sticks" href="#" i18n="receiverButtonSticks"></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
TABS.receiver = {};
|
TABS.receiver = {
|
||||||
|
rateChartHeight: 120
|
||||||
|
};
|
||||||
|
|
||||||
TABS.receiver.initialize = function (callback) {
|
TABS.receiver.initialize = function (callback) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
|
@ -18,7 +21,12 @@ TABS.receiver.initialize = function (callback) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function get_rc_map() {
|
function get_rc_map() {
|
||||||
MSP.send_message(MSP_codes.MSP_RX_MAP, false, false, load_html);
|
MSP.send_message(MSP_codes.MSP_RX_MAP, false, false, load_config);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fetch features so we can check if RX_MSP is enabled:
|
||||||
|
function load_config() {
|
||||||
|
MSP.send_message(MSP_codes.MSP_BF_CONFIG, false, false, load_html);
|
||||||
}
|
}
|
||||||
|
|
||||||
function load_html() {
|
function load_html() {
|
||||||
|
@ -52,7 +60,12 @@ TABS.receiver.initialize = function (callback) {
|
||||||
});
|
});
|
||||||
|
|
||||||
// generate bars
|
// generate bars
|
||||||
var bar_names = ['Roll', 'Pitch', 'Yaw', 'Throttle'],
|
var bar_names = [
|
||||||
|
chrome.i18n.getMessage('controlAxisRoll'),
|
||||||
|
chrome.i18n.getMessage('controlAxisPitch'),
|
||||||
|
chrome.i18n.getMessage('controlAxisYaw'),
|
||||||
|
chrome.i18n.getMessage('controlAxisThrottle')
|
||||||
|
],
|
||||||
bar_container = $('.tab-receiver .bars'),
|
bar_container = $('.tab-receiver .bars'),
|
||||||
aux_index = 1;
|
aux_index = 1;
|
||||||
|
|
||||||
|
@ -61,7 +74,7 @@ TABS.receiver.initialize = function (callback) {
|
||||||
if (i < bar_names.length) {
|
if (i < bar_names.length) {
|
||||||
name = bar_names[i];
|
name = bar_names[i];
|
||||||
} else {
|
} else {
|
||||||
name = 'AUX ' + aux_index++;
|
name = chrome.i18n.getMessage("controlAxisAux" + (aux_index++));
|
||||||
}
|
}
|
||||||
|
|
||||||
bar_container.append('\
|
bar_container.append('\
|
||||||
|
@ -176,6 +189,8 @@ TABS.receiver.initialize = function (callback) {
|
||||||
|
|
||||||
$('select[name="rssi_channel"]').val(MISC.rssi_channel);
|
$('select[name="rssi_channel"]').val(MISC.rssi_channel);
|
||||||
|
|
||||||
|
var rateHeight = TABS.receiver.rateChartHeight;
|
||||||
|
|
||||||
// UI Hooks
|
// UI Hooks
|
||||||
// curves
|
// curves
|
||||||
$('.tunings .throttle input').on('input change', function () {
|
$('.tunings .throttle input').on('input change', function () {
|
||||||
|
@ -201,14 +216,14 @@ TABS.receiver.initialize = function (callback) {
|
||||||
var midx = 220 * mid,
|
var midx = 220 * mid,
|
||||||
midxl = midx * 0.5,
|
midxl = midx * 0.5,
|
||||||
midxr = (((220 - midx) * 0.5) + midx),
|
midxr = (((220 - midx) * 0.5) + midx),
|
||||||
midy = 58 - (midx * (58 / 220)),
|
midy = rateHeight - (midx * (rateHeight / 220)),
|
||||||
midyl = 58 - ((58 - midy) * 0.5 *(expo + 1)),
|
midyl = rateHeight - ((rateHeight - midy) * 0.5 *(expo + 1)),
|
||||||
midyr = (midy / 2) * (expo + 1);
|
midyr = (midy / 2) * (expo + 1);
|
||||||
|
|
||||||
// draw
|
// draw
|
||||||
context.clearRect(0, 0, 220, 58);
|
context.clearRect(0, 0, 220, rateHeight);
|
||||||
context.beginPath();
|
context.beginPath();
|
||||||
context.moveTo(0, 58);
|
context.moveTo(0, rateHeight);
|
||||||
context.quadraticCurveTo(midxl, midyl, midx, midy);
|
context.quadraticCurveTo(midxl, midyl, midx, midy);
|
||||||
context.moveTo(midx, midy);
|
context.moveTo(midx, midy);
|
||||||
context.quadraticCurveTo(midxr, midyr, 220, 0);
|
context.quadraticCurveTo(midxr, midyr, 220, 0);
|
||||||
|
@ -237,13 +252,13 @@ TABS.receiver.initialize = function (callback) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// math magic by englishman
|
// math magic by englishman
|
||||||
var ratey = 58 * rate;
|
var ratey = rateHeight * rate;
|
||||||
|
|
||||||
// draw
|
// draw
|
||||||
context.clearRect(0, 0, 220, 58);
|
context.clearRect(0, 0, 220, rateHeight);
|
||||||
context.beginPath();
|
context.beginPath();
|
||||||
context.moveTo(0, 58);
|
context.moveTo(0, rateHeight);
|
||||||
context.quadraticCurveTo(110, 58 - ((ratey / 2) * (1 - expo)), 220, 58 - ratey);
|
context.quadraticCurveTo(110, rateHeight - ((ratey / 2) * (1 - expo)), 220, rateHeight - ratey);
|
||||||
context.lineWidth = 2;
|
context.lineWidth = 2;
|
||||||
context.stroke();
|
context.stroke();
|
||||||
}, 0);
|
}, 0);
|
||||||
|
@ -303,6 +318,35 @@ TABS.receiver.initialize = function (callback) {
|
||||||
MSP.send_message(MSP_codes.MSP_SET_RC_TUNING, MSP.crunch(MSP_codes.MSP_SET_RC_TUNING), false, save_rc_map);
|
MSP.send_message(MSP_codes.MSP_SET_RC_TUNING, MSP.crunch(MSP_codes.MSP_SET_RC_TUNING), false, save_rc_map);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$("a.sticks").click(function() {
|
||||||
|
var
|
||||||
|
windowWidth = 370,
|
||||||
|
windowHeight = 510;
|
||||||
|
|
||||||
|
chrome.app.window.create("/tabs/receiver_msp.html", {
|
||||||
|
id: "receiver_msp",
|
||||||
|
innerBounds: {
|
||||||
|
minWidth: windowWidth, minHeight: windowHeight,
|
||||||
|
width: windowWidth, height: windowHeight,
|
||||||
|
maxWidth: windowWidth, maxHeight: windowHeight
|
||||||
|
},
|
||||||
|
alwaysOnTop: true
|
||||||
|
}, function(createdWindow) {
|
||||||
|
// Give the window a callback it can use to send the channels (otherwise it can't see those objects)
|
||||||
|
createdWindow.contentWindow.setRawRx = function(channels) {
|
||||||
|
if (CONFIGURATOR.connectionValid && GUI.active_tab != 'cli') {
|
||||||
|
MSP.setRawRx(channels);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Only show the MSP control sticks if the MSP Rx feature is enabled
|
||||||
|
$("a.sticks").toggle(bit_check(BF_CONFIG.features, 14 /* RX_MSP */));
|
||||||
|
|
||||||
$('select[name="rx_refresh_rate"]').change(function () {
|
$('select[name="rx_refresh_rate"]').change(function () {
|
||||||
var plot_update_rate = parseInt($(this).val(), 10);
|
var plot_update_rate = parseInt($(this).val(), 10);
|
||||||
|
|
||||||
|
|
109
tabs/receiver_msp.css
Normal file
109
tabs/receiver_msp.css
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
body {
|
||||||
|
font-family: 'Segoe UI', Tahoma, sans-serif;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #303030;
|
||||||
|
margin: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.control-gimbals {
|
||||||
|
/* A generous padding around the window edges ensures that we continue to receive mousemove events (since
|
||||||
|
* cursor stays in the window for longer)
|
||||||
|
*/
|
||||||
|
padding:25px;
|
||||||
|
padding-bottom:0;
|
||||||
|
text-align:center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.control-gimbal {
|
||||||
|
position:relative;
|
||||||
|
width:120px;
|
||||||
|
height:120px;
|
||||||
|
background-color:#eee;
|
||||||
|
margin-left:1em;
|
||||||
|
margin-right:1em;
|
||||||
|
margin-bottom:2em;
|
||||||
|
display:inline-block;
|
||||||
|
border-radius:5px;
|
||||||
|
|
||||||
|
cursor:pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.crosshair {
|
||||||
|
display:block;
|
||||||
|
position:absolute;
|
||||||
|
background-color:#ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.crosshair-vert {
|
||||||
|
width:1px;
|
||||||
|
height:100%;
|
||||||
|
left:50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.crosshair-horz {
|
||||||
|
height:1px;
|
||||||
|
width:100%;
|
||||||
|
top:50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gimbal-label {
|
||||||
|
display:block;
|
||||||
|
position:absolute;
|
||||||
|
text-align:center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gimbal-label-horz {
|
||||||
|
top:calc(100% + 0.5em);
|
||||||
|
width:100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gimbal-label-vert {
|
||||||
|
transform:rotate(-90deg);
|
||||||
|
/*transform-origin:0% 100%;*/
|
||||||
|
top:calc(50% - 0.5em);
|
||||||
|
width:100%;
|
||||||
|
left:calc(-50% - 1em);
|
||||||
|
}
|
||||||
|
|
||||||
|
.control-stick {
|
||||||
|
background-color:rgba(255,50,50,1.0);
|
||||||
|
width:20px;
|
||||||
|
height:20px;
|
||||||
|
margin-left:-10px;
|
||||||
|
margin-top:-10px;
|
||||||
|
display:block;
|
||||||
|
border-radius:100%;
|
||||||
|
position:absolute;
|
||||||
|
|
||||||
|
cursor:pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.control-slider {
|
||||||
|
margin:20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tooltip {
|
||||||
|
position: absolute;
|
||||||
|
left: calc(100% + 24px);
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.control-slider .slider {
|
||||||
|
margin-left:50px;
|
||||||
|
margin-right:50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slider-label {
|
||||||
|
position:absolute;
|
||||||
|
text-align:right;
|
||||||
|
width:40px;
|
||||||
|
left:-65px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-enable {
|
||||||
|
padding:0.5em;
|
||||||
|
font-size:110%;
|
||||||
|
margin-left:auto;
|
||||||
|
margin-right:auto;
|
||||||
|
display:block;
|
||||||
|
}
|
71
tabs/receiver_msp.html
Normal file
71
tabs/receiver_msp.html
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<script type="text/javascript" src="/js/libraries/jquery-2.1.4.min.js"></script>
|
||||||
|
<script type="text/javascript" src="/js/libraries/jquery-ui-1.11.4.min.js"></script>
|
||||||
|
<script type="text/javascript" src="/js/libraries/jquery.nouislider.all.min.js"></script>
|
||||||
|
|
||||||
|
<script type="text/javascript" src="receiver_msp.js"></script>
|
||||||
|
|
||||||
|
<link type="text/css" rel="stylesheet" href="/js/libraries/jquery.nouislider.min.css">
|
||||||
|
<link type="text/css" rel="stylesheet" href="/js/libraries/jquery.nouislider.pips.min.css">
|
||||||
|
|
||||||
|
<link type="text/css" rel="stylesheet" href="receiver_msp.css" media="all" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="control-gimbals">
|
||||||
|
<div class="control-gimbal left">
|
||||||
|
<span class="gimbal-label gimbal-label-vert"></span>
|
||||||
|
<span class="gimbal-label gimbal-label-horz"></span>
|
||||||
|
|
||||||
|
<span class="crosshair crosshair-vert"></span>
|
||||||
|
<span class="crosshair crosshair-horz"></span>
|
||||||
|
<div class="control-stick">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="control-gimbal right">
|
||||||
|
<span class="gimbal-label gimbal-label-vert"></span>
|
||||||
|
<span class="gimbal-label gimbal-label-horz"></span>
|
||||||
|
|
||||||
|
<span class="crosshair crosshair-vert"></span>
|
||||||
|
<span class="crosshair crosshair-horz"></span>
|
||||||
|
<div class="control-stick">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="control-sliders">
|
||||||
|
<div class="control-slider">
|
||||||
|
<div class="slider">
|
||||||
|
<span class="slider-label"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="control-slider">
|
||||||
|
<div class="slider">
|
||||||
|
<span class="slider-label"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="control-slider">
|
||||||
|
<div class="slider">
|
||||||
|
<span class="slider-label"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="control-slider">
|
||||||
|
<div class="slider">
|
||||||
|
<span class="slider-label"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="warning">
|
||||||
|
<p>
|
||||||
|
These sticks allow Cleanflight to be armed and tested without a transmitter or receiver being
|
||||||
|
present. However, <strong>this feature is not intended for flight and propellers must not be attached.</strong>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
This feature does not guarantee reliable control of your craft. <strong>Serious injury is likely to
|
||||||
|
result if propellers are left on.</strong>
|
||||||
|
</p>
|
||||||
|
<button class="button-enable" type="button">Enable controls</button>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
185
tabs/receiver_msp.js
Normal file
185
tabs/receiver_msp.js
Normal file
|
@ -0,0 +1,185 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var
|
||||||
|
CHANNEL_MIN_VALUE = 1000,
|
||||||
|
CHANNEL_MID_VALUE = 1500,
|
||||||
|
CHANNEL_MAX_VALUE = 2000,
|
||||||
|
|
||||||
|
// What's the index of each channel in the MSP channel list?
|
||||||
|
channelMSPIndexes = {
|
||||||
|
roll: 0,
|
||||||
|
pitch: 1,
|
||||||
|
yaw: 2,
|
||||||
|
throttle: 3,
|
||||||
|
aux1: 4,
|
||||||
|
aux2: 5,
|
||||||
|
aux3: 6,
|
||||||
|
aux4: 7,
|
||||||
|
},
|
||||||
|
|
||||||
|
// Set reasonable initial stick positions (Mode 2)
|
||||||
|
stickValues = {
|
||||||
|
throttle: CHANNEL_MIN_VALUE,
|
||||||
|
pitch: CHANNEL_MID_VALUE,
|
||||||
|
roll: CHANNEL_MID_VALUE,
|
||||||
|
yaw: CHANNEL_MID_VALUE,
|
||||||
|
aux1: CHANNEL_MIN_VALUE,
|
||||||
|
aux2: CHANNEL_MIN_VALUE,
|
||||||
|
aux3: CHANNEL_MIN_VALUE,
|
||||||
|
aux4: CHANNEL_MIN_VALUE
|
||||||
|
},
|
||||||
|
|
||||||
|
// First the vertical axis, then the horizontal:
|
||||||
|
gimbals = [
|
||||||
|
["throttle", "yaw"],
|
||||||
|
["pitch", "roll"],
|
||||||
|
],
|
||||||
|
|
||||||
|
gimbalElems,
|
||||||
|
sliderElems,
|
||||||
|
|
||||||
|
enableTX = false;
|
||||||
|
|
||||||
|
function transmitChannels() {
|
||||||
|
var
|
||||||
|
channelValues = [0, 0, 0, 0, 0, 0, 0, 0];
|
||||||
|
|
||||||
|
if (!enableTX) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var stickName in stickValues) {
|
||||||
|
channelValues[channelMSPIndexes[stickName]] = stickValues[stickName];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Callback given to us by the window creator so we can have it send data over MSP for us:
|
||||||
|
if (!window.setRawRx(channelValues)) {
|
||||||
|
// MSP connection has gone away
|
||||||
|
chrome.app.window.current().close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function stickPortionToChannelValue(portion) {
|
||||||
|
portion = Math.min(Math.max(portion, 0.0), 1.0);
|
||||||
|
|
||||||
|
return Math.round(portion * (CHANNEL_MAX_VALUE - CHANNEL_MIN_VALUE) + CHANNEL_MIN_VALUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
function channelValueToStickPortion(channel) {
|
||||||
|
return (channel - CHANNEL_MIN_VALUE) / (CHANNEL_MAX_VALUE - CHANNEL_MIN_VALUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateControlPositions() {
|
||||||
|
for (var stickName in stickValues) {
|
||||||
|
var
|
||||||
|
stickValue = stickValues[stickName];
|
||||||
|
|
||||||
|
// Look for the gimbal which corresponds to this stick name
|
||||||
|
for (var gimbalIndex in gimbals) {
|
||||||
|
var
|
||||||
|
gimbal = gimbals[gimbalIndex],
|
||||||
|
gimbalElem = gimbalElems.get(gimbalIndex),
|
||||||
|
gimbalSize = $(gimbalElem).width(),
|
||||||
|
stickElem = $(".control-stick", gimbalElem);
|
||||||
|
|
||||||
|
if (gimbal[0] == stickName) {
|
||||||
|
stickElem.css('top', (1.0 - channelValueToStickPortion(stickValue)) * gimbalSize + "px");
|
||||||
|
break;
|
||||||
|
} else if (gimbal[1] == stickName) {
|
||||||
|
stickElem.css('left', channelValueToStickPortion(stickValue) * gimbalSize + "px");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleGimbalMouseDrag(e) {
|
||||||
|
var
|
||||||
|
gimbal = $(gimbalElems.get(e.data.gimbalIndex)),
|
||||||
|
gimbalOffset = gimbal.offset(),
|
||||||
|
gimbalSize = gimbal.width();
|
||||||
|
|
||||||
|
stickValues[gimbals[e.data.gimbalIndex][0]] = stickPortionToChannelValue(1.0 - (e.pageY - gimbalOffset.top) / gimbalSize);
|
||||||
|
stickValues[gimbals[e.data.gimbalIndex][1]] = stickPortionToChannelValue((e.pageX - gimbalOffset.left) / gimbalSize);
|
||||||
|
|
||||||
|
updateControlPositions();
|
||||||
|
}
|
||||||
|
|
||||||
|
function localizeAxisNames() {
|
||||||
|
for (var gimbalIndex in gimbals) {
|
||||||
|
var
|
||||||
|
gimbal = gimbalElems.get(gimbalIndex);
|
||||||
|
|
||||||
|
$(".gimbal-label-vert", gimbal).text(chrome.i18n.getMessage("controlAxis" + gimbals[gimbalIndex][0]));
|
||||||
|
$(".gimbal-label-horz", gimbal).text(chrome.i18n.getMessage("controlAxis" + gimbals[gimbalIndex][1]));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var sliderIndex = 0; sliderIndex < 4; sliderIndex++) {
|
||||||
|
$(".slider-label", sliderElems.get(sliderIndex)).text(chrome.i18n.getMessage("controlAxisAux" + (sliderIndex + 1)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$(document).ready(function() {
|
||||||
|
$(".button-enable").click(function() {
|
||||||
|
var
|
||||||
|
shrinkHeight = $(".warning").height();
|
||||||
|
|
||||||
|
$(".warning").slideUp("short", function() {
|
||||||
|
chrome.app.window.current().innerBounds.minHeight -= shrinkHeight;
|
||||||
|
chrome.app.window.current().innerBounds.height -= shrinkHeight;
|
||||||
|
chrome.app.window.current().innerBounds.maxHeight -= shrinkHeight;
|
||||||
|
});
|
||||||
|
|
||||||
|
enableTX = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
gimbalElems = $(".control-gimbal");
|
||||||
|
sliderElems = $(".control-slider");
|
||||||
|
|
||||||
|
gimbalElems.each(function(gimbalIndex) {
|
||||||
|
$(this).on('mousedown', {gimbalIndex: gimbalIndex}, function(e) {
|
||||||
|
if (e.which == 1) { // Only move sticks on left mouse button
|
||||||
|
handleGimbalMouseDrag(e);
|
||||||
|
|
||||||
|
$(window).on('mousemove', {gimbalIndex: gimbalIndex}, handleGimbalMouseDrag);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$(".slider", sliderElems).each(function(sliderIndex) {
|
||||||
|
var
|
||||||
|
initialValue = stickValues["aux" + (sliderIndex + 1)];
|
||||||
|
|
||||||
|
$(this)
|
||||||
|
.noUiSlider({
|
||||||
|
start: initialValue,
|
||||||
|
range: {
|
||||||
|
min: CHANNEL_MIN_VALUE,
|
||||||
|
max: CHANNEL_MAX_VALUE
|
||||||
|
}
|
||||||
|
}).on('slide change set', function(e, value) {
|
||||||
|
value = Math.round(parseFloat(value));
|
||||||
|
|
||||||
|
stickValues["aux" + (sliderIndex + 1)] = value;
|
||||||
|
|
||||||
|
$(".tooltip", this).text(value);
|
||||||
|
});
|
||||||
|
|
||||||
|
$(this).append('<div class="tooltip"></div>');
|
||||||
|
|
||||||
|
$(".tooltip", this).text(initialValue);
|
||||||
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Mouseup handler needs to be bound to the window in order to receive mouseup if mouse leaves window.
|
||||||
|
*/
|
||||||
|
$(window).mouseup(function(e) {
|
||||||
|
$(this).off('mousemove', handleGimbalMouseDrag);
|
||||||
|
});
|
||||||
|
|
||||||
|
localizeAxisNames();
|
||||||
|
|
||||||
|
updateControlPositions();
|
||||||
|
|
||||||
|
setInterval(transmitChannels, 50);
|
||||||
|
});
|
|
@ -15,6 +15,7 @@ TABS.sensors.initialize = function (callback) {
|
||||||
SENSOR_DATA.gyroscope[i] = 0;
|
SENSOR_DATA.gyroscope[i] = 0;
|
||||||
SENSOR_DATA.magnetometer[i] = 0;
|
SENSOR_DATA.magnetometer[i] = 0;
|
||||||
SENSOR_DATA.sonar = 0;
|
SENSOR_DATA.sonar = 0;
|
||||||
|
SENSOR_DATA.altitude = 0;
|
||||||
SENSOR_DATA.debug[i] = 0;
|
SENSOR_DATA.debug[i] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,10 +3,6 @@
|
||||||
.tab-servos input[type="number"]::-webkit-inner-spin-button {
|
.tab-servos input[type="number"]::-webkit-inner-spin-button {
|
||||||
border: 0;
|
border: 0;
|
||||||
}
|
}
|
||||||
.tab-servos .supported_wrapper,
|
|
||||||
.tab-servos .direction_wrapper {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.tab-servos .title {
|
.tab-servos .title {
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
|
|
||||||
|
@ -130,3 +126,16 @@
|
||||||
.tab-servos .update:hover {
|
.tab-servos .update:hover {
|
||||||
background-color: #dedcdc;
|
background-color: #dedcdc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tab-servos .require-support {
|
||||||
|
display:none;
|
||||||
|
}
|
||||||
|
.tab-servos.supported .require-support {
|
||||||
|
display:block;
|
||||||
|
}
|
||||||
|
.tab-servos .require-upgrade {
|
||||||
|
display:block;
|
||||||
|
}
|
||||||
|
.tab-servos.supported .require-upgrade {
|
||||||
|
display:none;
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
<div class="tab-servos">
|
<div class="tab-servos">
|
||||||
<span i18n="servosModel"></span> <strong class="model"></strong>
|
<div class="require-support">
|
||||||
<div class="supported_wrapper">
|
|
||||||
<div class="title" i18n="servosChangeDirection"></div>
|
<div class="title" i18n="servosChangeDirection"></div>
|
||||||
<table class="fields">
|
<table class="fields">
|
||||||
<tr class="main">
|
<tr class="main">
|
||||||
|
@ -8,21 +7,14 @@
|
||||||
<th style="width: 120px" i18n="servosMid"></th>
|
<th style="width: 120px" i18n="servosMid"></th>
|
||||||
<th style="width: 120px" i18n="servosMin"></th>
|
<th style="width: 120px" i18n="servosMin"></th>
|
||||||
<th style="width: 120px" i18n="servosMax"></th>
|
<th style="width: 120px" i18n="servosMax"></th>
|
||||||
|
<th style="width: 120px" i18n="servosAngleAtMin"></th>
|
||||||
|
<th style="width: 120px" i18n="servosAngleAtMax"></th>
|
||||||
<th style="width: 40px">CH1</th>
|
<th style="width: 40px">CH1</th>
|
||||||
<th style="width: 40px">CH2</th>
|
<th style="width: 40px">CH2</th>
|
||||||
<th style="width: 40px">CH3</th>
|
<th style="width: 40px">CH3</th>
|
||||||
<th style="width: 40px">CH4</th>
|
<th style="width: 40px">CH4</th>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
<div class="direction_wrapper">
|
|
||||||
<div class="title" style="width: 258px" i18n="servosGyroAccelDirection"></div>
|
|
||||||
<table class="directions" style="width: 260px">
|
|
||||||
<tr class="main">
|
|
||||||
<th style="width: 200px" i18n="servosName"></th>
|
|
||||||
<th i18n="servosDirection"></th>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<div class="live">
|
<div class="live">
|
||||||
<span i18n="servosLiveMode"></span> <input type="checkbox" />
|
<span i18n="servosLiveMode"></span> <input type="checkbox" />
|
||||||
</div>
|
</div>
|
||||||
|
@ -30,4 +22,7 @@
|
||||||
<a class="update" href="#" i18n="servosButtonSave"></a>
|
<a class="update" href="#" i18n="servosButtonSave"></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="note require-upgrade" i18n="servosFirmwareUpgradeRequired">
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
238
tabs/servos.js
238
tabs/servos.js
|
@ -1,9 +1,3 @@
|
||||||
/* Please don't take code in this file very seriously !!!
|
|
||||||
|
|
||||||
I was "kinda" forced to write this implementation "this way" because the Servo code implementation
|
|
||||||
from multiwii is so horrible, obstructive and non dynamic, not to mention it doesn't make any sense
|
|
||||||
that there was just no other way around this then hardcoding/implementing each model separately.
|
|
||||||
*/
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
TABS.servos = {};
|
TABS.servos = {};
|
||||||
|
@ -15,12 +9,22 @@ TABS.servos.initialize = function (callback) {
|
||||||
googleAnalytics.sendAppView('Servos');
|
googleAnalytics.sendAppView('Servos');
|
||||||
}
|
}
|
||||||
|
|
||||||
function get_servo_conf_data() {
|
function get_servo_configurations() {
|
||||||
MSP.send_message(MSP_codes.MSP_SERVO_CONF, false, false, get_channel_forwarding_data);
|
MSP.send_message(MSP_codes.MSP_SERVO_CONFIGURATIONS, false, false, get_servo_mix_rules);
|
||||||
}
|
}
|
||||||
|
|
||||||
function get_channel_forwarding_data() {
|
function get_servo_mix_rules() {
|
||||||
MSP.send_message(MSP_codes.MSP_CHANNEL_FORWARDING, false, false, get_rc_data);
|
MSP.send_message(MSP_codes.MSP_SERVO_MIX_RULES, false, false, get_channel_forwarding);
|
||||||
|
}
|
||||||
|
|
||||||
|
function get_channel_forwarding() {
|
||||||
|
var nextFunction = get_rc_data;
|
||||||
|
|
||||||
|
if (semver.lt(CONFIG.apiVersion, "1.12.0")) {
|
||||||
|
MSP.send_message(MSP_codes.MSP_CHANNEL_FORWARDING, false, false, nextFunction);
|
||||||
|
} else {
|
||||||
|
nextFunction();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function get_rc_data() {
|
function get_rc_data() {
|
||||||
|
@ -35,9 +39,17 @@ TABS.servos.initialize = function (callback) {
|
||||||
$('#content').load("./tabs/servos.html", process_html);
|
$('#content').load("./tabs/servos.html", process_html);
|
||||||
}
|
}
|
||||||
|
|
||||||
MSP.send_message(MSP_codes.MSP_IDENT, false, false, get_servo_conf_data);
|
MSP.send_message(MSP_codes.MSP_IDENT, false, false, get_servo_configurations);
|
||||||
|
|
||||||
function process_html() {
|
function update_ui() {
|
||||||
|
|
||||||
|
if (semver.lt(CONFIG.apiVersion, "1.12.0")) {
|
||||||
|
|
||||||
|
$(".tab-servos").removeClass("supported");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$(".tab-servos").addClass("supported");
|
||||||
|
|
||||||
var servoCheckbox = '';
|
var servoCheckbox = '';
|
||||||
var servoHeader = '';
|
var servoHeader = '';
|
||||||
|
@ -46,7 +58,7 @@ TABS.servos.initialize = function (callback) {
|
||||||
<th >A' + (i+1) + '</th>\
|
<th >A' + (i+1) + '</th>\
|
||||||
';
|
';
|
||||||
}
|
}
|
||||||
servoHeader = servoHeader + '<th style="width: 200px" i18n="servosDirection"></th>';
|
servoHeader = servoHeader + '<th style="width: 200px" i18n="servosDirectionAndRate"></th>';
|
||||||
|
|
||||||
for (var i = 0; i < RC.active_channels; i++) {
|
for (var i = 0; i < RC.active_channels; i++) {
|
||||||
servoCheckbox = servoCheckbox + '\
|
servoCheckbox = servoCheckbox + '\
|
||||||
|
@ -54,67 +66,29 @@ TABS.servos.initialize = function (callback) {
|
||||||
';
|
';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$('div.tab-servos table.fields tr.main').append(servoHeader);
|
$('div.tab-servos table.fields tr.main').append(servoHeader);
|
||||||
|
|
||||||
function process_directions(name, obj, bitpos) {
|
function process_servos(name, alternate, obj) {
|
||||||
$('div.direction_wrapper').show();
|
|
||||||
|
|
||||||
var val;
|
|
||||||
|
|
||||||
$('div.tab-servos table.directions').append('\
|
|
||||||
<tr>\
|
|
||||||
<td class="name" style="text-align: center">' + name + '</td>\
|
|
||||||
<td class="direction" style="text-align: right">\
|
|
||||||
<select name="direction">\
|
|
||||||
<option value="0">' + chrome.i18n.getMessage('servosNormal') + '</option>\
|
|
||||||
<option value="1">' + chrome.i18n.getMessage('servosReverse') + '</option>\
|
|
||||||
</select>\
|
|
||||||
</td>\
|
|
||||||
</tr>\
|
|
||||||
');
|
|
||||||
|
|
||||||
if (bit_check(SERVO_CONFIG[obj].rate, bitpos)) val = 1;
|
|
||||||
else val = 0;
|
|
||||||
|
|
||||||
$('div.tab-servos table.directions tr:last select').val(val);
|
|
||||||
$('div.tab-servos table.directions tr:last select').data('info', {'obj': obj, 'bitpos': bitpos});
|
|
||||||
}
|
|
||||||
|
|
||||||
function process_servos(name, alternate, obj, directions) {
|
|
||||||
|
|
||||||
$('div.supported_wrapper').show();
|
$('div.supported_wrapper').show();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$('div.tab-servos table.fields').append('\
|
$('div.tab-servos table.fields').append('\
|
||||||
<tr> \
|
<tr> \
|
||||||
<td style="text-align: center">' + name + '</td>\
|
<td style="text-align: center">' + name + '</td>\
|
||||||
<td class="middle"><input type="number" min="1000" max="2000" value="' + SERVO_CONFIG[obj].middle + '" /></td>\
|
<td class="middle"><input type="number" min="500" max="2500" value="' + SERVO_CONFIG[obj].middle + '" /></td>\
|
||||||
<td class="min"><input type="number" min="1000" max="2000" value="' + SERVO_CONFIG[obj].min +'" /></td>\
|
<td class="min"><input type="number" min="500" max="2500" value="' + SERVO_CONFIG[obj].min +'" /></td>\
|
||||||
<td class="max"><input type="number" min="1000" max="2000" value="' + SERVO_CONFIG[obj].max +'" /></td>\
|
<td class="max"><input type="number" min="500" max="2500" value="' + SERVO_CONFIG[obj].max +'" /></td>\
|
||||||
|
<td class="angleAtMin"><input type="number" min="-90" max="0" value="' + SERVO_CONFIG[obj].angleAtMin +'" /></td>\
|
||||||
|
<td class="angleAtMax"><input type="number" min="0" max="90" value="' + SERVO_CONFIG[obj].angleAtMax +'" /></td>\
|
||||||
' + servoCheckbox + '\
|
' + servoCheckbox + '\
|
||||||
<td class="direction">\
|
<td class="direction">\
|
||||||
<input class="first" type="checkbox"/><span class="name">' + name + '</span>\
|
|
||||||
<input class="second" type="checkbox"/><span class="alternate">' + alternate + '</span>\
|
|
||||||
</td>\
|
</td>\
|
||||||
</tr> \
|
</tr> \
|
||||||
');
|
');
|
||||||
|
|
||||||
|
if (SERVO_CONFIG[obj].indexOfChannelToForward >= 0) {
|
||||||
|
|
||||||
// translate to user-selected language
|
|
||||||
localize();
|
|
||||||
|
|
||||||
$('div.tab-servos table.fields tr:last td.channel input').eq(SERVO_CONFIG[obj].indexOfChannelToForward).prop('checked', true);
|
$('div.tab-servos table.fields tr:last td.channel input').eq(SERVO_CONFIG[obj].indexOfChannelToForward).prop('checked', true);
|
||||||
|
}
|
||||||
if (directions == true) {
|
|
||||||
$('div.tab-servos table.fields tr:last td.direction input:first').prop('checked', bit_check(SERVO_CONFIG[obj].rate, 0));
|
|
||||||
$('div.tab-servos table.fields tr:last td.direction input:last').prop('checked', bit_check(SERVO_CONFIG[obj].rate, 1));
|
|
||||||
} else if (directions == 2) {
|
|
||||||
// removing checkboxes
|
|
||||||
$('div.tab-servos table.fields tr:last td.direction').html('');
|
|
||||||
|
|
||||||
// adding select box and generating options
|
// adding select box and generating options
|
||||||
$('div.tab-servos table.fields tr:last td.direction').append('\
|
$('div.tab-servos table.fields tr:last td.direction').append('\
|
||||||
|
@ -129,10 +103,6 @@ TABS.servos.initialize = function (callback) {
|
||||||
|
|
||||||
// select current rate
|
// select current rate
|
||||||
select.val(SERVO_CONFIG[obj].rate);
|
select.val(SERVO_CONFIG[obj].rate);
|
||||||
} else {
|
|
||||||
// removing checkboxes
|
|
||||||
$('div.tab-servos table.fields tr:last td.direction').html('');
|
|
||||||
}
|
|
||||||
|
|
||||||
$('div.tab-servos table.fields tr:last').data('info', {'obj': obj});
|
$('div.tab-servos table.fields tr:last').data('info', {'obj': obj});
|
||||||
|
|
||||||
|
@ -146,18 +116,7 @@ TABS.servos.initialize = function (callback) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function servos_update(save_to_eeprom) {
|
function servos_update(save_configuration_to_eeprom) {
|
||||||
// update bitfields
|
|
||||||
$('div.tab-servos table.directions tr:not(".main")').each(function () {
|
|
||||||
var info = $('select', this).data('info');
|
|
||||||
var val = parseInt($('select', this).val());
|
|
||||||
|
|
||||||
// in this stage we need to know which bitfield and which bitposition needs to be flipped
|
|
||||||
if (val) SERVO_CONFIG[info.obj].rate = bit_set(SERVO_CONFIG[info.obj].rate, info.bitpos);
|
|
||||||
else SERVO_CONFIG[info.obj].rate = bit_clear(SERVO_CONFIG[info.obj].rate, info.bitpos);
|
|
||||||
});
|
|
||||||
|
|
||||||
// update the rest
|
|
||||||
$('div.tab-servos table.fields tr:not(".main")').each(function () {
|
$('div.tab-servos table.fields tr:not(".main")').each(function () {
|
||||||
var info = $(this).data('info');
|
var info = $(this).data('info');
|
||||||
|
|
||||||
|
@ -174,122 +133,37 @@ TABS.servos.initialize = function (callback) {
|
||||||
SERVO_CONFIG[info.obj].middle = parseInt($('.middle input', this).val());
|
SERVO_CONFIG[info.obj].middle = parseInt($('.middle input', this).val());
|
||||||
SERVO_CONFIG[info.obj].min = parseInt($('.min input', this).val());
|
SERVO_CONFIG[info.obj].min = parseInt($('.min input', this).val());
|
||||||
SERVO_CONFIG[info.obj].max = parseInt($('.max input', this).val());
|
SERVO_CONFIG[info.obj].max = parseInt($('.max input', this).val());
|
||||||
|
SERVO_CONFIG[info.obj].angleAtMin = parseInt($('.angleAtMin input', this).val());
|
||||||
|
SERVO_CONFIG[info.obj].angleAtMax = parseInt($('.angleAtMax input', this).val());
|
||||||
|
|
||||||
// update rate if direction fields exist
|
|
||||||
if ($('.direction input', this).length) {
|
|
||||||
if ($('.direction input:first', this).is(':checked')) SERVO_CONFIG[info.obj].rate = bit_set(SERVO_CONFIG[info.obj].rate, 0);
|
|
||||||
else SERVO_CONFIG[info.obj].rate = bit_clear(SERVO_CONFIG[info.obj].rate, 0);
|
|
||||||
|
|
||||||
if ($('.direction input:last', this).is(':checked')) SERVO_CONFIG[info.obj].rate = bit_set(SERVO_CONFIG[info.obj].rate, 1);
|
|
||||||
else SERVO_CONFIG[info.obj].rate = bit_clear(SERVO_CONFIG[info.obj].rate, 1);
|
|
||||||
} else if ($('.direction select', this).length) {
|
|
||||||
var val = parseInt($('.direction select', this).val());
|
var val = parseInt($('.direction select', this).val());
|
||||||
SERVO_CONFIG[info.obj].rate = val;
|
SERVO_CONFIG[info.obj].rate = val;
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
MSP.send_message(MSP_codes.MSP_SET_CHANNEL_FORWARDING, MSP.crunch(MSP_codes.MSP_SET_CHANNEL_FORWARDING), false, function () {
|
//
|
||||||
MSP.send_message(MSP_codes.MSP_SET_SERVO_CONF, MSP.crunch(MSP_codes.MSP_SET_SERVO_CONF), false, function () {
|
// send data to FC
|
||||||
if (save_to_eeprom) {
|
//
|
||||||
// Save changes to EEPROM
|
MSP.sendServoConfigurations(send_servo_mixer_rules);
|
||||||
|
|
||||||
|
function send_servo_mixer_rules() {
|
||||||
|
MSP.sendServoConfigurations(save_to_eeprom);
|
||||||
|
}
|
||||||
|
|
||||||
|
function save_to_eeprom() {
|
||||||
|
if (save_configuration_to_eeprom) {
|
||||||
MSP.send_message(MSP_codes.MSP_EEPROM_WRITE, false, false, function () {
|
MSP.send_message(MSP_codes.MSP_EEPROM_WRITE, false, false, function () {
|
||||||
GUI.log(chrome.i18n.getMessage('servosEepromSave'));
|
GUI.log(chrome.i18n.getMessage('servosEepromSave'));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
});
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// drop previous table
|
// drop previous table
|
||||||
$('div.tab-servos table.fields tr:not(:first)').remove();
|
$('div.tab-servos table.fields tr:not(:first)').remove();
|
||||||
|
|
||||||
var model = $('div.tab-servos strong.model');
|
for (var servoIndex = 0; servoIndex < 8; servoIndex++) {
|
||||||
var supported_models = [1, 4, 5, 8, 14, 20, 21];
|
process_servos('Servo ' + servoIndex, '', servoIndex, false);
|
||||||
|
|
||||||
switch (CONFIG.multiType) {
|
|
||||||
case 1: // TRI
|
|
||||||
// looking ok so far
|
|
||||||
model.text('TRI');
|
|
||||||
|
|
||||||
process_directions('YAW', 5, 0);
|
|
||||||
|
|
||||||
process_servos('Yaw Servo', '', 5, false);
|
|
||||||
break;
|
|
||||||
case 4: // BI
|
|
||||||
// looking ok so far
|
|
||||||
model.text('BI');
|
|
||||||
|
|
||||||
process_directions('L YAW', 4, 1);
|
|
||||||
process_directions('R YAW', 5, 1);
|
|
||||||
process_directions('L NICK', 4, 0);
|
|
||||||
process_directions('R NICK', 5, 0);
|
|
||||||
|
|
||||||
process_servos('Left Servo', '', 4, false);
|
|
||||||
process_servos('Right Servo', '', 5, false);
|
|
||||||
break;
|
|
||||||
case 5: // Gimbal
|
|
||||||
// needs to be verified
|
|
||||||
model.text('Gimbal');
|
|
||||||
|
|
||||||
// rate
|
|
||||||
process_servos('Pitch Servo', '', 0, 2);
|
|
||||||
process_servos('Roll Servo', '', 1, 2);
|
|
||||||
break;
|
|
||||||
case 8: // Flying Wing
|
|
||||||
// looking ok so far
|
|
||||||
model.text('Flying Wing');
|
|
||||||
|
|
||||||
process_directions('L ROLL', 3, 1);
|
|
||||||
process_directions('R ROLL', 4, 1);
|
|
||||||
process_directions('L NICK', 3, 0);
|
|
||||||
process_directions('R NICK', 4, 0);
|
|
||||||
|
|
||||||
process_servos('Left Wing', '', 3, false);
|
|
||||||
process_servos('Right Wing', '', 4, false);
|
|
||||||
break;
|
|
||||||
case 14: // Airplane
|
|
||||||
model.text('Airplane');
|
|
||||||
|
|
||||||
// rate
|
|
||||||
process_servos('Wing 1', '', 3, 2);
|
|
||||||
process_servos('Wing 2', '', 4, 2);
|
|
||||||
process_servos('Rudd', '', 5, 2);
|
|
||||||
process_servos('Elev', '', 6, 2);
|
|
||||||
break;
|
|
||||||
case 20: // Dualcopter
|
|
||||||
// looking ok so far
|
|
||||||
model.text('Dualcopter');
|
|
||||||
|
|
||||||
process_directions('PITCH', 4, 0);
|
|
||||||
process_directions('ROLL', 5, 0);
|
|
||||||
|
|
||||||
process_servos('Roll', '', 5, false);
|
|
||||||
process_servos('Nick', '', 4, false);
|
|
||||||
break;
|
|
||||||
case 21: // Singlecopter
|
|
||||||
// looking ok so far
|
|
||||||
model.text('Singlecopter');
|
|
||||||
|
|
||||||
process_servos('Right', 'R YAW', 3, true);
|
|
||||||
process_servos('Left', 'L YAW', 4, true);
|
|
||||||
process_servos('Front', 'F YAW', 5, true);
|
|
||||||
process_servos('Rear', 'YAW', 6, true);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
model.text(chrome.i18n.getMessage('servosModelNoSupport'));
|
|
||||||
|
|
||||||
// implementation of feature servo_tilt
|
|
||||||
if (AUX_CONFIG.indexOf('CAMSTAB') > -1 || AUX_CONFIG.indexOf('CAMTRIG') > -1) {
|
|
||||||
// Gimbal on
|
|
||||||
// needs to be verified
|
|
||||||
model.text('Gimbal / Tilt Servos');
|
|
||||||
|
|
||||||
// rate
|
|
||||||
process_servos('Pitch Servo', '', 0, 2);
|
|
||||||
process_servos('Roll Servo', '', 1, 2);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// UI hooks for dynamically generated elements
|
// UI hooks for dynamically generated elements
|
||||||
|
@ -301,12 +175,18 @@ TABS.servos.initialize = function (callback) {
|
||||||
});
|
});
|
||||||
|
|
||||||
$('a.update').click(function () {
|
$('a.update').click(function () {
|
||||||
// standard check for supported_models + custom implementation for feature servo_tilt
|
|
||||||
if (supported_models.indexOf(CONFIG.multiType) != -1 || AUX_CONFIG.indexOf('CAMSTAB') > -1 || AUX_CONFIG.indexOf('CAMTRIG') > -1) {
|
|
||||||
servos_update(true);
|
servos_update(true);
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function process_html() {
|
||||||
|
|
||||||
|
update_ui();
|
||||||
|
|
||||||
|
// translate to user-selected language
|
||||||
|
localize();
|
||||||
|
|
||||||
// status data pulled via separate timer with static speed
|
// status data pulled via separate timer with static speed
|
||||||
GUI.interval_add('status_pull', function () {
|
GUI.interval_add('status_pull', function () {
|
||||||
MSP.send_message(MSP_codes.MSP_STATUS);
|
MSP.send_message(MSP_codes.MSP_STATUS);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue