mirror of
https://github.com/betaflight/betaflight-configurator.git
synced 2025-07-19 14:25:14 +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"
|
||||
},
|
||||
"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": {
|
||||
"message": "Contributing"
|
||||
|
@ -253,7 +253,7 @@
|
|||
"message": "Calibrate Accelerometer"
|
||||
},
|
||||
"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": {
|
||||
"message": "Calibrate Magnetometer"
|
||||
|
@ -372,8 +372,8 @@
|
|||
"initialSetupModel": {
|
||||
"message": "Model: $1"
|
||||
},
|
||||
"initialSetupHeading": {
|
||||
"message": "Heading: $1 deg"
|
||||
"initialSetupAttitude": {
|
||||
"message": "$1 deg"
|
||||
},
|
||||
"initialSetupAccelCalibStarted": {
|
||||
"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."
|
||||
},
|
||||
|
||||
"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": {
|
||||
"message": "Board Alignment"
|
||||
},
|
||||
|
@ -478,9 +482,6 @@
|
|||
"configurationBatteryMinimum": {
|
||||
"message": "Minimum Cell Voltage"
|
||||
},
|
||||
"configurationBatteryWarning": {
|
||||
"message": "Warning Cell Voltage"
|
||||
},
|
||||
"configurationBatteryMaximum": {
|
||||
"message": "Maximum Cell Voltage"
|
||||
},
|
||||
|
@ -502,6 +503,18 @@
|
|||
"configurationBatteryMultiwiiCurrent": {
|
||||
"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": {
|
||||
"message": "GPS"
|
||||
},
|
||||
|
@ -514,6 +527,10 @@
|
|||
"configurationGPSubxSbas": {
|
||||
"message": "Ground Assistance Type"
|
||||
},
|
||||
"configurationGPSHelp": {
|
||||
"message": "<strong>Note:</strong> Remember to configure a Serial Port (via Ports tab) when using GPS feature."
|
||||
},
|
||||
|
||||
"configurationSerialRX": {
|
||||
"message": "Serial Receiver Provider"
|
||||
},
|
||||
|
@ -525,7 +542,10 @@
|
|||
},
|
||||
|
||||
"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": {
|
||||
"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>"
|
||||
},
|
||||
|
||||
"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": {
|
||||
"message": "Throttle MID"
|
||||
},
|
||||
|
@ -649,6 +672,9 @@
|
|||
"receiverButtonRefresh": {
|
||||
"message": "Refresh"
|
||||
},
|
||||
"receiverButtonSticks": {
|
||||
"message": "Control sticks"
|
||||
},
|
||||
"receiverDataRefreshed": {
|
||||
"message": "RC Tuning data <strong>refreshed</strong>"
|
||||
},
|
||||
|
@ -794,15 +820,13 @@
|
|||
},
|
||||
|
||||
|
||||
"servosModel": {
|
||||
"message": "Model:"
|
||||
"servosFirmwareUpgradeRequired": {
|
||||
"message": "Servos requires firmware >= 1.10.0."
|
||||
},
|
||||
|
||||
"servosChangeDirection": {
|
||||
"message": "Change Direction in TX To Match"
|
||||
},
|
||||
"servosGyroAccelDirection": {
|
||||
"message": "Gyroscope / Accelerometer Direction"
|
||||
},
|
||||
"servosName": {
|
||||
"message": "Name"
|
||||
},
|
||||
|
@ -815,8 +839,14 @@
|
|||
"servosMax": {
|
||||
"message": "MAX"
|
||||
},
|
||||
"servosDirection": {
|
||||
"message": "Direction"
|
||||
"servosAngleAtMin": {
|
||||
"message": "Angle at min"
|
||||
},
|
||||
"servosAngleAtMax": {
|
||||
"message": "Angle at max"
|
||||
},
|
||||
"servosDirectionAndRate": {
|
||||
"message": "Direction and rate"
|
||||
},
|
||||
"servosLiveMode": {
|
||||
"message": "Enable Live mode:"
|
||||
|
@ -824,9 +854,6 @@
|
|||
"servosButtonSave": {
|
||||
"message": "Save"
|
||||
},
|
||||
"servosModelNoSupport": {
|
||||
"message": "This model doesn't support servos"
|
||||
},
|
||||
"servosNormal": {
|
||||
"message": "Normal"
|
||||
},
|
||||
|
@ -1045,7 +1072,7 @@
|
|||
"message": "Attempt to flash the board automatically (triggered by newly detected serial port)"
|
||||
},
|
||||
"firmwareFlasherFullChipErase": {
|
||||
"message": "Full Chip Erase"
|
||||
"message": "Full chip erase"
|
||||
},
|
||||
"firmwareFlasherFullChipEraseDescription": {
|
||||
"message": "Wipes all configuration data currently stored on the board"
|
||||
|
@ -1057,7 +1084,7 @@
|
|||
"message": "Flash most recent (untested) development firmware"
|
||||
},
|
||||
"firmwareFlasherManualBaud": {
|
||||
"message": "Manual Baud Rate"
|
||||
"message": "Manual baud rate"
|
||||
},
|
||||
"firmwareFlasherManualBaudDescription": {
|
||||
"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"
|
||||
},
|
||||
"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": {
|
||||
"message": "Leave Firmware Flasher"
|
||||
|
@ -1128,5 +1155,41 @@
|
|||
},
|
||||
"ledStripEepromSaved": {
|
||||
"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>
|
||||
<p>
|
||||
- Support flashing of the SPRacingF3.<br />
|
||||
|
@ -23,10 +30,10 @@
|
|||
</p>
|
||||
<span>2015.03.29 - 0.63.0 - cleanflight</span>
|
||||
<p>
|
||||
- Configuration tab supports auto_disarm_delay and disarm_kill_switch - Requires 1.8.0 firmware.<br />
|
||||
- PID Tuning tab allows TPA Breakpoint changes - Requires 1.8.0 firmware.<br />
|
||||
- Corrected Artificial Horizon Pitch/Roll views.<br />
|
||||
- Changed logging time stamp to include date stamp.<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 firmware >= 1.8.0).<br />
|
||||
- Correct Artificial Horizon Pitch/Roll views.<br />
|
||||
- Change logging time stamp to include date stamp.<br />
|
||||
- Support new firmware 1.8 serial port configuration.<br />
|
||||
- Move documentation and help to new tab.<br />
|
||||
- Add contributing section to welcome tab.<br />
|
||||
|
@ -38,7 +45,7 @@
|
|||
<span>2015.02.26 - 0.62.0 - cleanflight</span>
|
||||
<p>
|
||||
- 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 />
|
||||
- Fix loading online flash files - github moved them to amazon aws.<br />
|
||||
- Fix to fallback 3D model.<br />
|
||||
|
@ -46,7 +53,7 @@
|
|||
</p>
|
||||
<span>2015.02.03 - 0.61.0 - cleanflight</span>
|
||||
<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 colors.<br />
|
||||
- Support for displaying sonar sensor reading on the sensors tab.<br />
|
||||
|
@ -54,21 +61,21 @@
|
|||
- New Logo. (Tom McCullough)<br />
|
||||
- New 3D models (AkFreak).<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 />
|
||||
- Fix for disappearing tabs in chrome 41 beta.<br />
|
||||
- Various other minor improvements.<br />
|
||||
</p>
|
||||
<span>2015.01.08 - 0.60.0 - cleanflight</span>
|
||||
<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 />
|
||||
</p>
|
||||
<span>2015.01.08 - 0.59.1 - cleanflight</span>
|
||||
<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 />
|
||||
- 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 />
|
||||
- Support 'release candidate' and 'stable' releases.
|
||||
</p>
|
||||
|
@ -88,7 +95,7 @@
|
|||
<span>2014.12.06 - 0.57.1 - cleanflight</span>
|
||||
<p>
|
||||
- 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 Armattan Quads as a sponsor.<br />
|
||||
- Various UI tweaks.<br />
|
||||
|
@ -96,17 +103,17 @@
|
|||
<span>2014.12.06 - 0.57</span>
|
||||
<p>
|
||||
- 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 />
|
||||
- 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 />
|
||||
- Bugfix for GPS distance to home not displaying<br />
|
||||
- Bugfix for backup/restore misbehaving (mostly on OSX)<br />
|
||||
</p>
|
||||
<span>2014.11.04 - 0.56</span>
|
||||
<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 fetching development firmware<br />
|
||||
</p>
|
||||
|
@ -116,9 +123,9 @@
|
|||
- Minimum accepted firmware version set to 2.31<br />
|
||||
- Support for flashing development firmware<br />
|
||||
- Setup tab performance improvements, faster 3D model<br />
|
||||
- Strongly improved amount of data stored in backups<br />
|
||||
- Improved flash on connect in firmware flasher<br />
|
||||
- Rearranged texts and options in firmware flasher<br />
|
||||
- Strongly improve amount of data stored in backups<br />
|
||||
- Improve flash on connect in firmware flasher<br />
|
||||
- Rearrange texts and options in firmware flasher<br />
|
||||
- Bugfix for corrupted minimum window size on Windows 7<br />
|
||||
- Bugfix for incorrect date & time in firmware flasher<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_RC_TUNING,
|
||||
MSP_codes.MSP_ACC_TRIM,
|
||||
MSP_codes.MSP_SERVO_CONF,
|
||||
MSP_codes.MSP_CHANNEL_FORWARDING,
|
||||
MSP_codes.MSP_SERVO_CONFIGURATIONS,
|
||||
MSP_codes.MSP_MODE_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() {
|
||||
var fetchingProfile = 0,
|
||||
codeKey = 0;
|
||||
|
@ -54,6 +63,7 @@ function configuration_backup(callback) {
|
|||
'RC': jQuery.extend(true, {}, RC_tuning),
|
||||
'AccTrim': jQuery.extend(true, [], CONFIG.accelerometerTrims),
|
||||
'ServoConfig': jQuery.extend(true, [], SERVO_CONFIG),
|
||||
'ServoRules': jQuery.extend(true, [], SERVO_RULES),
|
||||
'ModeRanges': jQuery.extend(true, [], MODE_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) {
|
||||
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,
|
||||
MSP_codes.MSP_SET_RC_TUNING,
|
||||
MSP_codes.MSP_SET_ACC_TRIM,
|
||||
MSP_codes.MSP_SET_SERVO_CONF,
|
||||
MSP_codes.MSP_SET_CHANNEL_FORWARDING
|
||||
MSP_codes.MSP_SET_ACC_TRIM
|
||||
];
|
||||
|
||||
MSP.send_message(MSP_codes.MSP_STATUS, false, false, function () {
|
||||
|
@ -472,6 +512,7 @@ function configuration_restore(callback) {
|
|||
RC_tuning = configuration.profiles[profile].RC;
|
||||
CONFIG.accelerometerTrims = configuration.profiles[profile].AccTrim;
|
||||
SERVO_CONFIG = configuration.profiles[profile].ServoConfig;
|
||||
SERVO_RULES = configuration.profiles[profile].ServoRules;
|
||||
MODE_RANGES = configuration.profiles[profile].ModeRanges;
|
||||
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() {
|
||||
MSP.sendModeRanges(upload_adjustment_ranges);
|
||||
}
|
||||
|
@ -510,7 +559,7 @@ function configuration_restore(callback) {
|
|||
}
|
||||
// start uploading
|
||||
load_objects(0);
|
||||
upload_mode_ranges();
|
||||
upload_servo_configuration();
|
||||
}
|
||||
|
||||
function upload_unique_data() {
|
||||
|
|
37
js/boards.js
37
js/boards.js
|
@ -3,58 +3,43 @@
|
|||
var BOARD_DEFINITIONS = [
|
||||
{
|
||||
name: "CC3D",
|
||||
identifier: "CC3D",
|
||||
vcp: true
|
||||
identifier: "CC3D"
|
||||
}, {
|
||||
name: "ChebuzzF3",
|
||||
identifier: "CHF3",
|
||||
vcp: false
|
||||
identifier: "CHF3"
|
||||
}, {
|
||||
name: "CJMCU",
|
||||
identifier: "CJM1",
|
||||
vcp: false
|
||||
identifier: "CJM1"
|
||||
}, {
|
||||
name: "EUSTM32F103RB",
|
||||
identifier: "EUF1",
|
||||
vcp: false
|
||||
identifier: "EUF1"
|
||||
}, {
|
||||
name: "Naze/Flip32+",
|
||||
identifier: "AFNA",
|
||||
vcp: false
|
||||
identifier: "AFNA"
|
||||
}, {
|
||||
name: "Naze32Pro",
|
||||
identifier: "AFF3",
|
||||
vcp: false
|
||||
identifier: "AFF3"
|
||||
}, {
|
||||
name: "Olimexino",
|
||||
identifier: "OLI1"
|
||||
}, {
|
||||
name: "Port103R",
|
||||
identifier: "103R",
|
||||
vcp: false
|
||||
identifier: "103R"
|
||||
}, {
|
||||
name: "Sparky",
|
||||
identifier: "SPKY",
|
||||
vcp: true
|
||||
identifier: "SPKY"
|
||||
}, {
|
||||
name: "STM32F3Discovery",
|
||||
identifier: "SDF3",
|
||||
vcp: true
|
||||
}, {
|
||||
name: "Colibri Race",
|
||||
identifier: "CLBR",
|
||||
vcp: true
|
||||
identifier: "SDF3"
|
||||
}, {
|
||||
name: "SP Racing F3",
|
||||
identifier: "SRF3",
|
||||
vcp: false
|
||||
identifier: "SRF3"
|
||||
}
|
||||
];
|
||||
|
||||
var DEFAULT_BOARD_DEFINITION = {
|
||||
name: "Unknown",
|
||||
identifier: "????",
|
||||
vcp: false
|
||||
identifier: "????"
|
||||
};
|
||||
|
||||
var BOARD = {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
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/
|
||||
'apiVersionAccepted': '1.2.0',
|
||||
|
@ -86,6 +86,7 @@ var MODE_RANGES = [];
|
|||
var ADJUSTMENT_RANGES = [];
|
||||
|
||||
var SERVO_CONFIG = [];
|
||||
var SERVO_RULES = [];
|
||||
|
||||
var SERIAL_CONFIG = {
|
||||
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
49
js/model.js
49
js/model.js
|
@ -2,27 +2,30 @@
|
|||
|
||||
// generate mixer
|
||||
var mixerList = [
|
||||
{name: 'Tricopter', model: 'tricopter', image: 'tri'},
|
||||
{name: 'Quad +', model: 'quad_x', image: 'quad_p'},
|
||||
{name: 'Quad X', model: 'quad_x', image: 'quad_x'},
|
||||
{name: 'Bicopter', model: 'custom', image: 'bicopter'},
|
||||
{name: 'Gimbal', model: 'custom', image: 'custom'},
|
||||
{name: 'Y6', model: 'y6', image: 'y6'},
|
||||
{name: 'Hex +', model: 'hex_plus', image: 'hex_p'},
|
||||
{name: 'Flying Wing', model: 'custom', image: 'flying_wing'},
|
||||
{name: 'Y4', model: 'y4', image: 'y4'},
|
||||
{name: 'Hex X', model: 'hex_x', image: 'hex_x'},
|
||||
{name: 'Octo X8', model: 'custom', image: 'octo_x8'},
|
||||
{name: 'Octo Flat +', model: 'custom', image: 'octo_flat_p'},
|
||||
{name: 'Octo Flat X', model: 'custom', image: 'octo_flat_x'},
|
||||
{name: 'Airplane', model: 'custom', image: 'airplane'},
|
||||
{name: 'Heli 120', model: 'custom', image: 'custom'},
|
||||
{name: 'Heli 90', model: 'custom', image: 'custom'},
|
||||
{name: 'V-tail Quad', model: 'quad_vtail', image: 'vtail_quad'},
|
||||
{name: 'Hex H', model: 'custom', image: 'custom'},
|
||||
{name: 'PPM to SERVO', model: 'custom', image: 'custom'},
|
||||
{name: 'Dualcopter', model: 'custom', image: 'custom'},
|
||||
{name: 'Singlecopter', model: 'custom', image: 'custom'},
|
||||
{name: 'A-tail Quad', model: 'quad_atail', image: 'atail_quad'},
|
||||
{name: 'Custom', model: 'custom', image: 'custom'}
|
||||
{name: 'Tricopter', model: 'tricopter', image: 'tri'},
|
||||
{name: 'Quad +', model: 'quad_x', image: 'quad_p'},
|
||||
{name: 'Quad X', model: 'quad_x', image: 'quad_x'},
|
||||
{name: 'Bicopter', model: 'custom', image: 'bicopter'},
|
||||
{name: 'Gimbal', model: 'custom', image: 'custom'},
|
||||
{name: 'Y6', model: 'y6', image: 'y6'},
|
||||
{name: 'Hex +', model: 'hex_plus', image: 'hex_p'},
|
||||
{name: 'Flying Wing', model: 'custom', image: 'flying_wing'},
|
||||
{name: 'Y4', model: 'y4', image: 'y4'},
|
||||
{name: 'Hex X', model: 'hex_x', image: 'hex_x'},
|
||||
{name: 'Octo X8', model: 'custom', image: 'octo_x8'},
|
||||
{name: 'Octo Flat +', model: 'custom', image: 'octo_flat_p'},
|
||||
{name: 'Octo Flat X', model: 'custom', image: 'octo_flat_x'},
|
||||
{name: 'Airplane', model: 'custom', image: 'airplane'},
|
||||
{name: 'Heli 120', model: 'custom', image: 'custom'},
|
||||
{name: 'Heli 90', model: 'custom', image: 'custom'},
|
||||
{name: 'V-tail Quad', model: 'quad_vtail', image: 'vtail_quad'},
|
||||
{name: 'Hex H', model: 'custom', image: 'custom'},
|
||||
{name: 'PPM to SERVO', model: 'custom', image: 'custom'},
|
||||
{name: 'Dualcopter', model: 'custom', image: 'custom'},
|
||||
{name: 'Singlecopter', model: 'custom', image: 'custom'},
|
||||
{name: 'A-tail Quad', model: 'quad_atail', image: 'atail_quad'},
|
||||
{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();
|
||||
|
||||
if ("CLFL" == CONFIG.flightControllerIdentifier){
|
||||
|
||||
/* placing this elsewhere
|
||||
var documentationButton = $('#button-documentation');
|
||||
var documentationButton = $('#button-documentation');
|
||||
documentationButton.show();
|
||||
documentationButton.html("Documentation for "+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-disconnected').show();
|
||||
|
||||
|
||||
var flashstate = $('#header_dataflash');
|
||||
flashstate.hide();
|
||||
|
||||
/* just a thought
|
||||
var sensor_state = $('#sensor-status');
|
||||
sensor_state.hide();
|
||||
*/
|
||||
var documentationButton = $('#button-documentation');
|
||||
documentationButton.hide();
|
||||
}
|
||||
|
||||
function read_serial(info) {
|
||||
|
|
|
@ -141,6 +141,13 @@ TABS.cli.read = function (readInfo) {
|
|||
text += "<br />";
|
||||
}
|
||||
break;
|
||||
case 60:
|
||||
text += '<';
|
||||
break;
|
||||
case 62:
|
||||
text += '>';
|
||||
break;
|
||||
|
||||
default:
|
||||
text += String.fromCharCode(data[i]);
|
||||
}
|
||||
|
|
|
@ -99,6 +99,13 @@
|
|||
|
||||
border: 1px solid silver;
|
||||
}
|
||||
|
||||
.tab-configuration .number input.disabled {
|
||||
width: 50px;
|
||||
padding: 0px 5px;
|
||||
background-color: #ececec;
|
||||
}
|
||||
|
||||
.tab-configuration .number span {
|
||||
margin-left: 10px;
|
||||
line-height: 20px;
|
||||
|
@ -154,7 +161,6 @@
|
|||
.tab-configuration .disarm .checkbox span {
|
||||
margin-left: 15px;
|
||||
}
|
||||
|
||||
.tab-configuration .save {
|
||||
display: block;
|
||||
float: right;
|
||||
|
|
|
@ -127,19 +127,10 @@
|
|||
<!-- list generated here -->
|
||||
</select>
|
||||
|
||||
<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 class="help">
|
||||
<p i18n="configurationSerialRXHelp"></p>
|
||||
</div>
|
||||
|
||||
<div class="groupTitle" i18n="configurationFailsafe"></div>
|
||||
<table>
|
||||
<thead>
|
||||
|
@ -159,8 +150,6 @@
|
|||
<span i18n="configurationThrottleFailsafe"></span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
<div class="rightWrapper current voltage">
|
||||
<div class="groupTitle" i18n="configurationBatteryVoltage"></div>
|
||||
|
@ -183,12 +172,6 @@
|
|||
<span i18n="configurationBatteryMinimum"></span>
|
||||
</label>
|
||||
</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">
|
||||
<label>
|
||||
<input type="number" name="maxcellvoltage" step="0.1" min="1" max="5" />
|
||||
|
@ -207,7 +190,7 @@
|
|||
<span i18n="configurationBatteryScale"></span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="groupTitle" i18n="configurationCurrent"></div>
|
||||
<div class="groupTitle" i18n="configurationCurrent"></div>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
|
@ -241,6 +224,40 @@
|
|||
</label>
|
||||
</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="leftWrapper gps">
|
||||
<div class="groupTitle" i18n="configurationGPS"></div>
|
||||
|
@ -281,6 +298,11 @@
|
|||
<span i18n="configurationMagDeclination"></span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="help">
|
||||
<p i18n="configurationGPSHelp"></p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="rightWrapper">
|
||||
<div class="groupTitle" i18n="configurationFeatures"></div>
|
||||
|
@ -297,6 +319,7 @@
|
|||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="clear-both"></div>
|
||||
<div class="buttons">
|
||||
<a class="save" href="#" i18n="configurationButtonSave"></a>
|
||||
|
|
67
tabs/configuration.js
Executable file → Normal file
67
tabs/configuration.js
Executable file → Normal file
|
@ -36,7 +36,11 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
|
|||
}
|
||||
|
||||
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() {
|
||||
|
@ -45,6 +49,17 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
|
|||
|
||||
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() {
|
||||
// translate to user-selected language
|
||||
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: 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: 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: 8, group: 'rxFailsafe', name: 'FAILSAFE', description: 'Failsafe settings on RX signal loss'},
|
||||
{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'}
|
||||
];
|
||||
|
||||
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 features_e = $('.features');
|
||||
|
@ -256,7 +277,7 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
|
|||
// fill magnetometer
|
||||
$('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")) {
|
||||
$('input[name="autodisarmdelay"]').val(ARMING_CONFIG.auto_disarm_delay);
|
||||
$('input[name="disarmkillswitch"]').prop('checked', ARMING_CONFIG.disarm_kill_switch);
|
||||
|
@ -265,6 +286,13 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
|
|||
$('div.disarmdelay').show();
|
||||
else
|
||||
$('div.disarmdelay').hide();
|
||||
|
||||
// fill FC loop time
|
||||
$('input[name="looptime"]').val(FC_CONFIG.loopTime);
|
||||
|
||||
recalculate_cycles_sec();
|
||||
|
||||
$('div.cycles').show();
|
||||
}
|
||||
|
||||
// fill throttle
|
||||
|
@ -276,7 +304,6 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
|
|||
|
||||
// fill battery
|
||||
$('input[name="mincellvoltage"]').val(MISC.vbatmincellvoltage);
|
||||
$('input[name="warningcellvoltage"]').val(MISC.vbatwarningcellvoltage);
|
||||
$('input[name="maxcellvoltage"]').val(MISC.vbatmaxcellvoltage);
|
||||
$('input[name="warningcellvoltage"]').val(MISC.vbatwarningcellvoltage);
|
||||
$('input[name="voltagescale"]').val(MISC.vbatscale);
|
||||
|
@ -288,6 +315,10 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
|
|||
|
||||
|
||||
// UI hooks
|
||||
$('input[name="looptime"]').change(function() {
|
||||
recalculate_cycles_sec();
|
||||
});
|
||||
|
||||
$('input[type="checkbox"].feature', features_e).change(function () {
|
||||
var element = $(this),
|
||||
index = element.data('bit'),
|
||||
|
@ -339,6 +370,7 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
|
|||
if(semver.gte(CONFIG.apiVersion, "1.8.0")) {
|
||||
ARMING_CONFIG.auto_disarm_delay = parseInt($('input[name="autodisarmdelay"]').val());
|
||||
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());
|
||||
|
@ -348,7 +380,6 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
|
|||
MISC.mincommand = parseInt($('input[name="mincommand"]').val());
|
||||
|
||||
MISC.vbatmincellvoltage = parseFloat($('input[name="mincellvoltage"]').val());
|
||||
MISC.vbatwarningcellvoltage = parseFloat($('input[name="warningcellvoltage"]').val());
|
||||
MISC.vbatmaxcellvoltage = parseFloat($('input[name="maxcellvoltage"]').val());
|
||||
MISC.vbatwarningcellvoltage = parseFloat($('input[name="warningcellvoltage"]').val());
|
||||
MISC.vbatscale = parseInt($('input[name="voltagescale"]').val());
|
||||
|
@ -375,7 +406,11 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
|
|||
}
|
||||
|
||||
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() {
|
||||
|
@ -393,20 +428,12 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
|
|||
function reinitialize() {
|
||||
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() {
|
||||
MSP.send_message(MSP_codes.MSP_IDENT, false, false, function () {
|
||||
GUI.log(chrome.i18n.getMessage('deviceReady'));
|
||||
TABS.configuration.initialize(false, $('#content').scrollTop());
|
||||
});
|
||||
},1500); // 1500 ms seems to be just the right amount of delay to prevent data request timeouts
|
||||
}
|
||||
GUI.timeout_add('waiting_for_bootup', function waiting_for_bootup() {
|
||||
MSP.send_message(MSP_codes.MSP_IDENT, false, false, function () {
|
||||
GUI.log(chrome.i18n.getMessage('deviceReady'));
|
||||
TABS.configuration.initialize(false, $('#content').scrollTop());
|
||||
});
|
||||
},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);
|
||||
|
|
|
@ -59,7 +59,7 @@ TABS.dataflash.initialize = function (callback) {
|
|||
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 {
|
||||
$(".tab-dataflash .dataflash-used").css({
|
||||
display: 'none'
|
||||
|
@ -71,7 +71,7 @@ TABS.dataflash.initialize = function (callback) {
|
|||
width: ((DATAFLASH.totalSize - DATAFLASH.usedSize) / DATAFLASH.totalSize * 100) + "%",
|
||||
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 {
|
||||
$(".tab-dataflash .dataflash-free").css({
|
||||
display: 'none'
|
||||
|
@ -146,53 +146,66 @@ TABS.dataflash.initialize = function (callback) {
|
|||
$(".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() {
|
||||
var
|
||||
maxBytes = DATAFLASH.usedSize;
|
||||
|
||||
if (GUI.connected_to) {
|
||||
prepare_file(function(fileWriter) {
|
||||
// Begin by refreshing the occupied size in case it changed while the tab was open
|
||||
flash_update_summary(function() {
|
||||
var
|
||||
nextAddress = 0;
|
||||
maxBytes = DATAFLASH.usedSize;
|
||||
|
||||
show_saving_dialog();
|
||||
prepare_file(function(fileWriter) {
|
||||
var
|
||||
nextAddress = 0;
|
||||
|
||||
function onChunkRead(chunkAddress, chunkDataView) {
|
||||
if (chunkDataView != null) {
|
||||
// Did we receive any data?
|
||||
if (chunkDataView.byteLength > 0) {
|
||||
nextAddress += chunkDataView.byteLength;
|
||||
show_saving_dialog();
|
||||
|
||||
$(".dataflash-saving progress").attr("value", nextAddress / maxBytes * 100);
|
||||
function onChunkRead(chunkAddress, chunkDataView) {
|
||||
if (chunkDataView != null) {
|
||||
// Did we receive any data?
|
||||
if (chunkDataView.byteLength > 0) {
|
||||
nextAddress += chunkDataView.byteLength;
|
||||
|
||||
var
|
||||
blob = new Blob([chunkDataView]);
|
||||
$(".dataflash-saving progress").attr("value", nextAddress / maxBytes * 100);
|
||||
|
||||
fileWriter.onwriteend = function(e) {
|
||||
if (saveCancelled || nextAddress >= maxBytes) {
|
||||
if (saveCancelled) {
|
||||
dismiss_saving_dialog();
|
||||
var
|
||||
blob = new Blob([chunkDataView]);
|
||||
|
||||
fileWriter.onwriteend = function(e) {
|
||||
if (saveCancelled || nextAddress >= maxBytes) {
|
||||
if (saveCancelled) {
|
||||
dismiss_saving_dialog();
|
||||
} else {
|
||||
mark_saving_dialog_done();
|
||||
}
|
||||
} else {
|
||||
mark_saving_dialog_done();
|
||||
MSP.dataflashRead(nextAddress, onChunkRead);
|
||||
}
|
||||
} else {
|
||||
MSP.dataflashRead(nextAddress, onChunkRead);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
fileWriter.write(blob);
|
||||
fileWriter.write(blob);
|
||||
} else {
|
||||
// A zero-byte block indicates end-of-file, so we're done
|
||||
mark_saving_dialog_done();
|
||||
}
|
||||
} else {
|
||||
// A zero-byte block indicates end-of-file, so we're done
|
||||
mark_saving_dialog_done();
|
||||
// There was an error with the received block (address didn't match the one we asked for), retry
|
||||
MSP.dataflashRead(nextAddress, onChunkRead);
|
||||
}
|
||||
} else {
|
||||
// There was an error with the received block (address didn't match the one we asked for), retry
|
||||
MSP.dataflashRead(nextAddress, onChunkRead);
|
||||
}
|
||||
}
|
||||
|
||||
// Fetch the initial block
|
||||
MSP.dataflashRead(nextAddress, onChunkRead);
|
||||
// Fetch the initial block
|
||||
MSP.dataflashRead(nextAddress, onChunkRead);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -246,8 +259,7 @@ TABS.dataflash.initialize = function (callback) {
|
|||
}
|
||||
|
||||
function poll_for_erase_completion() {
|
||||
MSP.send_message(MSP_codes.MSP_DATAFLASH_SUMMARY, false, false, function() {
|
||||
update_html();
|
||||
flash_update_summary(function() {
|
||||
if (!eraseCancelled) {
|
||||
if (DATAFLASH.ready) {
|
||||
$(".dataflash-confirm-erase")[0].close();
|
||||
|
|
|
@ -39,7 +39,7 @@ TABS.firmware_flasher.initialize = function (callback) {
|
|||
var showDevReleases = ($('input.show_development_releases').is(':checked'));
|
||||
releases_e.append($("<option value='0'>{0}</option>".format(chrome.i18n.getMessage('firmwareFlasherOptionLabelSelectFirmware'))));
|
||||
|
||||
var releaseDescritpors = [];
|
||||
var releaseDescriptors = [];
|
||||
TABS.firmware_flasher.releases.forEach(function(release){
|
||||
release.assets.forEach(function(asset){
|
||||
var targetFromFilenameExpression = /.*_(.*)\.(.*)/;
|
||||
|
@ -81,11 +81,11 @@ TABS.firmware_flasher.initialize = function (callback) {
|
|||
"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
|
||||
var cmpVal = semver(o2.version).compare(semver(o1.version));
|
||||
if (cmpVal == 0){
|
||||
|
@ -96,7 +96,7 @@ TABS.firmware_flasher.initialize = function (callback) {
|
|||
});
|
||||
|
||||
var optionIndex = 1;
|
||||
releaseDescritpors.forEach(function(descriptor){
|
||||
releaseDescriptors.forEach(function(descriptor){
|
||||
var select_e =
|
||||
$("<option value='{0}'>{1} {2} {3} ({4})</option>".format(
|
||||
optionIndex++,
|
||||
|
|
|
@ -272,7 +272,7 @@ TABS.motors.initialize = function (callback) {
|
|||
');
|
||||
|
||||
servos_wrapper.append('\
|
||||
<div class="m-block servo-' + i + '">\
|
||||
<div class="m-block servo-' + (7 - i) + '">\
|
||||
<div class="meter-bar">\
|
||||
<div class="label"></div>\
|
||||
<div class="indicator">\
|
||||
|
|
|
@ -71,13 +71,13 @@
|
|||
border: 1px dashed silver;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.require-support {
|
||||
.tab-ports .require-support {
|
||||
display:none;
|
||||
}
|
||||
.tab-ports.supported .require-support {
|
||||
display:block;
|
||||
}
|
||||
.require-upgrade {
|
||||
.tab-ports .require-upgrade {
|
||||
display:block;
|
||||
}
|
||||
.tab-ports.supported .require-upgrade {
|
||||
|
|
|
@ -18,6 +18,11 @@
|
|||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="help">
|
||||
<p i18n="portsMSPHelp"></p>
|
||||
</div>
|
||||
|
||||
<div class="clear-both"></div>
|
||||
<div class="buttons">
|
||||
<a class="save" href="#" i18n="portsButtonSave"></a>
|
||||
|
|
25
tabs/ports.js
Executable file → Normal file
25
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(),
|
||||
identifier: oldSerialPort.identifier
|
||||
};
|
||||
|
||||
console.log(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);
|
||||
|
||||
function save_to_eeprom() {
|
||||
|
@ -259,22 +262,14 @@ TABS.ports.initialize = function (callback, scrollPosition) {
|
|||
function on_reboot_success_handler() {
|
||||
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() {
|
||||
MSP.send_message(MSP_codes.MSP_IDENT, false, false, function () {
|
||||
GUI.log(chrome.i18n.getMessage('deviceReady'));
|
||||
TABS.ports.initialize(false, $('#content').scrollTop());
|
||||
});
|
||||
}, 1500); // seems to be just the right amount of delay to prevent data request timeouts
|
||||
}
|
||||
|
||||
|
||||
var rebootTimeoutDelay = 1500; // seems to be just the right amount of delay to prevent data request timeouts
|
||||
|
||||
GUI.timeout_add('waiting_for_bootup', function waiting_for_bootup() {
|
||||
MSP.send_message(MSP_codes.MSP_IDENT, false, false, function () {
|
||||
GUI.log(chrome.i18n.getMessage('deviceReady'));
|
||||
TABS.ports.initialize(false, $('#content').scrollTop());
|
||||
});
|
||||
}, rebootTimeoutDelay);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -3,6 +3,12 @@
|
|||
.tab-receiver input[type="number"]::-webkit-inner-spin-button {
|
||||
border: 0;
|
||||
}
|
||||
.tab-receiver .help {
|
||||
padding: 10px;
|
||||
background-color: #ffcb18;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.tab-receiver .bars {
|
||||
float: left;
|
||||
width: 45%;
|
||||
|
@ -218,7 +224,7 @@
|
|||
margin: 0 10px 10px 0;
|
||||
|
||||
width: 220px;
|
||||
height: 58px;
|
||||
height: 120px;
|
||||
|
||||
border: 1px solid silver;
|
||||
}
|
||||
|
@ -226,7 +232,7 @@
|
|||
margin: 0 10px 0 0;
|
||||
|
||||
width: 220px;
|
||||
height: 58px;
|
||||
height: 120px;
|
||||
|
||||
border: 1px solid silver;
|
||||
}
|
||||
|
@ -293,6 +299,7 @@
|
|||
position: absolute;
|
||||
bottom: 10px;
|
||||
}
|
||||
.tab-receiver .sticks,
|
||||
.tab-receiver .update,
|
||||
.tab-receiver .refresh {
|
||||
display: block;
|
||||
|
@ -311,6 +318,7 @@
|
|||
border: 1px solid silver;
|
||||
background-color: #ececec;
|
||||
}
|
||||
.tab-receiver .sticks,
|
||||
.tab-receiver .refresh {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
<div id="content-watermark"></div>
|
||||
<div class="tab-receiver">
|
||||
<div class="help">
|
||||
<p i18n="receiverHelp"></p>
|
||||
</div>
|
||||
|
||||
<div class="bars">
|
||||
</div>
|
||||
<div class="tunings">
|
||||
|
@ -53,10 +57,10 @@
|
|||
</div>
|
||||
<div class="curves">
|
||||
<div class="throttle_curve">
|
||||
<canvas width="220" height="58"></canvas>
|
||||
<canvas width="220" height="120"></canvas>
|
||||
</div>
|
||||
<div class="pitch_roll_curve">
|
||||
<canvas width="220" height="58"></canvas>
|
||||
<canvas width="220" height="120"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clear-both"></div>
|
||||
|
@ -82,5 +86,6 @@
|
|||
<div class="buttons">
|
||||
<a class="update" href="#" i18n="receiverButtonSave"></a>
|
||||
<a class="refresh" href="#" i18n="receiverButtonRefresh"></a>
|
||||
<a class="sticks" href="#" i18n="receiverButtonSticks"></a>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
'use strict';
|
||||
|
||||
TABS.receiver = {};
|
||||
TABS.receiver = {
|
||||
rateChartHeight: 120
|
||||
};
|
||||
|
||||
TABS.receiver.initialize = function (callback) {
|
||||
var self = this;
|
||||
|
||||
|
@ -18,7 +21,12 @@ TABS.receiver.initialize = function (callback) {
|
|||
}
|
||||
|
||||
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() {
|
||||
|
@ -52,7 +60,12 @@ TABS.receiver.initialize = function (callback) {
|
|||
});
|
||||
|
||||
// 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'),
|
||||
aux_index = 1;
|
||||
|
||||
|
@ -61,7 +74,7 @@ TABS.receiver.initialize = function (callback) {
|
|||
if (i < bar_names.length) {
|
||||
name = bar_names[i];
|
||||
} else {
|
||||
name = 'AUX ' + aux_index++;
|
||||
name = chrome.i18n.getMessage("controlAxisAux" + (aux_index++));
|
||||
}
|
||||
|
||||
bar_container.append('\
|
||||
|
@ -176,6 +189,8 @@ TABS.receiver.initialize = function (callback) {
|
|||
|
||||
$('select[name="rssi_channel"]').val(MISC.rssi_channel);
|
||||
|
||||
var rateHeight = TABS.receiver.rateChartHeight;
|
||||
|
||||
// UI Hooks
|
||||
// curves
|
||||
$('.tunings .throttle input').on('input change', function () {
|
||||
|
@ -201,14 +216,14 @@ TABS.receiver.initialize = function (callback) {
|
|||
var midx = 220 * mid,
|
||||
midxl = midx * 0.5,
|
||||
midxr = (((220 - midx) * 0.5) + midx),
|
||||
midy = 58 - (midx * (58 / 220)),
|
||||
midyl = 58 - ((58 - midy) * 0.5 *(expo + 1)),
|
||||
midy = rateHeight - (midx * (rateHeight / 220)),
|
||||
midyl = rateHeight - ((rateHeight - midy) * 0.5 *(expo + 1)),
|
||||
midyr = (midy / 2) * (expo + 1);
|
||||
|
||||
// draw
|
||||
context.clearRect(0, 0, 220, 58);
|
||||
context.clearRect(0, 0, 220, rateHeight);
|
||||
context.beginPath();
|
||||
context.moveTo(0, 58);
|
||||
context.moveTo(0, rateHeight);
|
||||
context.quadraticCurveTo(midxl, midyl, midx, midy);
|
||||
context.moveTo(midx, midy);
|
||||
context.quadraticCurveTo(midxr, midyr, 220, 0);
|
||||
|
@ -237,13 +252,13 @@ TABS.receiver.initialize = function (callback) {
|
|||
}
|
||||
|
||||
// math magic by englishman
|
||||
var ratey = 58 * rate;
|
||||
var ratey = rateHeight * rate;
|
||||
|
||||
// draw
|
||||
context.clearRect(0, 0, 220, 58);
|
||||
context.clearRect(0, 0, 220, rateHeight);
|
||||
context.beginPath();
|
||||
context.moveTo(0, 58);
|
||||
context.quadraticCurveTo(110, 58 - ((ratey / 2) * (1 - expo)), 220, 58 - ratey);
|
||||
context.moveTo(0, rateHeight);
|
||||
context.quadraticCurveTo(110, rateHeight - ((ratey / 2) * (1 - expo)), 220, rateHeight - ratey);
|
||||
context.lineWidth = 2;
|
||||
context.stroke();
|
||||
}, 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);
|
||||
});
|
||||
|
||||
$("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 () {
|
||||
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.magnetometer[i] = 0;
|
||||
SENSOR_DATA.sonar = 0;
|
||||
SENSOR_DATA.altitude = 0;
|
||||
SENSOR_DATA.debug[i] = 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,10 +3,6 @@
|
|||
.tab-servos input[type="number"]::-webkit-inner-spin-button {
|
||||
border: 0;
|
||||
}
|
||||
.tab-servos .supported_wrapper,
|
||||
.tab-servos .direction_wrapper {
|
||||
display: none;
|
||||
}
|
||||
.tab-servos .title {
|
||||
margin-top: 10px;
|
||||
|
||||
|
@ -130,3 +126,16 @@
|
|||
.tab-servos .update:hover {
|
||||
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">
|
||||
<span i18n="servosModel"></span> <strong class="model"></strong>
|
||||
<div class="supported_wrapper">
|
||||
<div class="require-support">
|
||||
<div class="title" i18n="servosChangeDirection"></div>
|
||||
<table class="fields">
|
||||
<tr class="main">
|
||||
|
@ -8,21 +7,14 @@
|
|||
<th style="width: 120px" i18n="servosMid"></th>
|
||||
<th style="width: 120px" i18n="servosMin"></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">CH2</th>
|
||||
<th style="width: 40px">CH3</th>
|
||||
<th style="width: 40px">CH4</th>
|
||||
</tr>
|
||||
</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">
|
||||
<span i18n="servosLiveMode"></span> <input type="checkbox" />
|
||||
</div>
|
||||
|
@ -30,4 +22,7 @@
|
|||
<a class="update" href="#" i18n="servosButtonSave"></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="note require-upgrade" i18n="servosFirmwareUpgradeRequired">
|
||||
</div>
|
||||
</div>
|
282
tabs/servos.js
282
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';
|
||||
|
||||
TABS.servos = {};
|
||||
|
@ -15,15 +9,25 @@ TABS.servos.initialize = function (callback) {
|
|||
googleAnalytics.sendAppView('Servos');
|
||||
}
|
||||
|
||||
function get_servo_conf_data() {
|
||||
MSP.send_message(MSP_codes.MSP_SERVO_CONF, false, false, get_channel_forwarding_data);
|
||||
function get_servo_configurations() {
|
||||
MSP.send_message(MSP_codes.MSP_SERVO_CONFIGURATIONS, false, false, get_servo_mix_rules);
|
||||
}
|
||||
|
||||
function get_channel_forwarding_data() {
|
||||
MSP.send_message(MSP_codes.MSP_CHANNEL_FORWARDING, false, false, get_rc_data);
|
||||
function get_servo_mix_rules() {
|
||||
MSP.send_message(MSP_codes.MSP_SERVO_MIX_RULES, false, false, get_channel_forwarding);
|
||||
}
|
||||
|
||||
function get_rc_data() {
|
||||
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() {
|
||||
MSP.send_message(MSP_codes.MSP_RC, false, false, get_boxnames_data);
|
||||
}
|
||||
|
||||
|
@ -35,9 +39,17 @@ TABS.servos.initialize = function (callback) {
|
|||
$('#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 servoHeader = '';
|
||||
|
@ -46,7 +58,7 @@ TABS.servos.initialize = function (callback) {
|
|||
<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++) {
|
||||
servoCheckbox = servoCheckbox + '\
|
||||
|
@ -54,86 +66,44 @@ TABS.servos.initialize = function (callback) {
|
|||
';
|
||||
}
|
||||
|
||||
|
||||
|
||||
$('div.tab-servos table.fields tr.main').append(servoHeader);
|
||||
|
||||
function process_directions(name, obj, bitpos) {
|
||||
$('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) {
|
||||
function process_servos(name, alternate, obj) {
|
||||
|
||||
$('div.supported_wrapper').show();
|
||||
|
||||
|
||||
|
||||
$('div.tab-servos table.fields').append('\
|
||||
<tr> \
|
||||
<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="min"><input type="number" min="1000" max="2000" value="' + SERVO_CONFIG[obj].min +'" /></td>\
|
||||
<td class="max"><input type="number" min="1000" max="2000" value="' + SERVO_CONFIG[obj].max +'" /></td>\
|
||||
<td class="middle"><input type="number" min="500" max="2500" value="' + SERVO_CONFIG[obj].middle + '" /></td>\
|
||||
<td class="min"><input type="number" min="500" max="2500" value="' + SERVO_CONFIG[obj].min +'" /></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 + '\
|
||||
<td class="direction">\
|
||||
<input class="first" type="checkbox"/><span class="name">' + name + '</span>\
|
||||
<input class="second" type="checkbox"/><span class="alternate">' + alternate + '</span>\
|
||||
</td>\
|
||||
</tr> \
|
||||
');
|
||||
|
||||
|
||||
|
||||
// translate to user-selected language
|
||||
localize();
|
||||
|
||||
$('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
|
||||
$('div.tab-servos table.fields tr:last td.direction').append('\
|
||||
<select class="rate" name="rate"></select>\
|
||||
');
|
||||
|
||||
var select = $('div.tab-servos table.fields tr:last td.direction select');
|
||||
|
||||
for (var i = 100; i > -101; i--) {
|
||||
select.append('<option value="' + i + '">Rate: ' + i + '%</option>');
|
||||
}
|
||||
|
||||
// select current rate
|
||||
select.val(SERVO_CONFIG[obj].rate);
|
||||
} else {
|
||||
// removing checkboxes
|
||||
$('div.tab-servos table.fields tr:last td.direction').html('');
|
||||
if (SERVO_CONFIG[obj].indexOfChannelToForward >= 0) {
|
||||
$('div.tab-servos table.fields tr:last td.channel input').eq(SERVO_CONFIG[obj].indexOfChannelToForward).prop('checked', true);
|
||||
}
|
||||
|
||||
// adding select box and generating options
|
||||
$('div.tab-servos table.fields tr:last td.direction').append('\
|
||||
<select class="rate" name="rate"></select>\
|
||||
');
|
||||
|
||||
var select = $('div.tab-servos table.fields tr:last td.direction select');
|
||||
|
||||
for (var i = 100; i > -101; i--) {
|
||||
select.append('<option value="' + i + '">Rate: ' + i + '%</option>');
|
||||
}
|
||||
|
||||
// select current rate
|
||||
select.val(SERVO_CONFIG[obj].rate);
|
||||
|
||||
$('div.tab-servos table.fields tr:last').data('info', {'obj': obj});
|
||||
|
||||
// UI hooks
|
||||
|
@ -146,18 +116,7 @@ TABS.servos.initialize = function (callback) {
|
|||
});
|
||||
}
|
||||
|
||||
function servos_update(save_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
|
||||
function servos_update(save_configuration_to_eeprom) {
|
||||
$('div.tab-servos table.fields tr:not(".main")').each(function () {
|
||||
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].min = parseInt($('.min 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);
|
||||
var val = parseInt($('.direction select', this).val());
|
||||
SERVO_CONFIG[info.obj].rate = val;
|
||||
});
|
||||
|
||||
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());
|
||||
SERVO_CONFIG[info.obj].rate = val;
|
||||
//
|
||||
// send data to FC
|
||||
//
|
||||
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 () {
|
||||
GUI.log(chrome.i18n.getMessage('servosEepromSave'));
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
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 () {
|
||||
if (save_to_eeprom) {
|
||||
// Save changes to EEPROM
|
||||
MSP.send_message(MSP_codes.MSP_EEPROM_WRITE, false, false, function () {
|
||||
GUI.log(chrome.i18n.getMessage('servosEepromSave'));
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// drop previous table
|
||||
$('div.tab-servos table.fields tr:not(:first)').remove();
|
||||
|
||||
var model = $('div.tab-servos strong.model');
|
||||
var supported_models = [1, 4, 5, 8, 14, 20, 21];
|
||||
|
||||
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);
|
||||
}
|
||||
for (var servoIndex = 0; servoIndex < 8; servoIndex++) {
|
||||
process_servos('Servo ' + servoIndex, '', servoIndex, false);
|
||||
}
|
||||
|
||||
// UI hooks for dynamically generated elements
|
||||
|
@ -301,12 +175,18 @@ TABS.servos.initialize = function (callback) {
|
|||
});
|
||||
|
||||
$('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
|
||||
GUI.interval_add('status_pull', function () {
|
||||
MSP.send_message(MSP_codes.MSP_STATUS);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue