Merge branch 'master' of https://github.com/iNavFlight/inav-configurator into submit-led-pwm
55
README.md
|
@ -41,12 +41,42 @@ Depending on target operating system, _INAV Configurator_ is distributed as _sta
|
|||
### Linux
|
||||
|
||||
1. Visit [release page](https://github.com/iNavFlight/inav-configurator/releases)
|
||||
1. Download Configurator for Linux platform (linux32 and linux64 are present)
|
||||
1. Extract tar.gz archive
|
||||
1. Make the following files executable:
|
||||
* inav-configurator `chmod +x inav-configurator`
|
||||
* (5.0.0+) chrome_crashpad_handler `chmod +x chrome_crashpad_handler`
|
||||
1. Run INAV Configurator app from unpacked folder
|
||||
2. Download Configurator for Linux platform (linux32 and linux64 are present)
|
||||
* **.rpm** is the Fedora installation file. Just download and install using `sudo dnf localinstall /path/to/INAV-Configurator_linux64-x.y.z-x86_64.rpm` or open it with a package manager (e.g. via Files)
|
||||
* **.deb** is the Debian/Ubuntu installation file. Just download and install using `sudo apt install /path/to/INAV-Configurator_linux64_x.y.z.deb` or open it with a package manager (e.g. via the File Manager)
|
||||
* **.tar.gz** is a universal archive. Download and continue with these instructions to install
|
||||
3. Change to the directory containing the downloaded **tar.gz** file
|
||||
4. download [this](https://raw.githubusercontent.com/iNavFlight/inav-configurator/master/assets/linux/inav-configurator.desktop) file to the same directory. Its filename should be `inav-configurator.desktop`.
|
||||
5. Extract **tar.gz** archive
|
||||
```
|
||||
tar -C /tmp/ -xf INAV-Configurator_linuxNN_x.y.z.tar.gz
|
||||
```
|
||||
**NN** is the bits of your OS. **x.y.z** is the INAV Configurator version number.
|
||||
|
||||
6. If this is the first time installing INAV Configurator, create a home for its files
|
||||
```
|
||||
sudo mkdir /opt/inav
|
||||
sudo chown $USER /opt/inav
|
||||
```
|
||||
7. Move the temporary files in to their home
|
||||
```
|
||||
mv /tmp/INAV\ Configurator /opt/inav/inav-configurator
|
||||
```
|
||||
8. Update the application icon.
|
||||
```
|
||||
sudo mkdir /opt/inav/inav-configurator/icon
|
||||
sudo cp /opt/inav/inav-configurator/images/inav_icon_128.png /opt/inav/inav-configurator/icon
|
||||
```
|
||||
9. As a one off, move the desktop file into the applications directory
|
||||
```
|
||||
sudo mv inav-configurator.desktop /usr/share/applications/
|
||||
```
|
||||
10. Make the following files executable:
|
||||
* inav-configurator `chmod +x /opt/inav/inav-configurator/inav-configurator`
|
||||
* (5.0.0+) chrome_crashpad_handler `chmod +x /opt/inav/inav-configurator/chrome_crashpad_handler`
|
||||
11. Run INAV Configurator app from unpacked folder `/opt/inav/inav-configurator/inav-configurator`
|
||||
|
||||
#### Notes
|
||||
|
||||
On some Linux distros, you may be missing `libatomic`, a `NW.JS` (specially `libnode.so`) dependency. If so, please install `libatomic` using your distro's package manager, e.g:
|
||||
|
||||
|
@ -54,15 +84,17 @@ On some Linux distros, you may be missing `libatomic`, a `NW.JS` (specially `lib
|
|||
* Debian / Ubuntu: `sudo apt install libatomic1`
|
||||
* Fedora: `sudo dnf install libatomic`
|
||||
|
||||
1. Don't 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
|
||||
|
||||
### Mac
|
||||
|
||||
1. Visit [release page](https://github.com/iNavFlight/inav-configurator/releases)
|
||||
1. Download Configurator for Mac platform
|
||||
1. Extract ZIP archive
|
||||
1. Run INAV Configurator
|
||||
1. Configurator is not signed, so you have to allow Mac to run untrusted application. There might be a monit for it during first run
|
||||
|
||||
## Building and running INAV Configurator locally (for development or Linux users)
|
||||
## Building and running INAV Configurator locally (for development)
|
||||
|
||||
For local development, **node.js** build system is used.
|
||||
|
||||
|
@ -96,7 +128,7 @@ To be able to open Inspector, you will need SDK flavours of NW.js
|
|||
## Different map providers
|
||||
|
||||
INAV Configurator 2.1 allows to choose between OpenStreetMap, Bing Maps (Aerial View), and MapProxy map providers.
|
||||
INAV Configurator is shipped **WITHOUT** API key for Bing Maps. That means: every user who wants to use Bing Maps has to create own account, agree to all _Terms and Conditions_ required by Bing Maps and configure INAV Configuerator by himself.
|
||||
INAV Configurator is shipped **WITHOUT** API key for Bing Maps. That means: every user who wants to use Bing Maps has to create own account, agree to all _Terms and Conditions_ required by Bing Maps and configure INAV Configurator by himself.
|
||||
|
||||
### How to choose Map provider
|
||||
|
||||
|
@ -136,11 +168,6 @@ INAV provides the font images so that custom fonts can be created for your perso
|
|||
|
||||
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
|
||||
|
||||
## Issue trackers
|
||||
|
||||
For INAV configurator issues raise them here
|
||||
|
|
|
@ -110,6 +110,9 @@
|
|||
"tabFailsafe": {
|
||||
"message": "Failsafe"
|
||||
},
|
||||
"tabEzTune": {
|
||||
"message": "Ez Tune"
|
||||
},
|
||||
"tabGPS": {
|
||||
"message": "GPS"
|
||||
},
|
||||
|
@ -485,10 +488,16 @@
|
|||
"message": "Welcome to <strong>INAV - Configurator</strong>, a utility designed to simplify updating, configuring and tuning of your flight controller."
|
||||
},
|
||||
"defaultWelcomeHead": {
|
||||
"message": "Hardware"
|
||||
"message": "Firmware & drivers"
|
||||
},
|
||||
"defaultWelcomeHead2": {
|
||||
"message": "INAV Friends"
|
||||
},
|
||||
"defaultWelcomeText2": {
|
||||
"message": "INAV is supported by a great community of users, developers and companies. Here is a short list: <a href=\"http://www.mateksys.com/\" target=\"_blank\">Mateksys</a>, <a href=\"https://www.speedybee.com/\" target=\"_blank\">SpeedyBee</a>, <a href=\"https://geprc.com/\" target=\"_blank\">GEPRC</a>. "
|
||||
},
|
||||
"defaultWelcomeText": {
|
||||
"message": "The application supports all hardware that can run INAV (<a href=\"https://inavflight.com/shop/s/bg/1890404\" target=\"_blank\">Matek F765-WSE</a>, <a href=\"https://inavflight.com/shop/s/bg/1755036\" target=\"_blank\">Matek H743-SLIM</a> and many other). The full list of recommended hardware is available <a href=\"https://github.com/iNavFlight/inav/wiki/Welcome-to-INAV,-useful-links-and-products\" target=\"_blank\">here</a>.<br /><br />The firmware source code can be downloaded from <a href=\"https://github.com/iNavFlight\" title=\"www.github.com\" target=\"_blank\">here</a><br />The newest binary firmware image is available <a href=\"https://github.com/iNavFlight/inav/releases\" title=\"www.github.com\" target=\"_blank\">here</a>.<br /><br />Latest <strong>STM USB VCP Drivers</strong> can be downloaded from <a href=\"http://www.st.com/web/en/catalog/tools/PF257938\" title=\"http://www.st.com\" target=\"_blank\">here</a><br />Latest <strong>Zadig</strong> for Windows DFU flashing can be downloaded from <a href=\"http://zadig.akeo.ie/\" title=\"http://zadig.akeo.ie\" target=\"_blank\">here</a><br />"
|
||||
"message": "The firmware source code can be downloaded from <a href=\"https://github.com/iNavFlight\" title=\"www.github.com\" target=\"_blank\">here</a><br />The newest binary firmware image is available <a href=\"https://github.com/iNavFlight/inav/releases\" title=\"www.github.com\" target=\"_blank\">here</a>.<br /><br />Latest <strong>STM USB VCP Drivers</strong> can be downloaded from <a href=\"http://www.st.com/web/en/catalog/tools/PF257938\" title=\"http://www.st.com\" target=\"_blank\">here</a><br />Latest <strong>Zadig</strong> for Windows DFU flashing can be downloaded from <a href=\"http://zadig.akeo.ie/\" title=\"http://zadig.akeo.ie\" target=\"_blank\">here</a><br />"
|
||||
},
|
||||
"defaultContributingHead": {
|
||||
"message": "Contributing"
|
||||
|
@ -900,18 +909,6 @@
|
|||
"configurationSerialRXHelp": {
|
||||
"message": "<strong>Note:</strong> Remember to configure a Serial Port (via Ports tab) for the serial receiver"
|
||||
},
|
||||
"configurationBoardAlignment": {
|
||||
"message": "Board and Sensor Alignment"
|
||||
},
|
||||
"configurationBoardAlignmentRoll": {
|
||||
"message": "Roll Degrees"
|
||||
},
|
||||
"configurationBoardAlignmentPitch": {
|
||||
"message": "Pitch Degrees"
|
||||
},
|
||||
"configurationBoardAlignmentYaw": {
|
||||
"message": "Yaw Degrees"
|
||||
},
|
||||
"configurationSensorAlignmentMag": {
|
||||
"message": "MAG Alignment"
|
||||
},
|
||||
|
@ -1365,6 +1362,24 @@
|
|||
"pidTuning_RatesAndExpo": {
|
||||
"message": "Rates & Expo"
|
||||
},
|
||||
"pidTuning_RateDynamics": {
|
||||
"message": "Rate Dynamics"
|
||||
},
|
||||
"pidTuning_RateDynamics_Sensitivity": {
|
||||
"message": "Sensitivity"
|
||||
},
|
||||
"pidTuning_RateDynamics_Correction": {
|
||||
"message": "Correction"
|
||||
},
|
||||
"pidTuning_RateDynamics_Weight": {
|
||||
"message": "Weight"
|
||||
},
|
||||
"pidTuning_RateDynamics_Center": {
|
||||
"message": "Center"
|
||||
},
|
||||
"pidTuning_RateDynamics_End": {
|
||||
"message": "End"
|
||||
},
|
||||
"pidTuning_RollPitchRate": {
|
||||
"message": "ROLL & PITCH rate"
|
||||
},
|
||||
|
@ -1569,6 +1584,9 @@
|
|||
"pidTuning_gyro_dyn_lpf_max_hz_help": {
|
||||
"message": "Defines the gyro LPF cutoff frequency at maximum throttle. When throttle is decreased, LPF cutoff frequency is decreased as well, down to the minimum cutoff frequency."
|
||||
},
|
||||
"loadedMixerProfile": {
|
||||
"message": "Loaded Mixer Profile: <strong style=\"color: #37a8db\">$1</strong>, Check modes tab: MIXER PROFILE 2 if you don't see the changes"
|
||||
},
|
||||
"loadedBatteryProfile": {
|
||||
"message": "Loaded Battery Profile: <strong style=\"color: #37a8db\">$1</strong>"
|
||||
},
|
||||
|
@ -2035,19 +2053,22 @@
|
|||
"message": "Signal Strength"
|
||||
},
|
||||
"magnetometerHead": {
|
||||
"message": "Magnetometer Alignment"
|
||||
"message": "Alignment tool"
|
||||
},
|
||||
"magnetometerHelp": {
|
||||
"message": "Adjust the magnetometer position until you get the same on the quad.<br/><strong>Note:</strong> If you have changed your flight controller alignment, make your adjustment relative to the FC position and not to the UAV position "
|
||||
"message": "1. Adjust Flight Controller orientation to match physical orientation on the aircraft <u>according to \"direction\" arrow on Flight Controller</u>.<br/>2. Adjust magnetometer orientation to match physical orientation on the aircraft <u>according to \"compass direction\" arrow or axis markings on magnetometer</u>.<br/><strong>Note:</strong> Magnetometer orientation preset (align_mag) is relative to FC. Make sure to align FC first (align_board_pitch, align_board_roll, align_board_yaw).<br/>If preset is not used (orientation is set using align_mag_roll, align_mag_pitch and align_mag_yaw), then magnetometer orientation is independent."
|
||||
},
|
||||
"magnetometerOrientationPreset": {
|
||||
"message": "Orientation presets"
|
||||
"message": "Orientation preset (align_mag). Relative to FC orientation"
|
||||
},
|
||||
"boardInfo": {
|
||||
"message": "1. Select Flight Controller alignment<br>(align_board_roll, align_board_pitch, align_board_yaw)"
|
||||
},
|
||||
"magnetometerInfo": {
|
||||
"message": "Select a preset or create a custom configuration moving the sliders"
|
||||
"message": "2. Select a preset (align_mag) or create a custom configuration using the sliders<br>(align_mag_roll, align_mag_pitch, align_mag_yaw)"
|
||||
},
|
||||
"magnetometerElementToShow": {
|
||||
"message": "Element to show"
|
||||
"message": "Element to show: Magnetometer model or axes"
|
||||
},
|
||||
|
||||
"axisTableTitleAxis": {
|
||||
|
@ -2060,9 +2081,6 @@
|
|||
"message": "Value [degree]"
|
||||
},
|
||||
|
||||
|
||||
|
||||
|
||||
"configurationMagnetometerHelp": {
|
||||
"message": "<strong>Note:</strong> Remember to configure a Serial Port (via Ports tab) when using the Magnetometer feature."
|
||||
},
|
||||
|
@ -2070,7 +2088,7 @@
|
|||
"message": "Mag Statistics"
|
||||
},
|
||||
"tabMAGNETOMETER": {
|
||||
"message": "Magnetometer"
|
||||
"message": "Alignment tool"
|
||||
},
|
||||
"motors": {
|
||||
"message": "Motors"
|
||||
|
@ -3371,14 +3389,23 @@
|
|||
"osd_pilot_name": {
|
||||
"message": "Pilot's Name"
|
||||
},
|
||||
"osdElement_PILOT_LOGO_HELP": {
|
||||
"message": "Shows your small pilot logo in the OSD, where you position it. This requires a custom font with your pilot logo."
|
||||
},
|
||||
"osd_use_pilot_logo": {
|
||||
"message": "Use pilot logo"
|
||||
},
|
||||
"osd_use_large_pilot_logo_help": {
|
||||
"message": "Use your large pilot logo with/instead of the INAV logo. This requires a custom font with your pilot logo. This is seen on the arming screen."
|
||||
},
|
||||
"osd_units": {
|
||||
"message": "Units"
|
||||
},
|
||||
"osd_main_voltage_decimals": {
|
||||
"message": "Voltage Decimals"
|
||||
},
|
||||
"osd_mah_used_precision": {
|
||||
"message": "mAh Used Precision"
|
||||
"osd_mah_precision": {
|
||||
"message": "mAh Precision"
|
||||
},
|
||||
"osd_coordinate_digits": {
|
||||
"message": "Coordinate Digits"
|
||||
|
@ -3419,6 +3446,60 @@
|
|||
"osd_home_position_arm_screen": {
|
||||
"message": "Home Position on Arming Screen"
|
||||
},
|
||||
"osd_hud_settings": {
|
||||
"message": "Heads up Display settings"
|
||||
},
|
||||
"osd_hud_settings_HELP": {
|
||||
"message": "This section allows tweaking the behavior of HUD elements."
|
||||
},
|
||||
"osd_hud_radar_disp": {
|
||||
"message": "Maximum number of radar elements on screen."
|
||||
},
|
||||
"osd_hud_radar_disp_help": {
|
||||
"message": "This is used for INAV Radar/FormationFlight. 0 disables this feature."
|
||||
},
|
||||
|
||||
"osd_hud_radar_range_min": {
|
||||
"message": "Minimum radar range"
|
||||
},
|
||||
"osd_hud_radar_range_min_help": {
|
||||
"message": "Radar aircrafts closer than this will not be displayed in the HUD."
|
||||
},
|
||||
|
||||
"osd_hud_radar_range_max": {
|
||||
"message": "Maximum radar range"
|
||||
},
|
||||
"osd_hud_radar_range_max_help": {
|
||||
"message": "Radar aircrafts further away than this will not be displayed in the HUD."
|
||||
},
|
||||
|
||||
|
||||
"osd_hud_wp_disp": {
|
||||
"message": "Maximum number of waypoint elements on screen."
|
||||
},
|
||||
"osd_hud_wp_disp_help": {
|
||||
"message": "Number of Wayponts to show on screen. 0 disables this feature."
|
||||
},
|
||||
"osd_camera_uptilt": {
|
||||
"message": "Camera uptilt"
|
||||
},
|
||||
"osd_camera_uptilt_help": {
|
||||
"message": "Set the camera uptilt for the FPV camera in degres, positive is up, negative is down, relative to the horizontal. Used for correct display of HUD items and AHI (when enabled)."
|
||||
},
|
||||
"osd_camera_fov_h": {
|
||||
"message": "Camera Horizontal FOV"
|
||||
},
|
||||
"osd_camera_fov_h_help": {
|
||||
"message": "Camera Horizontal Field of View in Degrees. It is used to calculate the position of elements in the HUD display."
|
||||
},
|
||||
"osd_camera_fov_v": {
|
||||
"message": "Camera Vertical FOV"
|
||||
},
|
||||
"osd_camera_fov_v_help": {
|
||||
"message": "Camera Vertical Field of View in Degrees. It is used to calculate the position of elements in the HUD display."
|
||||
},
|
||||
|
||||
|
||||
"osd_alarms": {
|
||||
"message": "Alarms"
|
||||
},
|
||||
|
@ -4331,6 +4412,9 @@
|
|||
"no_waypoints_to_save": {
|
||||
"message": "No waypoints to save !"
|
||||
},
|
||||
"mixerThrottleWarning": {
|
||||
"message": "Warning:value beyond normal operation range."
|
||||
},
|
||||
"servoMixer": {
|
||||
"message": "Servo mixer"
|
||||
},
|
||||
|
@ -4437,7 +4521,7 @@
|
|||
"message": "This will reset all PID settings to firmware default values and save.\nDo you want to continue?"
|
||||
},
|
||||
"mappingTableOutput": {
|
||||
"message": "Output"
|
||||
"message": "Output (timer)"
|
||||
},
|
||||
"mappingTableFunction": {
|
||||
"message": "Function"
|
||||
|
@ -4772,9 +4856,6 @@
|
|||
"WaypointOptionP2": {
|
||||
"message": "P2"
|
||||
},
|
||||
"rollPitchAdjustmentsMoved": {
|
||||
"message": "Roll & Pitch board orientation is available only in the CLI. Do not use it to trim the airplane for the level flight! Use Fixed Wing Level Trim on the PID tuning tab under Mechanics instead (<strong>fw_level_pitch_trim</strong>)."
|
||||
},
|
||||
"pidId": {
|
||||
"message": "#"
|
||||
},
|
||||
|
@ -4817,6 +4898,12 @@
|
|||
"motor_direction_inverted_hint": {
|
||||
"message": "Enable if the motor direction is reversed and the props are mounted in the opposite direction."
|
||||
},
|
||||
"mixer_pid_profile_linking": {
|
||||
"message": "PID Profile will use same index as Mixer Profile index"
|
||||
},
|
||||
"mixer_pid_profile_linking_hint": {
|
||||
"message": "mixer_pid_profile_linking: Enable on both Mixer Profile if you want PID Profile switching handled by Mixer Profile switching(Recommend in vtol/mixed plaform type setup)"
|
||||
},
|
||||
"blackboxFields": {
|
||||
"message": "Blackbox fields"
|
||||
},
|
||||
|
@ -4895,9 +4982,6 @@
|
|||
"pidTuning_MatrixFilterTypeHelp": {
|
||||
"message": "Defines the type of Matrix Filter. Default 2D filter is recommended for most users. 7-inch and larger quads may benefit from 3D filter."
|
||||
},
|
||||
"nmeaWarning": {
|
||||
"message": "NMEA protocol is deprecated and might be removed in the future. Please use UBLOX or UBLOX7 protocol instead."
|
||||
},
|
||||
"softSerialWarning": {
|
||||
"message": "It is not advisable to use softserial for flight critical devices like GPS or receiver, or high traffic devices like MSP DisplayPort."
|
||||
},
|
||||
|
@ -5135,14 +5219,20 @@
|
|||
"sensorDataFlashFreeSpace": {
|
||||
"message": "Dataflash: free space"
|
||||
},
|
||||
"mixerProfile1": {
|
||||
"message": "Mixer profile 1"
|
||||
},
|
||||
"mixerProfile2": {
|
||||
"message": "Mixer profile 2"
|
||||
},
|
||||
"sensorProfile1": {
|
||||
"message": "Profile 1"
|
||||
"message": "PID profile 1"
|
||||
},
|
||||
"sensorProfile2": {
|
||||
"message": "Profile 2"
|
||||
"message": "PID profile 2"
|
||||
},
|
||||
"sensorProfile3": {
|
||||
"message": "Profile 3"
|
||||
"message": "PID profile 3"
|
||||
},
|
||||
"sensorBatteryProfile1": {
|
||||
"message": "Battery profile 1"
|
||||
|
@ -5420,5 +5510,80 @@
|
|||
},
|
||||
"targetPrefetchFailNoPort": {
|
||||
"message": "Cannot prefetch target: No port"
|
||||
},
|
||||
"timerOutputs": {
|
||||
"message": "Timer outputs"
|
||||
},
|
||||
"ezTuneFilterHz": {
|
||||
"message": "Filter Hz"
|
||||
},
|
||||
"ezTuneAxisRatio": {
|
||||
"message": "Axis ratio"
|
||||
},
|
||||
"ezTuneResponse": {
|
||||
"message": "Response"
|
||||
},
|
||||
"ezTuneDamping": {
|
||||
"message": "Damping"
|
||||
},
|
||||
"ezTuneStability": {
|
||||
"message": "Stability"
|
||||
},
|
||||
"ezTuneAggressiveness": {
|
||||
"message": "Aggressiveness"
|
||||
},
|
||||
"ezTuneRate": {
|
||||
"message": "Rate"
|
||||
},
|
||||
"ezTuneExpo": {
|
||||
"message": "Expo"
|
||||
},
|
||||
"ezTuneFilterHzTips": {
|
||||
"message": "This sets the base cutoff frequency for all INAV gyro and D-term filters. Higher values will result in lower filter delay and better stabilization, but more noise will go through the filters and motors will get hot, UAV might oscillate and be unfyable. Your goal is to increase this value as high as possible before any negative effects appear. Negative effects include: hot motors, audible osciallations, UAV rapidly shaking, UAV gaining altitude by itself. Usual starting points for 'Filter Hz' are: <strong>3-inch props</strong>: 90, <strong>5-inch props</strong>: 110, <strong>7-inch props</strong>: 90, <strong>10-inch props</strong>: 75, <strong>12-inch props</strong>: 60. Use Blackbox and common sense to find a value that is most suited for your UAV."
|
||||
},
|
||||
"ezTuneAxisRatioTips": {
|
||||
"message": "Describes the weight/moment of inertia distribution of your UAV. The longer the frame (more mass on the front-back axis) more Axis Ratio is requires. Perfect X frame is ratio 100. Most modern frames should fit somewhere between 110 and 130. Default 110 is a good starting point."
|
||||
},
|
||||
"ezTuneResponseTips": {
|
||||
"message": "This setting defines how fast the UAV will react to stick movements and gyro signal. Higher values will result in faster reaction, but also in more overshoots and oscillations. If UAV feels sluggish or has a slow wobble, increase the Response. If it has hot motors, audibly osciallates, overshoots or feels too nervous, decrease the Response. Most modern quads should beefy motors will fly best with Response below 80. Should be tuned together with Damping. It is a P-term equivalent."
|
||||
},
|
||||
"ezTuneDampingTips": {
|
||||
"message": "Describes the stengths of a force that opposes any rotation speed change. It dampens roll and pitch acceleration and causes smoother and more stable flight. Your task during tuning is to find out how much you can increase it before any negative symptoms appear: hot motors, audible osciallations, overshoot. Most modern quads should accept 'Damping' up to 150-180. It is a D-term equivalent."
|
||||
},
|
||||
"ezTuneStabilityTips": {
|
||||
"message": "Defines long-term stabilization strength. Most modern quads should tolerate 'Stability' even up to 120-130. Usually does not have to be tuned at all. If UAV suffers from heavy propwash during vertical descent, lowering 'Stability' might help. It is a I-term equivalent"
|
||||
},
|
||||
"ezTuneAggressivenessTips": {
|
||||
"message": "Defines how fast your UAV will react to fast stick movements. Higher 'Aggressiveness' results in snappier fast manouvers. It does not affect stabilization, only stick feeling. It is a FF-term equivalent."
|
||||
},
|
||||
"ezTuneRateTips": {
|
||||
"message": "Defines how fast your UAV will rotate around roll, pitch and yaw axis. Higher 'Rate' results in faster rotation. Value of 0 is the equivalent of 300dps, 100 is the equivalent of 600dps, 200 is the equivalent of 900dps."
|
||||
},
|
||||
"ezTuneExpoTips": {
|
||||
"message": "Defines expo of the RC input. Lower values result in more sensitive stick in the center. Higher values result in less sensitive center and more rapid response at the end of the stick. Value of 0 is the equivalent of 0 expo, 100 is the equivalent of 0.7 expo, 200 is the equivalent of 1.0 expo."
|
||||
},
|
||||
"ezTunePidPreview": {
|
||||
"message": "PID preview"
|
||||
},
|
||||
"ezTuneRatePreview": {
|
||||
"message": "Rate preview"
|
||||
},
|
||||
"ezTuneRatePreviewAxis" : {
|
||||
"message": "Axis"
|
||||
},
|
||||
"ezTuneRatePreviewRate" : {
|
||||
"message": "Rate"
|
||||
},
|
||||
"ezTuneRatePreviewExpo" : {
|
||||
"message": "Expo"
|
||||
},
|
||||
"ezTuneEnabledTips": {
|
||||
"message": "When enabled, <strong>Ez Tune</strong> will override multiple INAV setting to simplify the tuning process. Instead of setting each PID and filtering setting independently, you only have to work with 7 sliders. Ez Tune will automatically adjust all other settings to match your needs. Ez Tune is a great starting point for new users and a great way to quickly tune a new UAV. It is not recommended to use Ez Tune on advanced builds, as it will override all your settings and you will not be able to fine tune your UAV. When Ez Tune is enabled, settings from the <strong>PID tuning</strong> tab will be overriden by EzTune."
|
||||
},
|
||||
"ezTuneDisclaimer": {
|
||||
"message": "<strong>Disclaimer:</strong> Ez Tune is an experimental function. It is not guaranteed to work on all UAVs. It is not guaranteed to work with all frame types. It is not guaranteed to work with all propellers. All computations and tuning result can change in future versions of INAV. We still encourage you to check it out and share your experience on INAV Discord in the <strong>#ez-tune</strong> channel"
|
||||
},
|
||||
"ezTuneNote": {
|
||||
"message": "<strong>Important</strong> Ez Tune is enabled. All settings on this tab are set and controlled by the Ez Tune. To use PID Tuning tab you have to disable Ez Tune. To do it, uncheck the <strong>Enabled</strong> checkbox on the Ez Tune tab."
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,6 +7,7 @@ var minimist = require('minimist');
|
|||
|
||||
var archiver = require('archiver');
|
||||
var del = require('del');
|
||||
var NwBuilder = require('nw-builder');
|
||||
var semver = require('semver');
|
||||
|
||||
var gulp = require('gulp');
|
||||
|
@ -125,6 +126,7 @@ sources.js = [
|
|||
'./js/serial_queue.js',
|
||||
'./js/msp_balanced_interval.js',
|
||||
'./tabs/advanced_tuning.js',
|
||||
'./tabs/ez_tune.js',
|
||||
'./js/peripherals.js',
|
||||
'./js/appUpdater.js',
|
||||
'./js/feature_framework.js',
|
||||
|
@ -263,7 +265,6 @@ gulp.task('dist', gulp.series('clean', 'dist-build'));
|
|||
|
||||
// Create app directories in ./apps
|
||||
gulp.task('apps', gulp.series('dist', function(done) {
|
||||
var NwBuilder = require('nw-builder');
|
||||
var builder = new NwBuilder({
|
||||
files: './dist/**/*',
|
||||
buildDir: appsDir,
|
||||
|
|
|
@ -823,12 +823,6 @@ helper.defaultsDialog = (function () {
|
|||
value: 25
|
||||
},
|
||||
],
|
||||
"features": [
|
||||
{
|
||||
bit: 4, // Enable MOTOR_STOP
|
||||
state: true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": 'Airplane without a Tail (Wing, Delta, etc)',
|
||||
|
@ -1042,12 +1036,6 @@ helper.defaultsDialog = (function () {
|
|||
value: 25
|
||||
},
|
||||
],
|
||||
"features": [
|
||||
{
|
||||
bit: 4, // Enable MOTOR_STOP
|
||||
state: true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": 'Rovers & Boats',
|
||||
|
@ -1205,6 +1193,7 @@ helper.defaultsDialog = (function () {
|
|||
|
||||
MIXER_CONFIG.platformType = currentMixerPreset.platform;
|
||||
MIXER_CONFIG.appliedMixerPreset = selectedDefaultPreset.mixerToApply;
|
||||
MIXER_CONFIG.motorStopOnLow = (currentMixerPreset.motorStopOnLow === true) ? true : false;
|
||||
MIXER_CONFIG.hasFlaps = (currentMixerPreset.hasFlaps === true) ? true : false;
|
||||
|
||||
SERVO_RULES.cleanup();
|
||||
|
|
35
js/fc.js
|
@ -64,7 +64,8 @@ var CONFIG,
|
|||
SAFEHOMES,
|
||||
BOARD_ALIGNMENT,
|
||||
CURRENT_METER_CONFIG,
|
||||
FEATURES;
|
||||
FEATURES,
|
||||
RATE_DYNAMICS;
|
||||
|
||||
var FC = {
|
||||
restartRequired: false,
|
||||
|
@ -117,6 +118,7 @@ var FC = {
|
|||
i2cError: 0,
|
||||
activeSensors: 0,
|
||||
mode: [],
|
||||
mixer_profile: 0,
|
||||
profile: 0,
|
||||
battery_profile: 0,
|
||||
uid: [0, 0, 0],
|
||||
|
@ -195,6 +197,7 @@ var FC = {
|
|||
MIXER_CONFIG = {
|
||||
yawMotorDirection: 0,
|
||||
yawJumpPreventionLimit: 0,
|
||||
motorStopOnLow: false,
|
||||
platformType: -1,
|
||||
hasFlaps: false,
|
||||
appliedMixerPreset: -1,
|
||||
|
@ -540,6 +543,27 @@ var FC = {
|
|||
SETTINGS = {};
|
||||
|
||||
SAFEHOMES = new SafehomeCollection();
|
||||
|
||||
RATE_DYNAMICS = {
|
||||
sensitivityCenter: null,
|
||||
sensitivityEnd: null,
|
||||
correctionCenter: null,
|
||||
correctionEnd: null,
|
||||
weightCenter: null,
|
||||
weightEnd: null
|
||||
};
|
||||
|
||||
EZ_TUNE = {
|
||||
enabled: null,
|
||||
filterHz: null,
|
||||
axisRatio: null,
|
||||
response: null,
|
||||
damping: null,
|
||||
stability: null,
|
||||
aggressiveness: null,
|
||||
rate: null,
|
||||
expo: null
|
||||
};
|
||||
},
|
||||
getOutputUsages: function() {
|
||||
return {
|
||||
|
@ -554,7 +578,6 @@ var FC = {
|
|||
getFeatures: function () {
|
||||
var features = [
|
||||
{bit: 1, group: 'batteryVoltage', name: 'VBAT'},
|
||||
{bit: 4, group: 'other', name: 'MOTOR_STOP'},
|
||||
{bit: 6, group: 'other', name: 'SOFTSERIAL', haveTip: true, showNameInTip: true},
|
||||
{bit: 7, group: 'other', name: 'GPS', haveTip: true},
|
||||
{bit: 10, group: 'other', name: 'TELEMETRY', showNameInTip: true},
|
||||
|
@ -593,7 +616,6 @@ var FC = {
|
|||
},
|
||||
getGpsProtocols: function () {
|
||||
return [
|
||||
'NMEA',
|
||||
'UBLOX',
|
||||
'UBLOX7',
|
||||
'MSP',
|
||||
|
@ -616,6 +638,7 @@ var FC = {
|
|||
'North American WAAS',
|
||||
'Japanese MSAS',
|
||||
'Indian GAGAN',
|
||||
'SouthPAN (AU/NZ)',
|
||||
'Disabled'
|
||||
];
|
||||
},
|
||||
|
@ -880,6 +903,7 @@ var FC = {
|
|||
'GVAR 5', // 35
|
||||
'GVAR 6', // 36
|
||||
'GVAR 7', // 37
|
||||
'Mixer Transition', // 38
|
||||
];
|
||||
},
|
||||
getServoMixInputName: function (input) {
|
||||
|
@ -1269,11 +1293,14 @@ var FC = {
|
|||
30: "CRSF SNR",
|
||||
31: "GPS Valid Fix",
|
||||
32: "Loiter Radius [cm]",
|
||||
33: "Active Profile",
|
||||
33: "Active PIDProfile",
|
||||
34: "Battery cells",
|
||||
35: "AGL status [0/1]",
|
||||
36: "AGL [cm]",
|
||||
37: "Rangefinder [cm]",
|
||||
38: "Active MixerProfile",
|
||||
39: "MixerTransition Active",
|
||||
40: "Yaw [deg]"
|
||||
}
|
||||
},
|
||||
3: {
|
||||
|
|
101
js/gui.js
|
@ -41,7 +41,8 @@ var GUI_control = function () {
|
|||
'advanced_tuning',
|
||||
'mission_control',
|
||||
'mixer',
|
||||
'programming'
|
||||
'programming',
|
||||
'ez_tune'
|
||||
];
|
||||
this.allowedTabs = this.defaultAllowedTabsWhenDisconnected;
|
||||
|
||||
|
@ -52,6 +53,17 @@ var GUI_control = function () {
|
|||
else if (navigator.appVersion.indexOf("Linux") != -1) this.operating_system = "Linux";
|
||||
else if (navigator.appVersion.indexOf("X11") != -1) this.operating_system = "UNIX";
|
||||
else this.operating_system = "Unknown";
|
||||
|
||||
this.colorTable = [
|
||||
"#8ecae6",
|
||||
"#2a9d8f",
|
||||
"#e9c46a",
|
||||
"#f4a261",
|
||||
"#e76f51",
|
||||
"#ef476f",
|
||||
"#ffc300"
|
||||
];
|
||||
|
||||
};
|
||||
|
||||
// message = string
|
||||
|
@ -249,6 +261,7 @@ GUI_control.prototype.updateStatusBar = function() {
|
|||
};
|
||||
|
||||
GUI_control.prototype.updateProfileChange = function() {
|
||||
$('#mixerprofilechange').val(CONFIG.mixer_profile);
|
||||
$('#profilechange').val(CONFIG.profile);
|
||||
$('#batteryprofilechange').val(CONFIG.battery_profile);
|
||||
};
|
||||
|
@ -383,5 +396,91 @@ GUI_control.prototype.renderLogicConditionSelect = function ($container, logicCo
|
|||
$select.val(current).change(onChange);
|
||||
}
|
||||
|
||||
GUI_control.prototype.sliderize = function ($input, value, min, max) {
|
||||
let scaledMax;
|
||||
let scaledMin;
|
||||
let scalingThreshold;
|
||||
|
||||
if ($input.data('normal-max')) {
|
||||
scaledMax = max * 2;
|
||||
scalingThreshold = Math.round(scaledMax * 0.8);
|
||||
scaledMin = min *2;
|
||||
} else {
|
||||
scaledMax = max;
|
||||
scaledMin = min;
|
||||
scalingThreshold = scaledMax;
|
||||
}
|
||||
|
||||
let $range = $('<input type="range" min="' + scaledMin + '" max="' + scaledMax + '" value="' + value + '"/>');
|
||||
if ($input.data('step')) {
|
||||
$range.attr('step', $input.data('step'));
|
||||
}
|
||||
$range.css({
|
||||
'display': 'block',
|
||||
'flex-grow': 100,
|
||||
'margin-left': '1em',
|
||||
'margin-right': '1em',
|
||||
});
|
||||
|
||||
$input.attr('min', min);
|
||||
$input.attr('max', max);
|
||||
$input.val(parseInt(value));
|
||||
$input.css({
|
||||
'width': 'auto',
|
||||
'min-width': '75px',
|
||||
});
|
||||
|
||||
$input.parent().css({
|
||||
'display': 'flex',
|
||||
'width': '100%'
|
||||
});
|
||||
$range.insertAfter($input);
|
||||
|
||||
$input.parent().find('.helpicon').css({
|
||||
'top': '5px',
|
||||
'left': '-10px'
|
||||
});
|
||||
|
||||
/*
|
||||
* Update slider to input
|
||||
*/
|
||||
$range.on('input', function() {
|
||||
let val = $(this).val();
|
||||
let normalMax = parseInt($input.data('normal-max'));
|
||||
|
||||
if (normalMax) {
|
||||
if (val <= scalingThreshold) {
|
||||
val = scaleRangeInt(val, scaledMin, scalingThreshold, min, normalMax);
|
||||
} else {
|
||||
val = scaleRangeInt(val, scalingThreshold + 1, scaledMax, normalMax + 1, max);
|
||||
}
|
||||
}
|
||||
|
||||
$input.val(val);
|
||||
$input.trigger('updated');
|
||||
});
|
||||
|
||||
$input.on('change', function() {
|
||||
|
||||
let val = $(this).val();
|
||||
let newVal;
|
||||
let normalMax = parseInt($input.data('normal-max'));
|
||||
if (normalMax) {
|
||||
if (val <= normalMax) {
|
||||
newVal = scaleRangeInt(val, min, normalMax, scaledMin, scalingThreshold);
|
||||
} else {
|
||||
newVal = scaleRangeInt(val, normalMax + 1, max, scalingThreshold + 1, scaledMax);
|
||||
}
|
||||
} else {
|
||||
newVal = val;
|
||||
}
|
||||
|
||||
$range.val(newVal);
|
||||
$input.trigger('updated');
|
||||
});
|
||||
|
||||
$input.trigger('change');
|
||||
};
|
||||
|
||||
// initialize object into GUI variable
|
||||
var GUI = new GUI_control();
|
||||
|
|
|
@ -350,6 +350,7 @@ const mixerList = [
|
|||
enabled: true,
|
||||
legacy: true,
|
||||
platform: PLATFORM_AIRPLANE,
|
||||
motorStopOnLow: true,
|
||||
motorMixer: [
|
||||
new MotorMixRule(1.0, 0.0, 0.0, 0.0),
|
||||
],
|
||||
|
@ -373,6 +374,7 @@ const mixerList = [
|
|||
enabled: true,
|
||||
legacy: false,
|
||||
platform: PLATFORM_AIRPLANE,
|
||||
motorStopOnLow: true,
|
||||
motorMixer: [
|
||||
new MotorMixRule(1.0, 0.0, 0.0, 0.1),
|
||||
new MotorMixRule(1.0, 0.0, 0.0, -0.1)
|
||||
|
@ -399,6 +401,7 @@ const mixerList = [
|
|||
enabled: true,
|
||||
legacy: true,
|
||||
platform: PLATFORM_AIRPLANE,
|
||||
motorStopOnLow: true,
|
||||
hasFlaps: true,
|
||||
motorMixer: [
|
||||
new MotorMixRule(1.0, 0.0, 0.0, 0.0),
|
||||
|
@ -427,6 +430,7 @@ const mixerList = [
|
|||
enabled: true,
|
||||
legacy: false,
|
||||
platform: PLATFORM_AIRPLANE,
|
||||
motorStopOnLow: true,
|
||||
hasFlaps: true,
|
||||
motorMixer: [
|
||||
new MotorMixRule(1.0, 0.0, 0.0, 0.3),
|
||||
|
@ -456,6 +460,7 @@ const mixerList = [
|
|||
enabled: true,
|
||||
legacy: false,
|
||||
platform: PLATFORM_AIRPLANE,
|
||||
motorStopOnLow: true,
|
||||
hasFlaps: true,
|
||||
motorMixer: [
|
||||
new MotorMixRule(1.0, 0.0, 0.0, 0.0),
|
||||
|
@ -486,6 +491,7 @@ const mixerList = [
|
|||
enabled: true,
|
||||
legacy: false,
|
||||
platform: PLATFORM_AIRPLANE,
|
||||
motorStopOnLow: true,
|
||||
hasFlaps: true,
|
||||
motorMixer: [
|
||||
new MotorMixRule(1.0, 0.0, 0.0, 0.3),
|
||||
|
@ -516,6 +522,7 @@ const mixerList = [
|
|||
enabled: true,
|
||||
legacy: false,
|
||||
platform: PLATFORM_AIRPLANE,
|
||||
motorStopOnLow: true,
|
||||
motorMixer: [
|
||||
new MotorMixRule(1.0, 0.0, 0.0, 0.0),
|
||||
],
|
||||
|
@ -542,6 +549,7 @@ const mixerList = [
|
|||
legacy: false,
|
||||
platform: PLATFORM_AIRPLANE,
|
||||
hasFlaps: true,
|
||||
motorStopOnLow: true,
|
||||
motorMixer: [
|
||||
new MotorMixRule(1.0, 0.0, 0.0, 0.0),
|
||||
],
|
||||
|
@ -568,6 +576,7 @@ const mixerList = [
|
|||
enabled: false,
|
||||
legacy: true,
|
||||
platform: PLATFORM_AIRPLANE,
|
||||
motorStopOnLow: true,
|
||||
motorMixer: [],
|
||||
servoMixer: []
|
||||
}, // 24
|
||||
|
|
|
@ -6,7 +6,7 @@ var MotorMixRule = function (throttle, roll, pitch, yaw) {
|
|||
var self = {};
|
||||
|
||||
self.fromMsp = function (mspThrottle, mspRoll, mspPitch, mspYaw) {
|
||||
throttle = mspThrottle / 1000;
|
||||
throttle = Math.round(((mspThrottle / 1000) - 2) * 1000) / 1000;
|
||||
roll = Math.round(((mspRoll / 1000) - 2) * 1000) / 1000;
|
||||
pitch = Math.round(((mspPitch / 1000) - 2) * 1000) / 1000;
|
||||
yaw = Math.round(((mspYaw / 1000) - 2) * 1000) / 1000;
|
||||
|
@ -17,11 +17,11 @@ var MotorMixRule = function (throttle, roll, pitch, yaw) {
|
|||
};
|
||||
|
||||
self.getThrottle = function () {
|
||||
return constrain(parseFloat(throttle, 10), 0, 1);
|
||||
return constrain(parseFloat(throttle, 10), -2, 2);
|
||||
};
|
||||
|
||||
self.getThrottleForMsp = function () {
|
||||
return self.getThrottle() * 1000;
|
||||
return (self.getThrottle()+2) * 1000;
|
||||
};
|
||||
|
||||
self.setThrottle = function (data) {
|
||||
|
|
|
@ -5,6 +5,7 @@ var MotorMixerRuleCollection = function () {
|
|||
|
||||
let self = {},
|
||||
data = [],
|
||||
inactiveData = [],
|
||||
maxMotorCount = 8;
|
||||
|
||||
self.setMotorCount = function (value) {
|
||||
|
@ -16,7 +17,11 @@ var MotorMixerRuleCollection = function () {
|
|||
};
|
||||
|
||||
self.put = function (element) {
|
||||
data.push(element);
|
||||
if (data.length < self.getMotorCount()){
|
||||
data.push(element);
|
||||
}else{
|
||||
inactiveData.push(element); //store the data for mixer_profile 2
|
||||
}
|
||||
};
|
||||
|
||||
self.get = function () {
|
||||
|
@ -30,18 +35,25 @@ var MotorMixerRuleCollection = function () {
|
|||
|
||||
self.flush = function () {
|
||||
data = [];
|
||||
inactiveData = [];
|
||||
};
|
||||
|
||||
self.cleanup = function () {
|
||||
var tmpData = [];
|
||||
var tmpInactiveData = [];
|
||||
|
||||
data.forEach(function (element) {
|
||||
if (element.isUsed()) {
|
||||
tmpData.push(element);
|
||||
}
|
||||
});
|
||||
|
||||
inactiveData.forEach(function (element) {
|
||||
if (element.isUsed()) {
|
||||
tmpInactiveData.push(element);
|
||||
}
|
||||
});
|
||||
data = tmpData;
|
||||
inactiveData = tmpInactiveData;
|
||||
};
|
||||
|
||||
self.inflate = function () {
|
||||
|
@ -55,7 +67,7 @@ var MotorMixerRuleCollection = function () {
|
|||
};
|
||||
|
||||
self.getNumberOfConfiguredMotors = function () {
|
||||
return data.length;
|
||||
return data.length > inactiveData.length ? data.length : inactiveData.length;
|
||||
};
|
||||
|
||||
return self;
|
||||
|
|
|
@ -180,6 +180,11 @@ var MSPCodes = {
|
|||
MSPV2_INAV_SET_RATE_PROFILE: 0x2008,
|
||||
MSPV2_INAV_AIR_SPEED: 0x2009,
|
||||
MSPV2_INAV_OUTPUT_MAPPING: 0x200A,
|
||||
MSP2_INAV_MC_BRAKING: 0x200B,
|
||||
MSP2_INAV_SET_MC_BRAKING: 0x200C,
|
||||
MSPV2_INAV_OUTPUT_MAPPING_EXT: 0x200D,
|
||||
MSP2_INAV_TIMER_OUTPUT_MODE: 0x200E,
|
||||
MSP2_INAV_SET_TIMER_OUTPUT_MODE: 0x200F,
|
||||
|
||||
MSP2_INAV_MIXER: 0x2010,
|
||||
MSP2_INAV_SET_MIXER: 0x2011,
|
||||
|
@ -191,9 +196,6 @@ var MSPCodes = {
|
|||
MSP2_INAV_OSD_PREFERENCES: 0x2016,
|
||||
MSP2_INAV_OSD_SET_PREFERENCES: 0x2017,
|
||||
|
||||
MSP2_INAV_MC_BRAKING: 0x200B,
|
||||
MSP2_INAV_SET_MC_BRAKING: 0x200C,
|
||||
|
||||
MSP2_INAV_SELECT_BATTERY_PROFILE: 0x2018,
|
||||
|
||||
MSP2_INAV_DEBUG: 0x2019,
|
||||
|
@ -217,6 +219,7 @@ var MSPCodes = {
|
|||
MSP2_INAV_SET_PROGRAMMING_PID: 0x2029,
|
||||
MSP2_INAV_PROGRAMMING_PID_STATUS: 0x202A,
|
||||
|
||||
|
||||
MSP2_PID: 0x2030,
|
||||
MSP2_SET_PID: 0x2031,
|
||||
|
||||
|
@ -234,5 +237,13 @@ var MSPCodes = {
|
|||
MSP2_INAV_LOGIC_CONDITIONS_SINGLE: 0x203B,
|
||||
|
||||
MSP2_INAV_LED_STRIP_CONFIG_EX: 0x2048,
|
||||
MSP2_INAV_SET_LED_STRIP_CONFIG_EX: 0x2049
|
||||
MSP2_INAV_SET_LED_STRIP_CONFIG_EX: 0x2049,
|
||||
|
||||
MSP2_INAV_RATE_DYNAMICS: 0x2060,
|
||||
MSP2_INAV_SET_RATE_DYNAMICS: 0x2061,
|
||||
|
||||
MSP2_INAV_EZ_TUNE: 0x2070,
|
||||
MSP2_INAV_EZ_TUNE_SET: 0x2071,
|
||||
|
||||
MSP2_INAV_SELECT_MIXER_PROFILE: 0x2080
|
||||
};
|
||||
|
|
|
@ -79,6 +79,8 @@ var mspHelper = (function (gui) {
|
|||
profile_byte = data.getUint8(offset++)
|
||||
CONFIG.profile = profile_byte & 0x0F;
|
||||
CONFIG.battery_profile = (profile_byte & 0xF0) >> 4;
|
||||
profile_byte = data.getUint8(offset++)
|
||||
CONFIG.mixer_profile = profile_byte & 0x0F;
|
||||
CONFIG.armingFlags = data.getUint32(offset, true);
|
||||
offset += 4;
|
||||
gui.updateStatusBar();
|
||||
|
@ -1453,7 +1455,8 @@ var mspHelper = (function (gui) {
|
|||
break;
|
||||
case MSPCodes.MSP2_INAV_MIXER:
|
||||
MIXER_CONFIG.yawMotorDirection = data.getInt8(0);
|
||||
MIXER_CONFIG.yawJumpPreventionLimit = data.getUint16(1, true);
|
||||
MIXER_CONFIG.yawJumpPreventionLimit = data.getUint8(1, true);
|
||||
MIXER_CONFIG.motorStopOnLow = data.getUint8(1, true);
|
||||
MIXER_CONFIG.platformType = data.getInt8(3);
|
||||
MIXER_CONFIG.hasFlaps = data.getInt8(4);
|
||||
MIXER_CONFIG.appliedMixerPreset = data.getInt16(5, true);
|
||||
|
@ -1482,7 +1485,32 @@ var mspHelper = (function (gui) {
|
|||
case MSPCodes.MSPV2_INAV_OUTPUT_MAPPING:
|
||||
OUTPUT_MAPPING.flush();
|
||||
for (i = 0; i < data.byteLength; ++i)
|
||||
OUTPUT_MAPPING.put(data.getUint8(i));
|
||||
OUTPUT_MAPPING.put({
|
||||
'timerId': i,
|
||||
'usageFlags': data.getUint8(i)});
|
||||
break;
|
||||
case MSPCodes.MSPV2_INAV_OUTPUT_MAPPING_EXT:
|
||||
OUTPUT_MAPPING.flush();
|
||||
for (i = 0; i < data.byteLength; i += 2) {
|
||||
timerId = data.getUint8(i);
|
||||
usageFlags = data.getUint8(i + 1);
|
||||
OUTPUT_MAPPING.put(
|
||||
{
|
||||
'timerId': timerId,
|
||||
'usageFlags': usageFlags
|
||||
});
|
||||
}
|
||||
break;
|
||||
|
||||
case MSPCodes.MSP2_INAV_TIMER_OUTPUT_MODE:
|
||||
if(data.byteLength > 2) {
|
||||
OUTPUT_MAPPING.flushTimerOverrides();
|
||||
}
|
||||
for (i = 0; i < data.byteLength; i += 2) {
|
||||
timerId = data.getUint8(i);
|
||||
outputMode = data.getUint8(i + 1);
|
||||
OUTPUT_MAPPING.setTimerOverride(timerId, outputMode);
|
||||
}
|
||||
break;
|
||||
|
||||
case MSPCodes.MSP2_INAV_MC_BRAKING:
|
||||
|
@ -1532,6 +1560,35 @@ var mspHelper = (function (gui) {
|
|||
console.log('Safehome points saved');
|
||||
break;
|
||||
|
||||
case MSPCodes.MSP2_INAV_RATE_DYNAMICS:
|
||||
RATE_DYNAMICS.sensitivityCenter = data.getUint8(0);
|
||||
RATE_DYNAMICS.sensitivityEnd = data.getUint8(1);
|
||||
RATE_DYNAMICS.correctionCenter = data.getUint8(2);
|
||||
RATE_DYNAMICS.correctionEnd = data.getUint8(3);
|
||||
RATE_DYNAMICS.weightCenter = data.getUint8(4);
|
||||
RATE_DYNAMICS.weightEnd = data.getUint8(5);
|
||||
break;
|
||||
|
||||
case MSPCodes.MSP2_INAV_SET_RATE_DYNAMICS:
|
||||
console.log('Rate dynamics saved');
|
||||
break;
|
||||
|
||||
case MSPCodes.MSP2_INAV_EZ_TUNE:
|
||||
EZ_TUNE.enabled = data.getUint8(0);
|
||||
EZ_TUNE.filterHz = data.getUint16(1, true);
|
||||
EZ_TUNE.axisRatio = data.getUint8(3);
|
||||
EZ_TUNE.response = data.getUint8(4);
|
||||
EZ_TUNE.damping = data.getUint8(5);
|
||||
EZ_TUNE.stability = data.getUint8(6);
|
||||
EZ_TUNE.aggressiveness = data.getUint8(7);
|
||||
EZ_TUNE.rate = data.getUint8(8);
|
||||
EZ_TUNE.expo = data.getUint8(9);
|
||||
break;
|
||||
|
||||
case MSPCodes.MSP2_INAV_EZ_TUNE_SET:
|
||||
console.log('EzTune settings saved');
|
||||
break;
|
||||
|
||||
default:
|
||||
console.log('Unknown code detected: ' + dataHandler.code);
|
||||
} else {
|
||||
|
@ -2129,8 +2186,8 @@ var mspHelper = (function (gui) {
|
|||
|
||||
case MSPCodes.MSP2_INAV_SET_MIXER:
|
||||
buffer.push(MIXER_CONFIG.yawMotorDirection);
|
||||
buffer.push(lowByte(MIXER_CONFIG.yawJumpPreventionLimit));
|
||||
buffer.push(highByte(MIXER_CONFIG.yawJumpPreventionLimit));
|
||||
buffer.push(MIXER_CONFIG.yawJumpPreventionLimit);
|
||||
buffer.push(MIXER_CONFIG.motorStopOnLow);
|
||||
buffer.push(MIXER_CONFIG.platformType);
|
||||
buffer.push(MIXER_CONFIG.hasFlaps);
|
||||
buffer.push(lowByte(MIXER_CONFIG.appliedMixerPreset));
|
||||
|
@ -2159,6 +2216,31 @@ var mspHelper = (function (gui) {
|
|||
buffer.push(BRAKING_CONFIG.bankAngle);
|
||||
break;
|
||||
|
||||
case MSPCodes.MSP2_INAV_SET_RATE_DYNAMICS:
|
||||
buffer.push(RATE_DYNAMICS.sensitivityCenter);
|
||||
buffer.push(RATE_DYNAMICS.sensitivityEnd);
|
||||
buffer.push(RATE_DYNAMICS.correctionCenter);
|
||||
buffer.push(RATE_DYNAMICS.correctionEnd);
|
||||
buffer.push(RATE_DYNAMICS.weightCenter);
|
||||
buffer.push(RATE_DYNAMICS.weightEnd);
|
||||
break;
|
||||
|
||||
case MSPCodes.MSP2_INAV_EZ_TUNE_SET:
|
||||
|
||||
buffer.push(EZ_TUNE.enabled);
|
||||
buffer.push(lowByte(EZ_TUNE.filterHz));
|
||||
buffer.push(highByte(EZ_TUNE.filterHz));
|
||||
buffer.push(EZ_TUNE.axisRatio);
|
||||
buffer.push(EZ_TUNE.response);
|
||||
buffer.push(EZ_TUNE.damping);
|
||||
buffer.push(EZ_TUNE.stability);
|
||||
buffer.push(EZ_TUNE.aggressiveness);
|
||||
buffer.push(EZ_TUNE.rate);
|
||||
buffer.push(EZ_TUNE.expo);
|
||||
console.log(buffer);
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
@ -2820,6 +2902,47 @@ var mspHelper = (function (gui) {
|
|||
MSP.send_message(MSPCodes.MSPV2_INAV_OUTPUT_MAPPING, false, false, callback);
|
||||
};
|
||||
|
||||
self.loadOutputMappingExt = function (callback) {
|
||||
MSP.send_message(MSPCodes.MSPV2_INAV_OUTPUT_MAPPING_EXT, false, false, callback);
|
||||
};
|
||||
|
||||
self.loadTimerOutputModes = function(callback) {
|
||||
MSP.send_message(MSPCodes.MSP2_INAV_TIMER_OUTPUT_MODE, false, false, callback);
|
||||
}
|
||||
|
||||
self.sendTimerOutputModes = function(callback) {
|
||||
var nextFunction = send_next_output_mode;
|
||||
var idIndex = 0;
|
||||
|
||||
var overrideIds = OUTPUT_MAPPING.getUsedTimerIds();
|
||||
|
||||
if (overrideIds.length == 0) {
|
||||
onCompleteCallback();
|
||||
} else {
|
||||
send_next_output_mode();
|
||||
}
|
||||
|
||||
function send_next_output_mode() {
|
||||
|
||||
var timerId = overrideIds[idIndex];
|
||||
|
||||
var outputMode = OUTPUT_MAPPING.getTimerOverride(timerId);
|
||||
|
||||
var buffer = [];
|
||||
buffer.push(timerId);
|
||||
buffer.push(outputMode);
|
||||
|
||||
// prepare for next iteration
|
||||
idIndex++;
|
||||
if (idIndex == overrideIds.length) {
|
||||
nextFunction = callback;
|
||||
|
||||
}
|
||||
MSP.send_message(MSPCodes.MSP2_INAV_SET_TIMER_OUTPUT_MODE, buffer, false, nextFunction);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
self.loadBatteryConfig = function (callback) {
|
||||
MSP.send_message(MSPCodes.MSPV2_BATTERY_CONFIG, false, false, callback);
|
||||
};
|
||||
|
@ -3312,6 +3435,22 @@ var mspHelper = (function (gui) {
|
|||
MSP.send_message(MSPCodes.MSP2_INAV_SET_MC_BRAKING, mspHelper.crunch(MSPCodes.MSP2_INAV_SET_MC_BRAKING), false, callback);
|
||||
};
|
||||
|
||||
self.loadRateDynamics = function (callback) {
|
||||
MSP.send_message(MSPCodes.MSP2_INAV_RATE_DYNAMICS, false, false, callback);
|
||||
}
|
||||
|
||||
self.saveRateDynamics = function (callback) {
|
||||
MSP.send_message(MSPCodes.MSP2_INAV_SET_RATE_DYNAMICS, mspHelper.crunch(MSPCodes.MSP2_INAV_SET_RATE_DYNAMICS), false, callback);
|
||||
}
|
||||
|
||||
self.loadEzTune = function (callback) {
|
||||
MSP.send_message(MSPCodes.MSP2_INAV_EZ_TUNE, false, false, callback);
|
||||
}
|
||||
|
||||
self.saveEzTune = function (callback) {
|
||||
MSP.send_message(MSPCodes.MSP2_INAV_EZ_TUNE_SET, mspHelper.crunch(MSPCodes.MSP2_INAV_EZ_TUNE_SET), false, callback);
|
||||
}
|
||||
|
||||
self.loadParameterGroups = function (callback) {
|
||||
MSP.send_message(MSPCodes.MSP2_COMMON_PG_LIST, false, false, function (resp) {
|
||||
var groups = [];
|
||||
|
|
|
@ -3,22 +3,63 @@
|
|||
|
||||
let OutputMappingCollection = function () {
|
||||
let self = {},
|
||||
data = [];
|
||||
data = [],
|
||||
timerOverrides = {};
|
||||
|
||||
const TIM_USE_ANY = 0;
|
||||
const TIM_USE_PPM = 0;
|
||||
const TIM_USE_PWM = 1;
|
||||
const TIM_USE_MC_MOTOR = 2; // Multicopter motor output
|
||||
const TIM_USE_MC_SERVO = 3; // Multicopter servo output (i.e. TRI)
|
||||
const TIM_USE_MC_CHNFW = 4; // Deprecated and not used after removal of CHANNEL_FORWARDING feature
|
||||
const TIM_USE_FW_MOTOR = 5;
|
||||
const TIM_USE_FW_SERVO = 6;
|
||||
const TIM_USE_MOTOR = 2; // Motor output
|
||||
const TIM_USE_SERVO = 3; // Servo output (i.e. TRI)
|
||||
//const TIM_USE_MC_CHNFW = 4; // Deprecated and not used after removal of CHANNEL_FORWARDING feature
|
||||
//const TIM_USE_FW_MOTOR = 5;
|
||||
//const TIM_USE_FW_SERVO = 6;
|
||||
const TIM_USE_LED = 24;
|
||||
const TIM_USE_BEEPER = 25;
|
||||
|
||||
const OUTPUT_TYPE_MOTOR = 0;
|
||||
const OUTPUT_TYPE_SERVO = 1;
|
||||
|
||||
self.TIMER_OUTPUT_MODE_AUTO = 0;
|
||||
self.TIMER_OUTPUT_MODE_MOTORS = 1;
|
||||
self.TIMER_OUTPUT_MODE_SERVOS = 2;
|
||||
|
||||
self.flushTimerOverrides = function() {
|
||||
timerOverrides = {};
|
||||
}
|
||||
|
||||
self.setTimerOverride = function (timer, outputMode) {
|
||||
timerOverrides[timer] = outputMode;
|
||||
}
|
||||
|
||||
self.getTimerOverride = function (timer) {
|
||||
return timerOverrides[timer];
|
||||
}
|
||||
|
||||
self.getTimerColor = function (timer) {
|
||||
let timerIndex = OUTPUT_MAPPING.getUsedTimerIds().indexOf(String(timer));
|
||||
|
||||
return GUI.colorTable[timerIndex % GUI.colorTable.length];
|
||||
}
|
||||
|
||||
self.getOutputTimerColor = function (output) {
|
||||
let timerId = OUTPUT_MAPPING.getTimerId(output);
|
||||
|
||||
return self.getTimerColor(timerId);
|
||||
}
|
||||
|
||||
self.getUsedTimerIds = function (timer) {
|
||||
let used = {};
|
||||
let outputCount = self.getOutputCount();
|
||||
|
||||
for (let i = 0; i < outputCount; ++i) {
|
||||
let timerId = self.getTimerId(i);
|
||||
used[timerId] = 1;
|
||||
}
|
||||
|
||||
return Object.keys(used).sort((a, b) => a - b);
|
||||
}
|
||||
|
||||
function getTimerMap(isMR, motors, servos) {
|
||||
let timerMap = [],
|
||||
motorsToGo = motors,
|
||||
|
@ -27,24 +68,13 @@ let OutputMappingCollection = function () {
|
|||
for (let i = 0; i < data.length; i++) {
|
||||
timerMap[i] = null;
|
||||
|
||||
if (isMR) {
|
||||
if (servosToGo > 0 && bit_check(data[i], TIM_USE_MC_SERVO)) {
|
||||
servosToGo--;
|
||||
timerMap[i] = OUTPUT_TYPE_SERVO;
|
||||
} else if (motorsToGo > 0 && bit_check(data[i], TIM_USE_MC_MOTOR)) {
|
||||
motorsToGo--;
|
||||
timerMap[i] = OUTPUT_TYPE_MOTOR;
|
||||
}
|
||||
} else {
|
||||
if (servosToGo > 0 && bit_check(data[i], TIM_USE_FW_SERVO)) {
|
||||
servosToGo--;
|
||||
timerMap[i] = OUTPUT_TYPE_SERVO;
|
||||
} else if (motorsToGo > 0 && bit_check(data[i], TIM_USE_FW_MOTOR)) {
|
||||
motorsToGo--;
|
||||
timerMap[i] = OUTPUT_TYPE_MOTOR;
|
||||
}
|
||||
if (servosToGo > 0 && bit_check(data[i]['usageFlags'], TIM_USE_SERVO)) {
|
||||
servosToGo--;
|
||||
timerMap[i] = OUTPUT_TYPE_SERVO;
|
||||
} else if (motorsToGo > 0 && bit_check(data[i]['usageFlags'], TIM_USE_MOTOR)) {
|
||||
motorsToGo--;
|
||||
timerMap[i] = OUTPUT_TYPE_MOTOR;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return timerMap;
|
||||
|
@ -70,7 +100,6 @@ let OutputMappingCollection = function () {
|
|||
outputMap[i] = "Servo " + servos[currentServoIndex];
|
||||
currentServoIndex++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return outputMap;
|
||||
|
@ -89,10 +118,8 @@ let OutputMappingCollection = function () {
|
|||
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
if (
|
||||
bit_check(data[i], TIM_USE_MC_MOTOR) ||
|
||||
bit_check(data[i], TIM_USE_MC_SERVO) ||
|
||||
bit_check(data[i], TIM_USE_FW_MOTOR) ||
|
||||
bit_check(data[i], TIM_USE_FW_SERVO)
|
||||
bit_check(data[i]['usageFlags'], TIM_USE_MOTOR) ||
|
||||
bit_check(data[i]['usageFlags'], TIM_USE_SERVO)
|
||||
) {
|
||||
retVal++;
|
||||
};
|
||||
|
@ -104,10 +131,8 @@ let OutputMappingCollection = function () {
|
|||
function getFirstOutputOffset() {
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
if (
|
||||
bit_check(data[i], TIM_USE_MC_MOTOR) ||
|
||||
bit_check(data[i], TIM_USE_MC_SERVO) ||
|
||||
bit_check(data[i], TIM_USE_FW_MOTOR) ||
|
||||
bit_check(data[i], TIM_USE_FW_SERVO)
|
||||
bit_check(data[i]['usageFlags'], TIM_USE_MOTOR) ||
|
||||
bit_check(data[i]['usageFlags'], TIM_USE_SERVO)
|
||||
) {
|
||||
return i;
|
||||
}
|
||||
|
@ -115,6 +140,10 @@ let OutputMappingCollection = function () {
|
|||
return 0;
|
||||
}
|
||||
|
||||
function getTimerId(outputIndex) {
|
||||
return data[outputIndex]['timerId'];
|
||||
}
|
||||
|
||||
function getOutput(servoIndex, bit) {
|
||||
|
||||
let offset = getFirstOutputOffset();
|
||||
|
@ -122,7 +151,7 @@ let OutputMappingCollection = function () {
|
|||
let lastFound = 0;
|
||||
|
||||
for (let i = offset; i < data.length; i++) {
|
||||
if (bit_check(data[i], bit)) {
|
||||
if (bit_check(data[i]['usageFlags'], bit)) {
|
||||
if (lastFound == servoIndex) {
|
||||
return i - offset + 1;
|
||||
} else {
|
||||
|
@ -134,12 +163,16 @@ let OutputMappingCollection = function () {
|
|||
return null;
|
||||
}
|
||||
|
||||
self.getTimerId = function(outputIndex) {
|
||||
return getTimerId(outputIndex)
|
||||
}
|
||||
|
||||
self.getFwServoOutput = function (servoIndex) {
|
||||
return getOutput(servoIndex, TIM_USE_FW_SERVO);
|
||||
return getOutput(servoIndex, TIM_USE_SERVO);
|
||||
};
|
||||
|
||||
self.getMrServoOutput = function (index) {
|
||||
return getOutput(index, TIM_USE_MC_SERVO);
|
||||
return getOutput(index, TIM_USE_SERVO);
|
||||
};
|
||||
|
||||
return self;
|
||||
|
|
|
@ -5,6 +5,7 @@ let ServoMixerRuleCollection = function () {
|
|||
|
||||
let self = {},
|
||||
data = [],
|
||||
inactiveData = [],
|
||||
maxServoCount = 16;
|
||||
|
||||
self.setServoCount = function (value) {
|
||||
|
@ -20,7 +21,11 @@ let ServoMixerRuleCollection = function () {
|
|||
}
|
||||
|
||||
self.put = function (element) {
|
||||
data.push(element);
|
||||
if (data.length < self.getServoRulesCount()) {
|
||||
data.push(element);
|
||||
}else{
|
||||
inactiveData.push(element); //store the data for mixer_profile 2
|
||||
}
|
||||
};
|
||||
|
||||
self.get = function () {
|
||||
|
@ -34,18 +39,24 @@ let ServoMixerRuleCollection = function () {
|
|||
|
||||
self.flush = function () {
|
||||
data = [];
|
||||
inactiveData = [];
|
||||
};
|
||||
|
||||
self.cleanup = function () {
|
||||
var tmpData = [];
|
||||
|
||||
var tmpInactiveData = [];
|
||||
data.forEach(function (element) {
|
||||
if (element.isUsed()) {
|
||||
tmpData.push(element);
|
||||
}
|
||||
});
|
||||
|
||||
inactiveData.forEach(function (element) {
|
||||
if (element.isUsed()) {
|
||||
tmpInactiveData.push(element);
|
||||
}
|
||||
});
|
||||
data = tmpData;
|
||||
inactiveData = tmpInactiveData;
|
||||
};
|
||||
|
||||
self.inflate = function () {
|
||||
|
@ -69,6 +80,15 @@ let ServoMixerRuleCollection = function () {
|
|||
}
|
||||
}
|
||||
}
|
||||
for (let ruleIndex in inactiveData) {
|
||||
if (inactiveData.hasOwnProperty(ruleIndex)) {
|
||||
let rule = inactiveData[ruleIndex];
|
||||
|
||||
if (rule.getTarget() == servoId && rule.isUsed()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
|
@ -106,12 +126,17 @@ let ServoMixerRuleCollection = function () {
|
|||
out.push(rule.getTarget());
|
||||
}
|
||||
}
|
||||
for (let ruleIndex in inactiveData) {
|
||||
if (inactiveData.hasOwnProperty(ruleIndex)) {
|
||||
let rule = inactiveData[ruleIndex];
|
||||
out.push(rule.getTarget());
|
||||
}
|
||||
}
|
||||
|
||||
let unique = [...new Set(out)];
|
||||
|
||||
return unique.sort(function(a, b) {
|
||||
return a-b;
|
||||
});
|
||||
let minIndex = Math.min(...out);
|
||||
let maxIndex = Math.max(...out);
|
||||
return Array.from({ length: maxIndex - minIndex + 1 }, (_, index) => minIndex + index);
|
||||
}
|
||||
|
||||
self.getNextUnusedIndex = function() {
|
||||
|
|
|
@ -85,88 +85,7 @@ var Settings = (function () {
|
|||
input.attr('maxlength', s.setting.max);
|
||||
} else if (input.data('presentation') == 'range') {
|
||||
|
||||
let scaledMax;
|
||||
let scaledMin;
|
||||
let scalingThreshold;
|
||||
|
||||
if (input.data('normal-max')) {
|
||||
scaledMax = s.setting.max * 2;
|
||||
scalingThreshold = Math.round(scaledMax * 0.8);
|
||||
scaledMin = s.setting.min *2;
|
||||
} else {
|
||||
scaledMax = s.setting.max;
|
||||
scaledMin = s.setting.min;
|
||||
scalingThreshold = scaledMax;
|
||||
}
|
||||
|
||||
|
||||
let $range = $('<input type="range" min="' + scaledMin + '" max="' + scaledMax + '" value="' + s.value + '"/>');
|
||||
if (input.data('step')) {
|
||||
$range.attr('step', input.data('step'));
|
||||
}
|
||||
$range.css({
|
||||
'display': 'block',
|
||||
'flex-grow': 100,
|
||||
'margin-left': '1em',
|
||||
'margin-right': '1em',
|
||||
});
|
||||
|
||||
input.attr('min', s.setting.min);
|
||||
input.attr('max', s.setting.max);
|
||||
input.val(parseInt(s.value));
|
||||
input.css({
|
||||
'width': 'auto',
|
||||
'min-width': '75px',
|
||||
});
|
||||
|
||||
input.parent().css({
|
||||
'display': 'flex',
|
||||
'width': '100%'
|
||||
});
|
||||
$range.insertAfter(input);
|
||||
|
||||
input.parent().find('.helpicon').css({
|
||||
'top': '5px',
|
||||
'left': '-10px'
|
||||
});
|
||||
|
||||
/*
|
||||
* Update slider to input
|
||||
*/
|
||||
$range.on('input', function() {
|
||||
let val = $(this).val();
|
||||
let normalMax = parseInt(input.data('normal-max'));
|
||||
|
||||
if (normalMax) {
|
||||
if (val <= scalingThreshold) {
|
||||
val = scaleRangeInt(val, scaledMin, scalingThreshold, s.setting.min, normalMax);
|
||||
} else {
|
||||
val = scaleRangeInt(val, scalingThreshold + 1, scaledMax, normalMax + 1, s.setting.max);
|
||||
}
|
||||
}
|
||||
|
||||
input.val(val);
|
||||
});
|
||||
|
||||
input.on('change', function() {
|
||||
|
||||
let val = $(this).val();
|
||||
let newVal;
|
||||
let normalMax = parseInt(input.data('normal-max'));
|
||||
if (normalMax) {
|
||||
if (val <= normalMax) {
|
||||
newVal = scaleRangeInt(val, s.setting.min, normalMax, scaledMin, scalingThreshold);
|
||||
} else {
|
||||
newVal = scaleRangeInt(val, normalMax + 1, s.setting.max, scalingThreshold + 1, scaledMax);
|
||||
}
|
||||
} else {
|
||||
newVal = val;
|
||||
}
|
||||
|
||||
$range.val(newVal);
|
||||
});
|
||||
|
||||
input.trigger('change');
|
||||
GUI.sliderize(input, s.value, s.setting.min, s.setting.max);
|
||||
|
||||
} else if (s.setting.type == 'float') {
|
||||
input.attr('type', 'number');
|
||||
|
|
21
main.css
|
@ -1643,7 +1643,7 @@ dialog {
|
|||
/* fixing padding for all Tabs*/
|
||||
.tab-setup, .tab-landing, .tab-adjustments, .tab-auxiliary, .tab-cli, .tab-configuration, .tab-failsafe, .tab-onboard_logging,
|
||||
.tab-firmware_flasher, .tab-gps, .tab-magnetometer, .tab-help, .tab-led-strip, .tab-logging, .tab-modes, .tab-motors, .tab-pid_tuning,
|
||||
.tab-ports, .tab-receiver, .tab-sensors, .tab-servos, .tab-osd, .tab-calibration {
|
||||
.tab-ports, .tab-receiver, .tab-sensors, .tab-servos, .tab-osd, .tab-calibration, .tab-ez_tune {
|
||||
height: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
@ -1685,7 +1685,7 @@ dialog {
|
|||
color: white;
|
||||
font-size: 10px;
|
||||
margin-top: 20px;
|
||||
width: 269px;
|
||||
width: 410px;
|
||||
float: right;
|
||||
margin-right: 10px;
|
||||
line-height: 12px;
|
||||
|
@ -1700,6 +1700,15 @@ dialog {
|
|||
|
||||
}
|
||||
|
||||
#mixer_profile_change {
|
||||
color: white;
|
||||
margin-top: 16px;
|
||||
width: 130px;
|
||||
float: left;
|
||||
margin-right: 10px;
|
||||
line-height: 12px;
|
||||
}
|
||||
|
||||
#profile_change {
|
||||
color: white;
|
||||
margin-top: 16px;
|
||||
|
@ -2275,3 +2284,11 @@ ol li {
|
|||
.controlProfileHighlightActive {
|
||||
background-color: #d5ebfe !important ;
|
||||
}
|
||||
|
||||
.no-border {
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
.bold {
|
||||
font-weight: bold;
|
||||
}
|
16
main.html
|
@ -87,6 +87,16 @@
|
|||
<div class="legend" i18n="sensorDataFlashFreeSpace"></div>
|
||||
</li>
|
||||
</ul>
|
||||
<div id="mixer_profile_change">
|
||||
<div class="dropdown dropdown-dark">
|
||||
<form name="mixer-profile-change" id="mixer-profile-change">
|
||||
<select class="dropdown-select" id="mixerprofilechange">
|
||||
<option value="0" i18n="mixerProfile1"></option>
|
||||
<option value="1" i18n="mixerProfile2"></option>
|
||||
</select>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div id="profile_change">
|
||||
<div class="dropdown dropdown-dark">
|
||||
<form name="profile-change" id="profile-change">
|
||||
|
@ -205,6 +215,9 @@
|
|||
<li class="tab_failsafe">
|
||||
<a href="#" data-i18n="tabFailsafe" class="tabicon ic_failsafe" title="Failsafe"></a>
|
||||
</li>
|
||||
<li class="tab_ez_tune">
|
||||
<a href="#" data-i18n="tabEzTune" class="tabicon ic_wizzard"></a>
|
||||
</li>
|
||||
<li class="tab_pid_tuning">
|
||||
<a href="#" data-i18n="tabPidTuning" class="tabicon ic_pid" title="PID Tuning"></a>
|
||||
</li>
|
||||
|
@ -251,8 +264,7 @@
|
|||
<a href="#" data-i18n="tabCLI" class="tabicon ic_cli" title="CLI"></a>
|
||||
</li>
|
||||
|
||||
<!--<li class=""><a href="#" class="tabicon ic_advanced">Advanced (spare icon)</a></li>-->
|
||||
<!--<li class=""><a href="#" class="tabicon ic_wizzard">Wizzard (spare icon)</a></li>-->
|
||||
<!-- <li class=""><a href="#" class="tabicon ic_advanced">Advanced (spare icon)</a></li> -->
|
||||
</ul>
|
||||
</div>
|
||||
<div class="clear-both"></div>
|
||||
|
|
16
main.js
|
@ -301,6 +301,9 @@ $(document).ready(function () {
|
|||
case 'cli':
|
||||
TABS.cli.initialize(content_ready);
|
||||
break;
|
||||
case 'ez_tune':
|
||||
TABS.ez_tune.initialize(content_ready);
|
||||
break;
|
||||
|
||||
default:
|
||||
console.log('Tab not found:' + tab);
|
||||
|
@ -545,6 +548,19 @@ $(document).ready(function () {
|
|||
|
||||
});
|
||||
|
||||
var mixerprofile_e = $('#mixerprofilechange');
|
||||
|
||||
mixerprofile_e.change(function () {
|
||||
var mixerprofile = parseInt($(this).val());
|
||||
MSP.send_message(MSPCodes.MSP2_INAV_SELECT_MIXER_PROFILE, [mixerprofile], false, function () {
|
||||
GUI.log(chrome.i18n.getMessage('loadedMixerProfile', [mixerprofile + 1]));
|
||||
MSP.send_message(MSPCodes.MSP_SET_REBOOT, false, false, function () {
|
||||
GUI.log(chrome.i18n.getMessage('deviceRebooting'));
|
||||
GUI.handleReconnect();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
var profile_e = $('#profilechange');
|
||||
|
||||
profile_e.change(function () {
|
||||
|
|
1212
package-lock.json
generated
|
@ -48,7 +48,7 @@
|
|||
"@quanle94/innosetup": "^6.0.2",
|
||||
"gulp-debian": "^0.1.9",
|
||||
"gulp-rename": "^2.0.0",
|
||||
"nw-builder": "^4.0.11",
|
||||
"nw-builder": "3.8.6",
|
||||
"rpm-builder": "^1.2.1",
|
||||
"semver": "6.3.0"
|
||||
},
|
||||
|
|
6903
resources/models/fc.gltf
Normal file
|
@ -1,51 +1,38 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Public domain (CC-BY-SA if you or your laws insist), generated by Jonathan Hudson's svg_model_motors.rb -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200pt" height="200pt" viewBox="0 0 200 200" version="1.1">
|
||||
<defs>
|
||||
<g>
|
||||
<symbol overflow="visible" id="glyph0-0">
|
||||
<path style="stroke:none;" d=""/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph0-1">
|
||||
<path style="stroke:none;" d="M 2.679688 -13.863281 L 2.679688 -15.75 C 4.457031 -15.921875 5.695312 -16.210938 6.398438 -16.617188 C 7.101562 -17.023438 7.625 -17.984375 7.96875 -19.496094 L 9.914062 -19.496094 L 9.914062 0 L 7.289062 0 L 7.289062 -13.863281 Z M 2.679688 -13.863281 "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph0-2">
|
||||
<path style="stroke:none;" d="M 1.921875 -4.402344 C 2.527344 -5.652344 3.710938 -6.785156 5.46875 -7.804688 L 8.09375 -9.324219 C 9.269531 -10.007812 10.09375 -10.589844 10.570312 -11.074219 C 11.316406 -11.832031 11.6875 -12.695312 11.6875 -13.671875 C 11.6875 -14.8125 11.347656 -15.714844 10.664062 -16.386719 C 9.980469 -17.054688 9.070312 -17.390625 7.929688 -17.390625 C 6.242188 -17.390625 5.078125 -16.753906 4.429688 -15.476562 C 4.082031 -14.792969 3.890625 -13.84375 3.855469 -12.632812 L 1.351562 -12.632812 C 1.378906 -14.335938 1.695312 -15.726562 2.296875 -16.804688 C 3.363281 -18.699219 5.246094 -19.648438 7.945312 -19.648438 C 10.1875 -19.648438 11.824219 -19.039062 12.859375 -17.828125 C 13.894531 -16.617188 14.410156 -15.265625 14.410156 -13.78125 C 14.410156 -12.214844 13.859375 -10.875 12.757812 -9.761719 C 12.117188 -9.113281 10.972656 -8.332031 9.324219 -7.410156 L 7.453125 -6.371094 C 6.558594 -5.878906 5.855469 -5.410156 5.34375 -4.960938 C 4.433594 -4.167969 3.859375 -3.289062 3.625 -2.324219 L 14.3125 -2.324219 L 14.3125 0 L 0.875 0 C 0.964844 -1.6875 1.316406 -3.152344 1.921875 -4.402344 Z M 1.921875 -4.402344 "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph0-3">
|
||||
<path style="stroke:none;" d="M 2.234375 -1.375 C 1.191406 -2.644531 0.671875 -4.191406 0.671875 -6.015625 L 3.242188 -6.015625 C 3.351562 -4.75 3.585938 -3.828125 3.953125 -3.253906 C 4.589844 -2.222656 5.742188 -1.710938 7.410156 -1.710938 C 8.703125 -1.710938 9.742188 -2.054688 10.527344 -2.75 C 11.3125 -3.441406 11.703125 -4.335938 11.703125 -5.429688 C 11.703125 -6.777344 11.289062 -7.71875 10.464844 -8.257812 C 9.640625 -8.796875 8.496094 -9.0625 7.027344 -9.0625 C 6.863281 -9.0625 6.695312 -9.0625 6.527344 -9.058594 C 6.359375 -9.054688 6.1875 -9.046875 6.015625 -9.039062 L 6.015625 -11.210938 C 6.269531 -11.183594 6.484375 -11.164062 6.65625 -11.15625 C 6.832031 -11.148438 7.019531 -11.140625 7.21875 -11.140625 C 8.140625 -11.140625 8.894531 -11.289062 9.488281 -11.578125 C 10.527344 -12.089844 11.046875 -13 11.046875 -14.3125 C 11.046875 -15.289062 10.699219 -16.042969 10.007812 -16.570312 C 9.316406 -17.097656 8.507812 -17.363281 7.585938 -17.363281 C 5.945312 -17.363281 4.8125 -16.816406 4.183594 -15.722656 C 3.835938 -15.121094 3.640625 -14.265625 3.59375 -13.152344 L 1.164062 -13.152344 C 1.164062 -14.609375 1.453125 -15.851562 2.039062 -16.871094 C 3.039062 -18.695312 4.804688 -19.605469 7.328125 -19.605469 C 9.324219 -19.605469 10.867188 -19.160156 11.960938 -18.273438 C 13.054688 -17.382812 13.601562 -16.097656 13.601562 -14.410156 C 13.601562 -13.207031 13.28125 -12.230469 12.632812 -11.484375 C 12.230469 -11.019531 11.710938 -10.65625 11.074219 -10.390625 C 12.105469 -10.109375 12.910156 -9.5625 13.488281 -8.757812 C 14.066406 -7.949219 14.355469 -6.964844 14.355469 -5.796875 C 14.355469 -3.929688 13.742188 -2.40625 12.507812 -1.230469 C 11.277344 -0.0546875 9.535156 0.53125 7.273438 0.53125 C 4.957031 0.53125 3.277344 -0.101562 2.234375 -1.375 Z M 2.234375 -1.375 "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph1-0">
|
||||
<path style="stroke:none;" d=""/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph1-1">
|
||||
<path style="stroke:none;" d="M 2.234375 -3.703125 C 2.269531 -3.050781 2.425781 -2.523438 2.695312 -2.117188 C 3.210938 -1.355469 4.121094 -0.976562 5.421875 -0.976562 C 6.003906 -0.976562 6.535156 -1.058594 7.015625 -1.226562 C 7.941406 -1.550781 8.40625 -2.128906 8.40625 -2.960938 C 8.40625 -3.585938 8.210938 -4.03125 7.820312 -4.296875 C 7.425781 -4.558594 6.804688 -4.785156 5.960938 -4.976562 L 4.40625 -5.328125 C 3.390625 -5.558594 2.671875 -5.808594 2.25 -6.085938 C 1.519531 -6.566406 1.15625 -7.28125 1.15625 -8.234375 C 1.15625 -9.265625 1.511719 -10.113281 2.226562 -10.773438 C 2.941406 -11.433594 3.949219 -11.765625 5.257812 -11.765625 C 6.460938 -11.765625 7.484375 -11.476562 8.324219 -10.894531 C 9.164062 -10.3125 9.585938 -9.386719 9.585938 -8.109375 L 8.125 -8.109375 C 8.046875 -8.722656 7.878906 -9.195312 7.625 -9.523438 C 7.152344 -10.121094 6.347656 -10.421875 5.210938 -10.421875 C 4.292969 -10.421875 3.636719 -10.230469 3.234375 -9.84375 C 2.832031 -9.457031 2.632812 -9.011719 2.632812 -8.5 C 2.632812 -7.9375 2.867188 -7.527344 3.335938 -7.265625 C 3.644531 -7.097656 4.339844 -6.890625 5.421875 -6.640625 L 7.03125 -6.273438 C 7.808594 -6.097656 8.40625 -5.855469 8.828125 -5.546875 C 9.558594 -5.011719 9.921875 -4.230469 9.921875 -3.210938 C 9.921875 -1.941406 9.460938 -1.03125 8.535156 -0.484375 C 7.609375 0.0625 6.535156 0.335938 5.3125 0.335938 C 3.886719 0.335938 2.769531 -0.0273438 1.960938 -0.757812 C 1.152344 -1.480469 0.757812 -2.464844 0.773438 -3.703125 Z M 2.234375 -3.703125 "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph1-2">
|
||||
<path style="stroke:none;" d="M 1.53125 -7.921875 L 1.53125 -9 C 2.546875 -9.097656 3.253906 -9.265625 3.65625 -9.496094 C 4.058594 -9.726562 4.355469 -10.277344 4.554688 -11.140625 L 5.664062 -11.140625 L 5.664062 0 L 4.164062 0 L 4.164062 -7.921875 Z M 1.53125 -7.921875 "/>
|
||||
</symbol>
|
||||
</g>
|
||||
</defs>
|
||||
<g id="surface6">
|
||||
<path style="fill:none;stroke-width:28;stroke-linecap:round;stroke-linejoin:round;stroke:rgb(72.941176%,72.941176%,72.941176%);stroke-opacity:1;stroke-miterlimit:10;" d="M 40 40 L 160 40 M 100 40 L 100 160 "/>
|
||||
<path style="fill:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(55,168,219);stroke-opacity:1;stroke-miterlimit:10;" d="M 128 160 C 128 175.464844 115.464844 188 100 188 C 84.535156 188 72 175.464844 72 160 C 72 144.535156 84.535156 132 100 132 C 115.464844 132 128 144.535156 128 160 M 80.199219 140.199219 L 80.199219 123.398438 M 80.199219 140.199219 L 97 142.214844 "/>
|
||||
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
|
||||
<use xlink:href="#glyph0-1" x="93" y="167"/>
|
||||
</g>
|
||||
<path style="fill:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(55,168,219);stroke-opacity:1;stroke-miterlimit:10;" d="M 188 40 C 188 55.464844 175.464844 68 160 68 C 144.535156 68 132 55.464844 132 40 C 132 24.535156 144.535156 12 160 12 C 175.464844 12 188 24.535156 188 40 M 140.199219 20.199219 L 140.199219 3.398438 M 140.199219 20.199219 L 157 22.214844 "/>
|
||||
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
|
||||
<use xlink:href="#glyph0-2" x="153" y="47"/>
|
||||
</g>
|
||||
<path style="fill:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(55,168,219);stroke-opacity:1;stroke-miterlimit:10;" d="M 68 40 C 68 55.464844 55.464844 68 40 68 C 24.535156 68 12 55.464844 12 40 C 12 24.535156 24.535156 12 40 12 C 55.464844 12 68 24.535156 68 40 M 59.800781 20.199219 L 57.785156 37 M 59.800781 20.199219 L 76.601562 20.199219 "/>
|
||||
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
|
||||
<use xlink:href="#glyph0-3" x="33" y="47"/>
|
||||
</g>
|
||||
<path style="fill:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 140 140 L 168 140 L 168 168 L 140 168 Z M 140 140 "/>
|
||||
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
|
||||
<use xlink:href="#glyph1-1" x="144" y="160"/>
|
||||
<use xlink:href="#glyph1-2" x="154.671875" y="160"/>
|
||||
</g>
|
||||
<path style="fill:none;stroke-width:12;stroke-linecap:butt;stroke-linejoin:bevel;stroke:rgb(98.039216%,2.745098%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 100 70 L 100 110 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(98.039216%,2.745098%,0%);fill-opacity:1;" d="M 100 65 L 85 80 L 115 80 L 100 65 "/>
|
||||
</g>
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 200 200" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;">
|
||||
<g id="surface6">
|
||||
<path d="M40,40L160,40M100,40L100,160" style="fill:none;fill-rule:nonzero;stroke:rgb(185,185,185);stroke-width:28px;"/>
|
||||
<path d="M128,160C128,175.465 115.465,188 100,188C84.535,188 72,175.465 72,160C72,144.535 84.535,132 100,132C115.465,132 128,144.535 128,160M80.199,140.199L80.199,123.398M80.199,140.199L97,142.215" style="fill:none;fill-rule:nonzero;stroke:rgb(55,168,219);stroke-width:3px;stroke-linecap:butt;stroke-linejoin:miter;"/>
|
||||
<g id="glyph0-1" transform="matrix(1,0,0,1,93,167)">
|
||||
<g>
|
||||
<path d="M2.68,-13.863L2.68,-15.75C4.457,-15.922 5.695,-16.211 6.398,-16.617C7.102,-17.023 7.625,-17.984 7.969,-19.496L9.914,-19.496L9.914,0L7.289,0L7.289,-13.863L2.68,-13.863Z" style="fill-rule:nonzero;"/>
|
||||
</g>
|
||||
</g>
|
||||
<path d="M188,40C188,55.465 175.465,68 160,68C144.535,68 132,55.465 132,40C132,24.535 144.535,12 160,12C175.465,12 188,24.535 188,40M140.199,20.199L140.199,3.398M140.199,20.199L157,22.215" style="fill:none;fill-rule:nonzero;stroke:rgb(55,168,219);stroke-width:3px;stroke-linecap:butt;stroke-linejoin:miter;"/>
|
||||
<g id="glyph0-2" transform="matrix(1,0,0,1,153,47)">
|
||||
<g>
|
||||
<path d="M1.922,-4.402C2.527,-5.652 3.711,-6.785 5.469,-7.805L8.094,-9.324C9.27,-10.008 10.094,-10.59 10.57,-11.074C11.316,-11.832 11.688,-12.695 11.688,-13.672C11.688,-14.813 11.348,-15.715 10.664,-16.387C9.98,-17.055 9.07,-17.391 7.93,-17.391C6.242,-17.391 5.078,-16.754 4.43,-15.477C4.082,-14.793 3.891,-13.844 3.855,-12.633L1.352,-12.633C1.379,-14.336 1.695,-15.727 2.297,-16.805C3.363,-18.699 5.246,-19.648 7.945,-19.648C10.188,-19.648 11.824,-19.039 12.859,-17.828C13.895,-16.617 14.41,-15.266 14.41,-13.781C14.41,-12.215 13.859,-10.875 12.758,-9.762C12.117,-9.113 10.973,-8.332 9.324,-7.41L7.453,-6.371C6.559,-5.879 5.855,-5.41 5.344,-4.961C4.434,-4.168 3.859,-3.289 3.625,-2.324L14.313,-2.324L14.313,0L0.875,0C0.965,-1.688 1.316,-3.152 1.922,-4.402Z" style="fill-rule:nonzero;"/>
|
||||
</g>
|
||||
</g>
|
||||
<g transform="matrix(0.0166389,-0.999862,-0.999862,-0.0166389,80.5581,80.9602)">
|
||||
<path d="M68,40C68,55.465 55.465,68 40,68C24.535,68 12,55.465 12,40C12,24.535 24.535,12 40,12C55.465,12 68,24.535 68,40M59.801,20.199L57.785,37M59.801,20.199L76.602,20.199" style="fill:none;fill-rule:nonzero;stroke:rgb(55,168,219);stroke-width:3px;stroke-linecap:butt;stroke-linejoin:miter;"/>
|
||||
</g>
|
||||
<g id="glyph0-3" transform="matrix(1,0,0,1,33,47)">
|
||||
<g>
|
||||
<path d="M2.234,-1.375C1.191,-2.645 0.672,-4.191 0.672,-6.016L3.242,-6.016C3.352,-4.75 3.586,-3.828 3.953,-3.254C4.59,-2.223 5.742,-1.711 7.41,-1.711C8.703,-1.711 9.742,-2.055 10.527,-2.75C11.313,-3.441 11.703,-4.336 11.703,-5.43C11.703,-6.777 11.289,-7.719 10.465,-8.258C9.641,-8.797 8.496,-9.063 7.027,-9.063C6.863,-9.063 6.695,-9.063 6.527,-9.059C6.359,-9.055 6.188,-9.047 6.016,-9.039L6.016,-11.211C6.27,-11.184 6.484,-11.164 6.656,-11.156C6.832,-11.148 7.02,-11.141 7.219,-11.141C8.141,-11.141 8.895,-11.289 9.488,-11.578C10.527,-12.09 11.047,-13 11.047,-14.313C11.047,-15.289 10.699,-16.043 10.008,-16.57C9.316,-17.098 8.508,-17.363 7.586,-17.363C5.945,-17.363 4.813,-16.816 4.184,-15.723C3.836,-15.121 3.641,-14.266 3.594,-13.152L1.164,-13.152C1.164,-14.609 1.453,-15.852 2.039,-16.871C3.039,-18.695 4.805,-19.605 7.328,-19.605C9.324,-19.605 10.867,-19.16 11.961,-18.273C13.055,-17.383 13.602,-16.098 13.602,-14.41C13.602,-13.207 13.281,-12.23 12.633,-11.484C12.23,-11.02 11.711,-10.656 11.074,-10.391C12.105,-10.109 12.91,-9.563 13.488,-8.758C14.066,-7.949 14.355,-6.965 14.355,-5.797C14.355,-3.93 13.742,-2.406 12.508,-1.23C11.277,-0.055 9.535,0.531 7.273,0.531C4.957,0.531 3.277,-0.102 2.234,-1.375Z" style="fill-rule:nonzero;"/>
|
||||
</g>
|
||||
</g>
|
||||
<rect x="140" y="140" width="28" height="28" style="fill:none;fill-rule:nonzero;stroke:black;stroke-width:3px;stroke-linecap:butt;stroke-linejoin:miter;"/>
|
||||
<g>
|
||||
<g id="glyph1-1" transform="matrix(1,0,0,1,144,160)">
|
||||
<path d="M2.234,-3.703C2.27,-3.051 2.426,-2.523 2.695,-2.117C3.211,-1.355 4.121,-0.977 5.422,-0.977C6.004,-0.977 6.535,-1.059 7.016,-1.227C7.941,-1.551 8.406,-2.129 8.406,-2.961C8.406,-3.586 8.211,-4.031 7.82,-4.297C7.426,-4.559 6.805,-4.785 5.961,-4.977L4.406,-5.328C3.391,-5.559 2.672,-5.809 2.25,-6.086C1.52,-6.566 1.156,-7.281 1.156,-8.234C1.156,-9.266 1.512,-10.113 2.227,-10.773C2.941,-11.434 3.949,-11.766 5.258,-11.766C6.461,-11.766 7.484,-11.477 8.324,-10.895C9.164,-10.313 9.586,-9.387 9.586,-8.109L8.125,-8.109C8.047,-8.723 7.879,-9.195 7.625,-9.523C7.152,-10.121 6.348,-10.422 5.211,-10.422C4.293,-10.422 3.637,-10.23 3.234,-9.844C2.832,-9.457 2.633,-9.012 2.633,-8.5C2.633,-7.938 2.867,-7.527 3.336,-7.266C3.645,-7.098 4.34,-6.891 5.422,-6.641L7.031,-6.273C7.809,-6.098 8.406,-5.855 8.828,-5.547C9.559,-5.012 9.922,-4.23 9.922,-3.211C9.922,-1.941 9.461,-1.031 8.535,-0.484C7.609,0.063 6.535,0.336 5.313,0.336C3.887,0.336 2.77,-0.027 1.961,-0.758C1.152,-1.48 0.758,-2.465 0.773,-3.703L2.234,-3.703Z" style="fill-rule:nonzero;"/>
|
||||
</g>
|
||||
<g id="glyph1-2" transform="matrix(1,0,0,1,154.672,160)">
|
||||
<path d="M1.531,-7.922L1.531,-9C2.547,-9.098 3.254,-9.266 3.656,-9.496C4.059,-9.727 4.355,-10.277 4.555,-11.141L5.664,-11.141L5.664,0L4.164,0L4.164,-7.922L1.531,-7.922Z" style="fill-rule:nonzero;"/>
|
||||
</g>
|
||||
</g>
|
||||
<path d="M100,70L100,110" style="fill:none;fill-rule:nonzero;stroke:rgb(250,6,0);stroke-width:12px;stroke-linecap:butt;stroke-linejoin:bevel;"/>
|
||||
<path d="M100,65L85,80L115,80L100,65" style="fill:rgb(250,6,0);fill-rule:nonzero;"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
|
Before Width: | Height: | Size: 8 KiB After Width: | Height: | Size: 6 KiB |
|
@ -1,177 +1,42 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Public domain (CC-BY-SA if you or your laws insist), generated by Jonathan Hudson's svg_model_motors.rb -->
|
||||
|
||||
<svg
|
||||
width="200pt"
|
||||
height="200pt"
|
||||
viewBox="0 0 200 200"
|
||||
version="1.1"
|
||||
id="svg60"
|
||||
sodipodi:docname="tri_reverse.svg"
|
||||
inkscape:version="1.1 (c68e22c387, 2021-05-23)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview62"
|
||||
pagecolor="#505050"
|
||||
bordercolor="#eeeeee"
|
||||
borderopacity="1"
|
||||
inkscape:pageshadow="0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:document-units="pt"
|
||||
showgrid="false"
|
||||
inkscape:zoom="3.1875"
|
||||
inkscape:cx="133.33333"
|
||||
inkscape:cy="108.39216"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1009"
|
||||
inkscape:window-x="1912"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg60" />
|
||||
<defs
|
||||
id="defs25">
|
||||
<g
|
||||
id="g23">
|
||||
<symbol
|
||||
overflow="visible"
|
||||
id="glyph0-0">
|
||||
<path
|
||||
style="stroke:none;"
|
||||
d=""
|
||||
id="path2" />
|
||||
</symbol>
|
||||
<symbol
|
||||
overflow="visible"
|
||||
id="glyph0-1">
|
||||
<path
|
||||
style="stroke:none;"
|
||||
d="M 2.679688 -13.863281 L 2.679688 -15.75 C 4.457031 -15.921875 5.695312 -16.210938 6.398438 -16.617188 C 7.101562 -17.023438 7.625 -17.984375 7.96875 -19.496094 L 9.914062 -19.496094 L 9.914062 0 L 7.289062 0 L 7.289062 -13.863281 Z M 2.679688 -13.863281 "
|
||||
id="path5" />
|
||||
</symbol>
|
||||
<symbol
|
||||
overflow="visible"
|
||||
id="glyph0-2">
|
||||
<path
|
||||
style="stroke:none;"
|
||||
d="M 1.921875 -4.402344 C 2.527344 -5.652344 3.710938 -6.785156 5.46875 -7.804688 L 8.09375 -9.324219 C 9.269531 -10.007812 10.09375 -10.589844 10.570312 -11.074219 C 11.316406 -11.832031 11.6875 -12.695312 11.6875 -13.671875 C 11.6875 -14.8125 11.347656 -15.714844 10.664062 -16.386719 C 9.980469 -17.054688 9.070312 -17.390625 7.929688 -17.390625 C 6.242188 -17.390625 5.078125 -16.753906 4.429688 -15.476562 C 4.082031 -14.792969 3.890625 -13.84375 3.855469 -12.632812 L 1.351562 -12.632812 C 1.378906 -14.335938 1.695312 -15.726562 2.296875 -16.804688 C 3.363281 -18.699219 5.246094 -19.648438 7.945312 -19.648438 C 10.1875 -19.648438 11.824219 -19.039062 12.859375 -17.828125 C 13.894531 -16.617188 14.410156 -15.265625 14.410156 -13.78125 C 14.410156 -12.214844 13.859375 -10.875 12.757812 -9.761719 C 12.117188 -9.113281 10.972656 -8.332031 9.324219 -7.410156 L 7.453125 -6.371094 C 6.558594 -5.878906 5.855469 -5.410156 5.34375 -4.960938 C 4.433594 -4.167969 3.859375 -3.289062 3.625 -2.324219 L 14.3125 -2.324219 L 14.3125 0 L 0.875 0 C 0.964844 -1.6875 1.316406 -3.152344 1.921875 -4.402344 Z M 1.921875 -4.402344 "
|
||||
id="path8" />
|
||||
</symbol>
|
||||
<symbol
|
||||
overflow="visible"
|
||||
id="glyph0-3">
|
||||
<path
|
||||
style="stroke:none;"
|
||||
d="M 2.234375 -1.375 C 1.191406 -2.644531 0.671875 -4.191406 0.671875 -6.015625 L 3.242188 -6.015625 C 3.351562 -4.75 3.585938 -3.828125 3.953125 -3.253906 C 4.589844 -2.222656 5.742188 -1.710938 7.410156 -1.710938 C 8.703125 -1.710938 9.742188 -2.054688 10.527344 -2.75 C 11.3125 -3.441406 11.703125 -4.335938 11.703125 -5.429688 C 11.703125 -6.777344 11.289062 -7.71875 10.464844 -8.257812 C 9.640625 -8.796875 8.496094 -9.0625 7.027344 -9.0625 C 6.863281 -9.0625 6.695312 -9.0625 6.527344 -9.058594 C 6.359375 -9.054688 6.1875 -9.046875 6.015625 -9.039062 L 6.015625 -11.210938 C 6.269531 -11.183594 6.484375 -11.164062 6.65625 -11.15625 C 6.832031 -11.148438 7.019531 -11.140625 7.21875 -11.140625 C 8.140625 -11.140625 8.894531 -11.289062 9.488281 -11.578125 C 10.527344 -12.089844 11.046875 -13 11.046875 -14.3125 C 11.046875 -15.289062 10.699219 -16.042969 10.007812 -16.570312 C 9.316406 -17.097656 8.507812 -17.363281 7.585938 -17.363281 C 5.945312 -17.363281 4.8125 -16.816406 4.183594 -15.722656 C 3.835938 -15.121094 3.640625 -14.265625 3.59375 -13.152344 L 1.164062 -13.152344 C 1.164062 -14.609375 1.453125 -15.851562 2.039062 -16.871094 C 3.039062 -18.695312 4.804688 -19.605469 7.328125 -19.605469 C 9.324219 -19.605469 10.867188 -19.160156 11.960938 -18.273438 C 13.054688 -17.382812 13.601562 -16.097656 13.601562 -14.410156 C 13.601562 -13.207031 13.28125 -12.230469 12.632812 -11.484375 C 12.230469 -11.019531 11.710938 -10.65625 11.074219 -10.390625 C 12.105469 -10.109375 12.910156 -9.5625 13.488281 -8.757812 C 14.066406 -7.949219 14.355469 -6.964844 14.355469 -5.796875 C 14.355469 -3.929688 13.742188 -2.40625 12.507812 -1.230469 C 11.277344 -0.0546875 9.535156 0.53125 7.273438 0.53125 C 4.957031 0.53125 3.277344 -0.101562 2.234375 -1.375 Z M 2.234375 -1.375 "
|
||||
id="path11" />
|
||||
</symbol>
|
||||
<symbol
|
||||
overflow="visible"
|
||||
id="glyph1-0">
|
||||
<path
|
||||
style="stroke:none;"
|
||||
d=""
|
||||
id="path14" />
|
||||
</symbol>
|
||||
<symbol
|
||||
overflow="visible"
|
||||
id="glyph1-1">
|
||||
<path
|
||||
style="stroke:none;"
|
||||
d="M 2.234375 -3.703125 C 2.269531 -3.050781 2.425781 -2.523438 2.695312 -2.117188 C 3.210938 -1.355469 4.121094 -0.976562 5.421875 -0.976562 C 6.003906 -0.976562 6.535156 -1.058594 7.015625 -1.226562 C 7.941406 -1.550781 8.40625 -2.128906 8.40625 -2.960938 C 8.40625 -3.585938 8.210938 -4.03125 7.820312 -4.296875 C 7.425781 -4.558594 6.804688 -4.785156 5.960938 -4.976562 L 4.40625 -5.328125 C 3.390625 -5.558594 2.671875 -5.808594 2.25 -6.085938 C 1.519531 -6.566406 1.15625 -7.28125 1.15625 -8.234375 C 1.15625 -9.265625 1.511719 -10.113281 2.226562 -10.773438 C 2.941406 -11.433594 3.949219 -11.765625 5.257812 -11.765625 C 6.460938 -11.765625 7.484375 -11.476562 8.324219 -10.894531 C 9.164062 -10.3125 9.585938 -9.386719 9.585938 -8.109375 L 8.125 -8.109375 C 8.046875 -8.722656 7.878906 -9.195312 7.625 -9.523438 C 7.152344 -10.121094 6.347656 -10.421875 5.210938 -10.421875 C 4.292969 -10.421875 3.636719 -10.230469 3.234375 -9.84375 C 2.832031 -9.457031 2.632812 -9.011719 2.632812 -8.5 C 2.632812 -7.9375 2.867188 -7.527344 3.335938 -7.265625 C 3.644531 -7.097656 4.339844 -6.890625 5.421875 -6.640625 L 7.03125 -6.273438 C 7.808594 -6.097656 8.40625 -5.855469 8.828125 -5.546875 C 9.558594 -5.011719 9.921875 -4.230469 9.921875 -3.210938 C 9.921875 -1.941406 9.460938 -1.03125 8.535156 -0.484375 C 7.609375 0.0625 6.535156 0.335938 5.3125 0.335938 C 3.886719 0.335938 2.769531 -0.0273438 1.960938 -0.757812 C 1.152344 -1.480469 0.757812 -2.464844 0.773438 -3.703125 Z M 2.234375 -3.703125 "
|
||||
id="path17" />
|
||||
</symbol>
|
||||
<symbol
|
||||
overflow="visible"
|
||||
id="glyph1-2">
|
||||
<path
|
||||
style="stroke:none;"
|
||||
d="M 1.53125 -7.921875 L 1.53125 -9 C 2.546875 -9.097656 3.253906 -9.265625 3.65625 -9.496094 C 4.058594 -9.726562 4.355469 -10.277344 4.554688 -11.140625 L 5.664062 -11.140625 L 5.664062 0 L 4.164062 0 L 4.164062 -7.921875 Z M 1.53125 -7.921875 "
|
||||
id="path20" />
|
||||
</symbol>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 200 200" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;">
|
||||
<path id="path27" d="M40,40L160,40M100,40L100,160" style="fill:none;fill-rule:nonzero;stroke:rgb(184,184,184);stroke-width:28px;"/>
|
||||
<path id="path29" d="M72,160C72,175.465 84.535,188 100,188C115.465,188 128,175.465 128,160C128,144.535 115.465,132 100,132C84.535,132 72,144.535 72,160M119.801,140.199L119.801,123.398M119.801,140.199L103,142.215" style="fill:none;fill-rule:nonzero;stroke:rgb(55,168,219);stroke-width:3px;stroke-linecap:butt;stroke-linejoin:miter;"/>
|
||||
<g id="use31" transform="matrix(1,0,0,1,93,167)">
|
||||
<g id="g33">
|
||||
<g id="use311" serif:id="use31">
|
||||
<path id="path5" d="M2.68,-13.863L2.68,-15.75C4.457,-15.922 5.695,-16.211 6.398,-16.617C7.102,-17.023 7.625,-17.984 7.969,-19.496L9.914,-19.496L9.914,0L7.289,0L7.289,-13.863L2.68,-13.863Z" style="fill-rule:nonzero;"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</defs>
|
||||
<path
|
||||
style="fill:none;stroke:#b8b8b8;stroke-width:28;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1"
|
||||
d="m 40,40 h 120 m -60,0 v 120"
|
||||
id="path27" />
|
||||
<path
|
||||
style="fill:none;stroke:#37a8db;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1"
|
||||
d="m 72,160 c 0,15.46484 12.53516,28 28,28 15.46484,0 28,-12.53516 28,-28 0,-15.46484 -12.53516,-28 -28,-28 -15.46484,0 -28,12.53516 -28,28 m 47.80078,-19.80078 v -16.80078 m 0,16.80078 L 103,142.21484"
|
||||
id="path29" />
|
||||
<g
|
||||
style="fill:#000000;fill-opacity:1"
|
||||
id="g33">
|
||||
<use
|
||||
xlink:href="#glyph0-1"
|
||||
x="93"
|
||||
y="167"
|
||||
id="use31"
|
||||
width="100%"
|
||||
height="100%" />
|
||||
</g>
|
||||
<path
|
||||
style="fill:none;stroke:#37a8db;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1"
|
||||
d="m 132,40 c 0,15.464844 12.53516,28 28,28 15.46484,0 28,-12.535156 28,-28 0,-15.464844 -12.53516,-28 -28,-28 -15.46484,0 -28,12.535156 -28,28 M 179.80078,20.199219 V 3.398438 m 0,16.800781 L 163,22.214844"
|
||||
id="path35-4" />
|
||||
<g
|
||||
style="fill:#000000;fill-opacity:1"
|
||||
id="g39">
|
||||
<use
|
||||
xlink:href="#glyph0-2"
|
||||
x="153"
|
||||
y="47"
|
||||
id="use37"
|
||||
width="100%"
|
||||
height="100%" />
|
||||
</g>
|
||||
<path
|
||||
style="fill:none;stroke:#37a8db;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1"
|
||||
d="m 11.807447,40 c 0,15.464844 12.535157,28 28.000001,28 15.464844,0 28,-12.535156 28,-28 0,-15.464844 -12.535156,-28 -28,-28 C 24.342604,12 11.807447,24.535156 11.807447,40 M 20.006667,20.199219 22.022292,37 M 20.006667,20.199219 H 3.2058824"
|
||||
id="path41-0" />
|
||||
<g
|
||||
style="fill:#000000;fill-opacity:1"
|
||||
id="g45">
|
||||
<use
|
||||
xlink:href="#glyph0-3"
|
||||
x="33"
|
||||
y="47"
|
||||
id="use43"
|
||||
width="100%"
|
||||
height="100%" />
|
||||
</g>
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1"
|
||||
d="m 140,140 h 28 v 28 h -28 z m 0,0"
|
||||
id="path47" />
|
||||
<g
|
||||
style="fill:#000000;fill-opacity:1"
|
||||
id="g53">
|
||||
<use
|
||||
xlink:href="#glyph1-1"
|
||||
x="144"
|
||||
y="160"
|
||||
id="use49"
|
||||
width="100%"
|
||||
height="100%" />
|
||||
<use
|
||||
xlink:href="#glyph1-2"
|
||||
x="154.67188"
|
||||
y="160"
|
||||
id="use51"
|
||||
width="100%"
|
||||
height="100%" />
|
||||
</g>
|
||||
<path
|
||||
style="fill:none;stroke:#fa0500;stroke-width:12;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-opacity:1"
|
||||
d="m 100,70 v 40"
|
||||
id="path55" />
|
||||
<path
|
||||
style="fill:#fa0500;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="M 100,65 85,80 h 30 L 100,65"
|
||||
id="path57" />
|
||||
<path id="path35-4" d="M132,40C132,55.465 144.535,68 160,68C175.465,68 188,55.465 188,40C188,24.535 175.465,12 160,12C144.535,12 132,24.535 132,40M179.801,20.199L179.801,3.398M179.801,20.199L163,22.215" style="fill:none;fill-rule:nonzero;stroke:rgb(55,168,219);stroke-width:3px;stroke-linecap:butt;stroke-linejoin:miter;"/>
|
||||
<g id="use37" transform="matrix(1,0,0,1,153,47)">
|
||||
<g id="g39">
|
||||
<g id="use371" serif:id="use37">
|
||||
<path id="path8" d="M1.922,-4.402C2.527,-5.652 3.711,-6.785 5.469,-7.805L8.094,-9.324C9.27,-10.008 10.094,-10.59 10.57,-11.074C11.316,-11.832 11.688,-12.695 11.688,-13.672C11.688,-14.813 11.348,-15.715 10.664,-16.387C9.98,-17.055 9.07,-17.391 7.93,-17.391C6.242,-17.391 5.078,-16.754 4.43,-15.477C4.082,-14.793 3.891,-13.844 3.855,-12.633L1.352,-12.633C1.379,-14.336 1.695,-15.727 2.297,-16.805C3.363,-18.699 5.246,-19.648 7.945,-19.648C10.188,-19.648 11.824,-19.039 12.859,-17.828C13.895,-16.617 14.41,-15.266 14.41,-13.781C14.41,-12.215 13.859,-10.875 12.758,-9.762C12.117,-9.113 10.973,-8.332 9.324,-7.41L7.453,-6.371C6.559,-5.879 5.855,-5.41 5.344,-4.961C4.434,-4.168 3.859,-3.289 3.625,-2.324L14.313,-2.324L14.313,0L0.875,0C0.965,-1.688 1.316,-3.152 1.922,-4.402Z" style="fill-rule:nonzero;"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g id="path41-0" transform="matrix(0.00137106,0.999999,0.999999,-0.00137106,1.45802,0.54821)">
|
||||
<path d="M11.807,40C11.807,55.465 24.343,68 39.807,68C55.272,68 67.807,55.465 67.807,40C67.807,24.535 55.272,12 39.807,12C24.343,12 11.807,24.535 11.807,40M20.007,20.199L22.022,37M20.007,20.199L3.206,20.199" style="fill:none;fill-rule:nonzero;stroke:rgb(55,168,219);stroke-width:3px;stroke-linecap:butt;stroke-linejoin:miter;"/>
|
||||
</g>
|
||||
<g id="use43" transform="matrix(1,0,0,1,33,47)">
|
||||
<g id="g45">
|
||||
<g id="use431" serif:id="use43">
|
||||
<path id="path11" d="M2.234,-1.375C1.191,-2.645 0.672,-4.191 0.672,-6.016L3.242,-6.016C3.352,-4.75 3.586,-3.828 3.953,-3.254C4.59,-2.223 5.742,-1.711 7.41,-1.711C8.703,-1.711 9.742,-2.055 10.527,-2.75C11.313,-3.441 11.703,-4.336 11.703,-5.43C11.703,-6.777 11.289,-7.719 10.465,-8.258C9.641,-8.797 8.496,-9.063 7.027,-9.063C6.863,-9.063 6.695,-9.063 6.527,-9.059C6.359,-9.055 6.188,-9.047 6.016,-9.039L6.016,-11.211C6.27,-11.184 6.484,-11.164 6.656,-11.156C6.832,-11.148 7.02,-11.141 7.219,-11.141C8.141,-11.141 8.895,-11.289 9.488,-11.578C10.527,-12.09 11.047,-13 11.047,-14.313C11.047,-15.289 10.699,-16.043 10.008,-16.57C9.316,-17.098 8.508,-17.363 7.586,-17.363C5.945,-17.363 4.813,-16.816 4.184,-15.723C3.836,-15.121 3.641,-14.266 3.594,-13.152L1.164,-13.152C1.164,-14.609 1.453,-15.852 2.039,-16.871C3.039,-18.695 4.805,-19.605 7.328,-19.605C9.324,-19.605 10.867,-19.16 11.961,-18.273C13.055,-17.383 13.602,-16.098 13.602,-14.41C13.602,-13.207 13.281,-12.23 12.633,-11.484C12.23,-11.02 11.711,-10.656 11.074,-10.391C12.105,-10.109 12.91,-9.563 13.488,-8.758C14.066,-7.949 14.355,-6.965 14.355,-5.797C14.355,-3.93 13.742,-2.406 12.508,-1.23C11.277,-0.055 9.535,0.531 7.273,0.531C4.957,0.531 3.277,-0.102 2.234,-1.375Z" style="fill-rule:nonzero;"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<rect id="path47" x="140" y="140" width="28" height="28" style="fill:none;fill-rule:nonzero;stroke:black;stroke-width:3px;stroke-linecap:butt;stroke-linejoin:miter;"/>
|
||||
<g id="g53">
|
||||
<g id="use49" transform="matrix(1,0,0,1,144,160)">
|
||||
<path id="path17" d="M2.234,-3.703C2.27,-3.051 2.426,-2.523 2.695,-2.117C3.211,-1.355 4.121,-0.977 5.422,-0.977C6.004,-0.977 6.535,-1.059 7.016,-1.227C7.941,-1.551 8.406,-2.129 8.406,-2.961C8.406,-3.586 8.211,-4.031 7.82,-4.297C7.426,-4.559 6.805,-4.785 5.961,-4.977L4.406,-5.328C3.391,-5.559 2.672,-5.809 2.25,-6.086C1.52,-6.566 1.156,-7.281 1.156,-8.234C1.156,-9.266 1.512,-10.113 2.227,-10.773C2.941,-11.434 3.949,-11.766 5.258,-11.766C6.461,-11.766 7.484,-11.477 8.324,-10.895C9.164,-10.313 9.586,-9.387 9.586,-8.109L8.125,-8.109C8.047,-8.723 7.879,-9.195 7.625,-9.523C7.152,-10.121 6.348,-10.422 5.211,-10.422C4.293,-10.422 3.637,-10.23 3.234,-9.844C2.832,-9.457 2.633,-9.012 2.633,-8.5C2.633,-7.938 2.867,-7.527 3.336,-7.266C3.645,-7.098 4.34,-6.891 5.422,-6.641L7.031,-6.273C7.809,-6.098 8.406,-5.855 8.828,-5.547C9.559,-5.012 9.922,-4.23 9.922,-3.211C9.922,-1.941 9.461,-1.031 8.535,-0.484C7.609,0.063 6.535,0.336 5.313,0.336C3.887,0.336 2.77,-0.027 1.961,-0.758C1.152,-1.48 0.758,-2.465 0.773,-3.703L2.234,-3.703Z" style="fill-rule:nonzero;"/>
|
||||
</g>
|
||||
<g id="use51" transform="matrix(1,0,0,1,154.672,160)">
|
||||
<path id="path20" d="M1.531,-7.922L1.531,-9C2.547,-9.098 3.254,-9.266 3.656,-9.496C4.059,-9.727 4.355,-10.277 4.555,-11.141L5.664,-11.141L5.664,0L4.164,0L4.164,-7.922L1.531,-7.922Z" style="fill-rule:nonzero;"/>
|
||||
</g>
|
||||
</g>
|
||||
<path id="path55" d="M100,70L100,110" style="fill:none;fill-rule:nonzero;stroke:rgb(250,5,0);stroke-width:12px;stroke-linecap:butt;stroke-linejoin:bevel;"/>
|
||||
<path id="path57" d="M100,65L85,80L115,80L100,65" style="fill:rgb(250,5,0);fill-rule:nonzero;"/>
|
||||
</svg>
|
||||
|
|
Before Width: | Height: | Size: 9.9 KiB After Width: | Height: | Size: 6.3 KiB |
|
@ -113,7 +113,7 @@
|
|||
| | SYM_MAH_KM_1 | SYM.MAH_KM_1 | mAh per Kilometre, right side | 108 | 0x6C |
|
||||
|  | SYM_WH | SYM.WH | Watthours symbol | 109 | 0x6D |
|
||||
|  | SYM_WH_KM | SYM.WH_KM | Watthours per Kilometre | 110 | 0x6E |
|
||||
|  | SYM_WH_MI | SYM.WH_MI | Watthours per Mile | 111 | 0x6F |
|
||||
|  | SYM_WH_MI | SYM.WH_MI | Watthours per Mile | 111 | 0x6F |
|
||||
|  | SYM_WH_NM | SYM.WH_NM | Watthours per Nautical Mile | 112 | 0x70 |
|
||||
|  | SYM_WATT | SYM.WATT | Watts symbol | 113 | 0x71 |
|
||||
|  | SYM_MW | SYM.MW | Milliwatts symbol | 114 | 0x72 |
|
||||
|
@ -224,6 +224,7 @@
|
|||
|  | SYM_FLIGHT_MINS_REMAINING | SYM.FLIGHT_MINS_REMAINING | Flight time (mins) remaining | 218 | 0xDA |
|
||||
|  | SYM_FLIGHT_HOURS_REMAINING | | Flight time (hours) remaining | 219 | 0xDB |
|
||||
|  | SYM_GROUND_COURSE | SYM.GROUND_COURSE | Ground course | 220 | 0xDC |
|
||||
|  | SYM_ALERT | SYM.ALERT | General Alert | 221 | 0xDD |
|
||||
|  | SYM_TERRAIN_FOLLOWING | SYM.TERRAIN_FOLLOWING | Terrain following | 251 | 0xFB |
|
||||
|  | SYM_CROSS_TRACK_ERROR | SYM.CROSS_TRACK_ERROR | Cross track error | 252 | 0xFC |
|
||||
|  | SYM_ADSB | SYM.ADSB | ADSB | 253 | 0xFD |
|
||||
|
@ -284,6 +285,7 @@
|
|||
|  | SYM_HOME_DIST | | Home distance icon | 357 | 0x165 |
|
||||
|  | SYM_AH_CH_CENTER | SYM.AH_CROSSHAIRS | Default crosshair centre | 358 | 0x166 |
|
||||
|  | SYM_FLIGHT_DIST_REMAINING | SYM.FLIGHT_DIST_REMAINING | Flight distance remaining | 359 | 0x167 |
|
||||
|  | SYM_ODOMETER | SYM.ODOMETER | Odometer (total aircraft distance) | 360 | 0x168 |
|
||||
|  | SYM_AH_CH_TYPE3 | SYM.AH_CROSSHAIRS | Crosshair type 3 | 400 - 402 | 0x190 - 0x192 |
|
||||
|  | SYM_AH_CH_TYPE4 | SYM.AH_CROSSHAIRS | Crosshair type 4 | 403 - 405 | 0x193 - 0x195 |
|
||||
|  | SYM_AH_CH_TYPE5 | SYM.AH_CROSSHAIRS | Crosshair type 5 | 406 - 408 | 0x196 - 0x198 |
|
||||
|
@ -322,5 +324,7 @@
|
|||
|  | SYM_SERVO_PAN_IS_CENTRED | | Pan servo is centred | 454 | 0x1C6 |
|
||||
|  | SYM_SERVO_PAN_IS_OFFSET_L | SYM.PAN_SERVO_IS_OFFSET_L | Pan servo is moved to the left | 455 | 0x1C7 |
|
||||
|  | SYM_SERVO_PAN_IS_OFFSET_R | | Pan servo is moved to the right | 456 | 0x1C8 |
|
||||
|  | SYM_PILOT_LOGO_SML_L | SYM.PILOT_LOGO_SML_L | Small Pilot logo | 469 - 471 | 0x1D5 - 0x1D7 |
|
||||
|  | SYM_PILOT_LOGO_LRG_START | | Large Pilot logo | 472 - 511 | 0x1D5 - 0x1D7 |
|
||||
|
||||
_*_ Do not change the IDs of these characters
|
||||
|
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
BIN
resources/osd/analogue/default/221.png
Normal file
After Width: | Height: | Size: 199 B |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 2.2 KiB |
BIN
resources/osd/analogue/default/360.png
Normal file
After Width: | Height: | Size: 2 KiB |
BIN
resources/osd/analogue/default/469_471.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
resources/osd/analogue/default/472_511.png
Normal file
After Width: | Height: | Size: 3 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 2.2 KiB |
BIN
resources/osd/digital/default/12x18/221.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
resources/osd/digital/default/12x18/360.png
Normal file
After Width: | Height: | Size: 2 KiB |
BIN
resources/osd/digital/default/12x18/469_471.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
BIN
resources/osd/digital/default/12x18/472_511.png
Normal file
After Width: | Height: | Size: 8.7 KiB |
BIN
resources/osd/digital/default/24x36/221.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
resources/osd/digital/default/24x36/360.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
resources/osd/digital/default/24x36/469_471.png
Normal file
After Width: | Height: | Size: 3.1 KiB |
BIN
resources/osd/digital/default/24x36/472_511.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
resources/osd/digital/default/36x54/221.png
Normal file
After Width: | Height: | Size: 2.6 KiB |
BIN
resources/osd/digital/default/36x54/360.png
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
resources/osd/digital/default/36x54/469_471.png
Normal file
After Width: | Height: | Size: 3.4 KiB |
BIN
resources/osd/digital/default/36x54/472_511.png
Normal file
After Width: | Height: | Size: 20 KiB |
32
src/css/tabs/ez_tune.css
Normal file
|
@ -0,0 +1,32 @@
|
|||
.ez-tune-preview {
|
||||
background-color: #8ecae6;
|
||||
margin-left: 1em;
|
||||
margin-bottom: 1em;
|
||||
min-width: 25%;
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
.ez-tune-preview h2 {
|
||||
font-size: 1.3em;
|
||||
margin-bottom: 1em;
|
||||
margin-top: 0.5em;
|
||||
color: #303030
|
||||
}
|
||||
|
||||
.ez-tune-preview table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.ez-tune-preview table td,
|
||||
.ez-tune-preview table th {
|
||||
padding: 0.5em;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.ez-tune-preview table th {
|
||||
background-color: #3EA5D4;
|
||||
}
|
||||
|
||||
.ez-tune-preview table td {
|
||||
background-color: #A8D6EC;
|
||||
}
|
|
@ -136,8 +136,9 @@
|
|||
|
||||
.tab-magnetometer #interactive_block {
|
||||
position: absolute;
|
||||
width: calc(100% - 40px);
|
||||
height: calc(100% - 245px);
|
||||
width: calc(100% - 655px);
|
||||
height: 771px;
|
||||
min-height: calc(100% - 200px);
|
||||
background-color: #f9f9f9;
|
||||
border-radius: 5px;
|
||||
border: 1px solid #e4e4e4;
|
||||
|
@ -190,6 +191,17 @@ progress[value]::-webkit-progress-value {
|
|||
box-shadow: 0 0 3px rgba(0, 0, 0, 0.25) inset;
|
||||
}
|
||||
|
||||
.tab-magnetometer-left-wrapper {
|
||||
float:left;
|
||||
width: calc( 100% - 655px );
|
||||
}
|
||||
|
||||
.tab-magnetometer-right-wrapper {
|
||||
float:right;
|
||||
width: 600px;
|
||||
}
|
||||
|
||||
|
||||
@media only screen and (max-width: 1055px) , only screen and (max-device-width: 1055px) {
|
||||
|
||||
#magnetometer-map {
|
||||
|
|
|
@ -401,18 +401,21 @@
|
|||
/* background: #D6D6D6 linear-gradient(-45deg, rgba(255, 255, 255, .2) 10%, transparent 10%, transparent 20%, rgba(255, 255, 255, .2) 20%, rgba(255, 255, 255, .2) 30%, transparent 30%, transparent 40%, rgba(255, 255, 255, .2) 40%, rgba(255, 255, 255, .2) 50%, transparent 50%, transparent 60%, rgba(255, 255, 255, .2) 60%, rgba(255, 255, 255, .2) 70%, transparent 70%, transparent 80%, rgba(255, 255, 255, .2) 80%, rgba(255, 255, 255, .2) 90%, transparent 90%, transparent 100%, rgba(255, 255, 255, .2) 100%, transparent); */
|
||||
}
|
||||
|
||||
.pid-slider-row {
|
||||
.pid-slider-row,
|
||||
.pid-switch-row {
|
||||
display: flex;
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.pid-slider-row span {
|
||||
.pid-slider-row span,
|
||||
.pid-switch-row .label {
|
||||
margin-right: 2em;
|
||||
width: 120px;
|
||||
line-height: 22px;;
|
||||
}
|
||||
|
||||
.pid-slider-row input[type="number"] {
|
||||
.pid-slider-row input[type="number"],
|
||||
.pid-switch-row input[type="number"] {
|
||||
font-family: 'open_sansregular', 'Segoe UI', Tahoma, sans-serif;
|
||||
background-color: #fff;
|
||||
border: 1px solid #ccc;
|
||||
|
@ -422,7 +425,9 @@
|
|||
margin-right: 2em;
|
||||
}
|
||||
|
||||
.pid-slider-row input[type="range"] {
|
||||
.pid-slider-row input[type="range"],
|
||||
.pid-switch-row input[type="range"]
|
||||
{
|
||||
display: block;
|
||||
flex-grow: 100;
|
||||
}
|
||||
|
@ -436,16 +441,26 @@
|
|||
padding: 4px;
|
||||
}
|
||||
|
||||
.pid-sliders-axis[data-axis="roll"] {
|
||||
background-color: #afe4fe;
|
||||
.pid-sliders-axis[data-axis="roll"],
|
||||
.pid-sliders-axis[data-axis="0"] {
|
||||
background-color: #8ecae6;
|
||||
}
|
||||
|
||||
.pid-sliders-axis[data-axis="pitch"] {
|
||||
background-color: #C4B5FF;
|
||||
.pid-sliders-axis[data-axis="pitch"],
|
||||
.pid-sliders-axis[data-axis="1"]
|
||||
{
|
||||
background-color: #00b4d8;
|
||||
}
|
||||
|
||||
.pid-sliders-axis[data-axis="yaw"] {
|
||||
background-color: #E6B6F0;
|
||||
.pid-sliders-axis[data-axis="yaw"],
|
||||
.pid-sliders-axis[data-axis="2"]
|
||||
{
|
||||
background-color: #e9c46a;
|
||||
}
|
||||
|
||||
.pid-sliders-axis[data-axis="3"]
|
||||
{
|
||||
background-color: #f4a261;
|
||||
}
|
||||
|
||||
#pid-sliders {
|
||||
|
|
|
@ -40,6 +40,21 @@
|
|||
float: left;
|
||||
}
|
||||
|
||||
.attitude_note1 {
|
||||
position: absolute;
|
||||
left: 130px;
|
||||
top: 29px;
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
.attitude_note2 {
|
||||
position: absolute;
|
||||
left: 130px;
|
||||
top: 13px;
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
|
||||
#interactive_block a.reset {
|
||||
position: absolute;
|
||||
display: block;
|
||||
|
|
|
@ -54,28 +54,6 @@
|
|||
|
||||
</div>
|
||||
</div>
|
||||
<div class="board gui_box grey">
|
||||
<div class="gui_box_titlebar">
|
||||
<div class="spacer_box_title" data-i18n="configurationBoardAlignment"></div>
|
||||
<div class="helpicon cf_tip" data-i18n_title="configHelp2"></div>
|
||||
</div>
|
||||
<div class="spacer_box">
|
||||
<div class="info-box" data-i18n="rollPitchAdjustmentsMoved"></div>
|
||||
<div class="number">
|
||||
<input id="board_align_yaw" type="number" name="board_align_yaw" step="0.1" min="-180" max="360" />
|
||||
<div class="alignicon yaw"></div>
|
||||
<label for="board_align_yaw" data-i18n="configurationBoardAlignmentYaw"></label>
|
||||
</div>
|
||||
<div class="select" style="position: relative; top: -3px;">
|
||||
<select id="magalign" class="magalign">
|
||||
<option value="0">Default</option>
|
||||
<!-- list generated here -->
|
||||
</select>
|
||||
<div class="alignicon yaw"></div>
|
||||
<label for="magalign" data-i18n="configurationSensorAlignmentMag"></label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="config-section gui_box grey other">
|
||||
<div class="gui_box_titlebar">
|
||||
|
|
|
@ -30,12 +30,10 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
|
|||
var saveChainer = new MSPChainerClass();
|
||||
|
||||
var saveChain = [
|
||||
mspHelper.saveSensorAlignment,
|
||||
mspHelper.saveAccTrim,
|
||||
mspHelper.saveArmingConfig,
|
||||
mspHelper.saveAdvancedConfig,
|
||||
mspHelper.saveVTXConfig,
|
||||
mspHelper.saveBoardAlignment,
|
||||
mspHelper.saveCurrentMeterConfig,
|
||||
mspHelper.saveMiscV2,
|
||||
saveSettings,
|
||||
|
@ -115,14 +113,6 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
|
|||
// translate to user-selected language
|
||||
localize();
|
||||
|
||||
let alignments = FC.getSensorAlignments();
|
||||
let orientation_mag_e = $('select.magalign');
|
||||
|
||||
for (i = 0; i < alignments.length; i++) {
|
||||
orientation_mag_e.append('<option value="' + (i + 1) + '">' + alignments[i] + '</option>');
|
||||
}
|
||||
orientation_mag_e.val(SENSOR_ALIGNMENT.align_mag);
|
||||
|
||||
// VTX
|
||||
var config_vtx = $('.config-vtx');
|
||||
if (VTX_CONFIG.device_type != VTX.DEV_UNKNOWN) {
|
||||
|
@ -209,7 +199,8 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
|
|||
$('input[name="board_align_yaw"]').val((BOARD_ALIGNMENT.yaw / 10.0).toFixed(1));
|
||||
|
||||
// fill magnetometer
|
||||
$('#mag_declination').val(MISC.mag_declination);
|
||||
//UPDATE: moved to GPS tab and hidden
|
||||
//$('#mag_declination').val(MISC.mag_declination);
|
||||
|
||||
// fill battery voltage
|
||||
$('#voltagesource').val(MISC.voltage_source);
|
||||
|
@ -264,7 +255,8 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
|
|||
$i2cSpeed.change();
|
||||
|
||||
$('a.save').click(function () {
|
||||
MISC.mag_declination = parseFloat($('#mag_declination').val());
|
||||
//UPDATE: moved to GPS tab and hidden
|
||||
//MISC.mag_declination = parseFloat($('#mag_declination').val());
|
||||
|
||||
ARMING_CONFIG.auto_disarm_delay = parseInt($('input[name="autodisarmdelay"]').val());
|
||||
|
||||
|
@ -281,8 +273,6 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
|
|||
MISC.battery_capacity_critical = parseInt($('#battery_capacity_critical').val() * MISC.battery_capacity / 100);
|
||||
MISC.battery_capacity_unit = $('#battery_capacity_unit').val();
|
||||
|
||||
SENSOR_ALIGNMENT.align_mag = parseInt(orientation_mag_e.val());
|
||||
|
||||
googleAnalytics.sendEvent('Setting', 'I2CSpeed', $('#i2c_speed').children("option:selected").text());
|
||||
|
||||
googleAnalytics.sendEvent('Board', 'Accelerometer', $('#sensor-acc').children("option:selected").text());
|
||||
|
@ -300,7 +290,6 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
|
|||
helper.features.reset();
|
||||
helper.features.fromUI($('.tab-configuration'));
|
||||
helper.features.execute(function () {
|
||||
BOARD_ALIGNMENT.yaw = Math.round(parseFloat($('input[name="board_align_yaw"]').val()) * 10);
|
||||
CURRENT_METER_CONFIG.scale = parseInt($('#currentscale').val());
|
||||
CURRENT_METER_CONFIG.offset = Math.round(parseFloat($('#currentoffset').val()) * 10);
|
||||
saveChainer.execute();
|
||||
|
|
175
tabs/ez_tune.html
Normal file
|
@ -0,0 +1,175 @@
|
|||
<!--suppress ALL -->
|
||||
<div id="content-watermark"></div>
|
||||
<div class="tab-ez_tune toolbar_fixed_bottom">
|
||||
<div class="content_wrapper">
|
||||
<div class="tab_title" data-i18n="tabEzTune"></div>
|
||||
<div class="note spacebottom">
|
||||
<div class="note_spacer">
|
||||
<p i18n="ezTuneDisclaimer"></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clear-both"></div>
|
||||
<div style="display: flex;">
|
||||
|
||||
<div>
|
||||
|
||||
<div class="pid-sliders-axis" style="background-color: #2a9d8f;">
|
||||
<div style="padding: 1em;" data-i18n="ezTuneEnabledTips"></div>
|
||||
<div class="pid-switch-row">
|
||||
<span data-i18n="configurationFeatureEnabled" class="bold label"></span>
|
||||
<div class="checkbox no-border">
|
||||
<input id="ez_tune_enabled" type="checkbox" class="ez-element toggle" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="clear-both"></div>
|
||||
</div>
|
||||
|
||||
<div class="pid-sliders-axis" data-axis="roll">
|
||||
<div style="padding: 1em;" data-i18n="ezTuneFilterHzTips"></div>
|
||||
<div class="pid-slider-row">
|
||||
<span data-i18n="ezTuneFilterHz" class="bold"></span>
|
||||
<div class="number no-border">
|
||||
<input id="ez_tune_filter_hz" type="number" class="ez-element" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="clear-both"></div>
|
||||
</div>
|
||||
|
||||
<div class="pid-sliders-axis" data-axis="pitch">
|
||||
<div style="padding: 1em;" data-i18n="ezTuneAxisRatioTips"></div>
|
||||
<div class="pid-slider-row">
|
||||
|
||||
<span data-i18n="ezTuneAxisRatio" class="bold"></span>
|
||||
<div class="number no-border">
|
||||
<input id="ez_tune_axis_ratio" type="number" class="ez-element" />
|
||||
</div>
|
||||
<div class="clear-both"></div>
|
||||
</div>
|
||||
|
||||
<div style="padding: 1em;" data-i18n="ezTuneResponseTips"></div>
|
||||
<div class="pid-slider-row">
|
||||
<span data-i18n="ezTuneResponse" class="bold"></span>
|
||||
<div class="number no-border">
|
||||
<input id="ez_tune_response" type="number" class="ez-element" />
|
||||
</div>
|
||||
<div class="clear-both"></div>
|
||||
</div>
|
||||
|
||||
<div style="padding: 1em;" data-i18n="ezTuneDampingTips"></div>
|
||||
<div class="pid-slider-row">
|
||||
<span data-i18n="ezTuneDamping" class="bold"></span>
|
||||
<div class="number no-border">
|
||||
<input id="ez_tune_damping" type="number" class="ez-element" />
|
||||
</div>
|
||||
<div class="clear-both"></div>
|
||||
</div>
|
||||
|
||||
<div style="padding: 1em;" data-i18n="ezTuneStabilityTips"></div>
|
||||
<div class="pid-slider-row">
|
||||
<span data-i18n="ezTuneStability" class="bold"></span>
|
||||
<div class="number no-border">
|
||||
<input id="ez_tune_stability" type="number" class="ez-element" />
|
||||
</div>
|
||||
<div class="clear-both"></div>
|
||||
</div>
|
||||
|
||||
<div style="padding: 1em;" data-i18n="ezTuneAggressivenessTips"></div>
|
||||
<div class="pid-slider-row">
|
||||
<span data-i18n="ezTuneAggressiveness" class="bold"></span>
|
||||
<div class="number no-border">
|
||||
<input id="ez_tune_aggressiveness" type="number" class="ez-element" />
|
||||
</div>
|
||||
<div class="clear-both"></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="pid-sliders-axis" data-axis="yaw">
|
||||
<div style="padding: 1em;" data-i18n="ezTuneRateTips"></div>
|
||||
<div class="pid-slider-row">
|
||||
<span data-i18n="ezTuneRate" class="bold"></span>
|
||||
<div class="number no-border">
|
||||
<input id="ez_tune_rate" type="number" class="ez-element" />
|
||||
</div>
|
||||
<div class="clear-both"></div>
|
||||
</div>
|
||||
|
||||
<div style="padding: 1em;" data-i18n="ezTuneExpoTips"></div>
|
||||
<div class="pid-slider-row">
|
||||
<span data-i18n="ezTuneExpo" class="bold"></span>
|
||||
<div class="number no-border">
|
||||
<input id="ez_tune_expo" type="number" class="ez-element" />
|
||||
</div>
|
||||
<div class="clear-both"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="ez-tune-preview">
|
||||
<h2 data-i18n="ezTunePidPreview"></h2>
|
||||
<table>
|
||||
<tr>
|
||||
<th> </th>
|
||||
<th>P</th>
|
||||
<th>I</th>
|
||||
<th>D</th>
|
||||
<th>FF</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th data-i18n="axisRoll"></th>
|
||||
<td id="preview-roll-p"></td>
|
||||
<td id="preview-roll-i"></td>
|
||||
<td id="preview-roll-d"></td>
|
||||
<td id="preview-roll-ff"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th data-i18n="axisPitch"></th>
|
||||
<td id="preview-pitch-p"></td>
|
||||
<td id="preview-pitch-i"></td>
|
||||
<td id="preview-pitch-d"></td>
|
||||
<td id="preview-pitch-ff"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th data-i18n="axisYaw"></th>
|
||||
<td id="preview-yaw-p"></td>
|
||||
<td id="preview-yaw-i"></td>
|
||||
<td id="preview-yaw-d"></td>
|
||||
<td id="preview-yaw-ff"></td>
|
||||
</tr>
|
||||
</table>
|
||||
<h2 data-i18n="ezTuneRatePreview"></h2>
|
||||
<table>
|
||||
<tr>
|
||||
<th data-i18n="ezTuneRatePreviewAxis"></th>
|
||||
<th data-i18n="ezTuneRatePreviewRate"></th>
|
||||
<th data-i18n="ezTuneRatePreviewExpo"></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th data-i18n="axisRoll"></th>
|
||||
<td id="preview-roll-rate"></td>
|
||||
<td id="preview-roll-expo"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th data-i18n="axisPitch"></th>
|
||||
<td id="preview-pitch-rate"></td>
|
||||
<td id="preview-pitch-expo"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th data-i18n="axisYaw"></th>
|
||||
<td id="preview-yaw-rate"></td>
|
||||
<td id="preview-yaw-expo"></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="clear-both"></div>
|
||||
</div>
|
||||
<div class="clear-both"></div>
|
||||
<div class="content_toolbar">
|
||||
<div class="btn save_btn">
|
||||
<a class="update" href="#" data-i18n="pidTuning_ButtonSave"></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
161
tabs/ez_tune.js
Normal file
|
@ -0,0 +1,161 @@
|
|||
/*global chrome,helper,mspHelper*/
|
||||
'use strict';
|
||||
|
||||
TABS.ez_tune = {
|
||||
|
||||
};
|
||||
|
||||
TABS.ez_tune.initialize = function (callback) {
|
||||
|
||||
let loadChainer = new MSPChainerClass();
|
||||
|
||||
let loadChain = [
|
||||
mspHelper.loadEzTune,
|
||||
];
|
||||
|
||||
let EZ_TUNE_PID_RP_DEFAULT = [40, 75, 23, 100];
|
||||
let EZ_TUNE_PID_YAW_DEFAULT = [45, 80, 0, 100];
|
||||
|
||||
loadChain.push(mspHelper.loadRateProfileData);
|
||||
|
||||
loadChainer.setChain(loadChain);
|
||||
loadChainer.setExitPoint(load_html);
|
||||
loadChainer.execute();
|
||||
|
||||
var saveChainer = new MSPChainerClass();
|
||||
|
||||
var saveChain = [
|
||||
mspHelper.saveEzTune,
|
||||
mspHelper.saveToEeprom
|
||||
];
|
||||
|
||||
saveChainer.setChain(saveChain);
|
||||
saveChainer.setExitPoint(reboot);
|
||||
|
||||
function reboot() {
|
||||
//noinspection JSUnresolvedVariable
|
||||
GUI.log(chrome.i18n.getMessage('configurationEepromSaved'));
|
||||
GUI.tab_switch_cleanup(function () {
|
||||
MSP.send_message(MSPCodes.MSP_SET_REBOOT, false, false, reinitialize);
|
||||
});
|
||||
}
|
||||
|
||||
function reinitialize() {
|
||||
GUI.log(chrome.i18n.getMessage('deviceRebooting'));
|
||||
GUI.handleReconnect($('.tab_ez_tune a'));
|
||||
}
|
||||
|
||||
if (GUI.active_tab != 'ez_tune') {
|
||||
GUI.active_tab = 'ez_tune';
|
||||
googleAnalytics.sendAppView('Ez Tune');
|
||||
}
|
||||
|
||||
function load_html() {
|
||||
GUI.load("./tabs/ez_tune.html", Settings.processHtml(process_html));
|
||||
}
|
||||
|
||||
function getYawPidScale(input) {
|
||||
const normalized = (input - 100) * 0.01;
|
||||
|
||||
return 1.0 + (normalized * 0.5);
|
||||
}
|
||||
|
||||
function scaleRange(x, srcMin, srcMax, destMin, destMax) {
|
||||
let a = (destMax - destMin) * (x - srcMin);
|
||||
let b = srcMax - srcMin;
|
||||
return ((a / b) + destMin);
|
||||
}
|
||||
|
||||
function updatePreview() {
|
||||
|
||||
let axisRatio = $('#ez_tune_axis_ratio').val() / 100;
|
||||
let response = $('#ez_tune_response').val();
|
||||
let damping = $('#ez_tune_damping').val();
|
||||
let stability = $('#ez_tune_stability').val();
|
||||
let aggressiveness = $('#ez_tune_aggressiveness').val();
|
||||
let rate = $('#ez_tune_rate').val();
|
||||
let expo = $('#ez_tune_expo').val();
|
||||
|
||||
$('#preview-roll-p').html(Math.floor(EZ_TUNE_PID_RP_DEFAULT[0] * response / 100));
|
||||
$('#preview-roll-i').html(Math.floor(EZ_TUNE_PID_RP_DEFAULT[1] * stability / 100));
|
||||
$('#preview-roll-d').html(Math.floor(EZ_TUNE_PID_RP_DEFAULT[2] * damping / 100));
|
||||
$('#preview-roll-ff').html(Math.floor(EZ_TUNE_PID_RP_DEFAULT[3] * aggressiveness / 100));
|
||||
|
||||
$('#preview-pitch-p').html(Math.floor(axisRatio * EZ_TUNE_PID_RP_DEFAULT[0] * response / 100));
|
||||
$('#preview-pitch-i').html(Math.floor(axisRatio * EZ_TUNE_PID_RP_DEFAULT[1] * stability / 100));
|
||||
$('#preview-pitch-d').html(Math.floor(axisRatio * EZ_TUNE_PID_RP_DEFAULT[2] * damping / 100));
|
||||
$('#preview-pitch-ff').html(Math.floor(axisRatio * EZ_TUNE_PID_RP_DEFAULT[3] * aggressiveness / 100));
|
||||
|
||||
$('#preview-yaw-p').html(Math.floor(EZ_TUNE_PID_YAW_DEFAULT[0] * getYawPidScale(response)));
|
||||
$('#preview-yaw-i').html(Math.floor(EZ_TUNE_PID_YAW_DEFAULT[1] * getYawPidScale(stability)));
|
||||
$('#preview-yaw-d').html(Math.floor(EZ_TUNE_PID_YAW_DEFAULT[2] * getYawPidScale(damping)));
|
||||
$('#preview-yaw-ff').html(Math.floor(EZ_TUNE_PID_YAW_DEFAULT[3] * getYawPidScale(aggressiveness)));
|
||||
|
||||
$('#preview-roll-rate').html(Math.floor(scaleRange(rate, 0, 200, 30, 90)) * 10 + " dps");
|
||||
$('#preview-pitch-rate').html(Math.floor(scaleRange(rate, 0, 200, 30, 90)) * 10 + " dps");
|
||||
$('#preview-yaw-rate').html((Math.floor(scaleRange(rate, 0, 200, 30, 90)) - 10) * 10 + " dps");
|
||||
|
||||
$('#preview-roll-expo').html(Math.floor(scaleRange(expo, 0, 200, 40, 100)) + "%");
|
||||
$('#preview-pitch-expo').html(Math.floor(scaleRange(expo, 0, 200, 40, 100)) + "%");
|
||||
$('#preview-yaw-expo').html(Math.floor(scaleRange(expo, 0, 200, 40, 100)) + "%");
|
||||
|
||||
}
|
||||
|
||||
function process_html() {
|
||||
localize();
|
||||
|
||||
helper.tabs.init($('.tab-ez_tune'));
|
||||
helper.features.updateUI($('.tab-ez_tune'), FEATURES);
|
||||
|
||||
$("#ez_tune_enabled").prop('checked', EZ_TUNE.enabled);
|
||||
|
||||
GUI.sliderize($('#ez_tune_filter_hz'), EZ_TUNE.filterHz, 10, 300);
|
||||
GUI.sliderize($('#ez_tune_axis_ratio'), EZ_TUNE.axisRatio, 25, 175);
|
||||
GUI.sliderize($('#ez_tune_response'), EZ_TUNE.response, 0, 200);
|
||||
GUI.sliderize($('#ez_tune_damping'), EZ_TUNE.damping, 0, 200);
|
||||
GUI.sliderize($('#ez_tune_stability'), EZ_TUNE.stability, 0, 200);
|
||||
GUI.sliderize($('#ez_tune_aggressiveness'), EZ_TUNE.aggressiveness, 0, 200);
|
||||
|
||||
GUI.sliderize($('#ez_tune_rate'), EZ_TUNE.rate, 0, 200);
|
||||
GUI.sliderize($('#ez_tune_expo'), EZ_TUNE.expo, 0, 200);
|
||||
|
||||
|
||||
$('.ez-element').on('updated', function () {
|
||||
updatePreview();
|
||||
});
|
||||
|
||||
updatePreview();
|
||||
|
||||
GUI.simpleBind();
|
||||
|
||||
GUI.content_ready(callback);
|
||||
|
||||
$('a.update').on('click', function () {
|
||||
|
||||
if ($("#ez_tune_enabled").is(":checked")) {
|
||||
EZ_TUNE.enabled = 1;
|
||||
} else {
|
||||
EZ_TUNE.enabled = 0;
|
||||
}
|
||||
|
||||
EZ_TUNE.filterHz = $('#ez_tune_filter_hz').val();
|
||||
EZ_TUNE.axisRatio = $('#ez_tune_axis_ratio').val();
|
||||
EZ_TUNE.response = $('#ez_tune_response').val();
|
||||
EZ_TUNE.damping = $('#ez_tune_damping').val();
|
||||
EZ_TUNE.stability = $('#ez_tune_stability').val();
|
||||
EZ_TUNE.aggressiveness = $('#ez_tune_aggressiveness').val();
|
||||
EZ_TUNE.rate = $('#ez_tune_rate').val();
|
||||
EZ_TUNE.expo = $('#ez_tune_expo').val();
|
||||
|
||||
saveChainer.execute();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
TABS.ez_tune.cleanup = function (callback) {
|
||||
if (callback) {
|
||||
callback();
|
||||
}
|
||||
};
|
|
@ -20,7 +20,6 @@
|
|||
<label for="feature-7"><span data-i18n="featureGPS"></span></label>
|
||||
<div for="feature-7" class="helpicon cf_tip" data-i18n_title="featureGPSTip"></div>
|
||||
</div>
|
||||
<div id="nmeaWarning" data-i18n="nmeaWarning" class="warning-box"></div>
|
||||
<div class="select">
|
||||
<select id="gps_protocol" class="gps_protocol">
|
||||
<!-- list generated here -->
|
||||
|
|
|
@ -76,11 +76,6 @@ TABS.gps.initialize = function (callback) {
|
|||
|
||||
gps_protocol_e.change(function () {
|
||||
MISC.gps_type = parseInt($(this).val());
|
||||
if (MISC.gps_type == 0) {
|
||||
$('#nmeaWarning').show();
|
||||
} else {
|
||||
$('#nmeaWarning').hide();
|
||||
}
|
||||
});
|
||||
|
||||
gps_protocol_e.val(MISC.gps_type);
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
</div>
|
||||
<div class="community">
|
||||
<ul class="communityDiscordSupport"><a href="https://discord.gg/peg2hhbYwN" target="_blank"><i class="fab fa-discord" aria-hidden="true"></i><span i18n="communityDiscordServer"></span></a></ul>
|
||||
<ul class="communityTelegramSupport"><a href="https://t.me/INAVFlight" target="_blank"><i class="fab fa-telegram" aria-hidden="true"></i><span i18n="communityTelegramSupport"></span></a></ul>
|
||||
<!-- <ul class="communityTelegramSupport"><a href="https://t.me/INAVFlight" target="_blank"><i class="fab fa-telegram" aria-hidden="true"></i><span i18n="communityTelegramSupport"></span></a></ul> -->
|
||||
<ul class="communityFacebookSupport"><a href="https://www.facebook.com/groups/INAVOfficial" target="_blank"><i class="fab fa-facebook" aria-hidden="true"></i><span i18n="communityFacebookSupport"></span></a></ul>
|
||||
</div>
|
||||
<div class="content_mid">
|
||||
|
@ -16,6 +16,8 @@
|
|||
<div class="wrap">
|
||||
<h2 i18n="defaultWelcomeHead"></h2>
|
||||
<div i18n="defaultWelcomeText"></div>
|
||||
<h2 i18n="defaultWelcomeHead2" style="margin-top: 1em;"></h2>
|
||||
<div i18n="defaultWelcomeText2"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="column half text2">
|
||||
|
@ -25,15 +27,6 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content_foot">
|
||||
<div class="sponsors">
|
||||
<div class="title" i18n="defaultSponsorsHead"></div>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="http://www.mateksys.com" title="www.mateksys.com" target="_blank"><img src="./images/partner/mateksys.png" alt="MATEK Systems" height="35" /></a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content_foot"></div>
|
||||
</div>
|
||||
</div>
|
|
@ -1,109 +1,188 @@
|
|||
<div class="tab-magnetometer">
|
||||
<div class="content_wrapper" style="height: calc(80% - 40px)">
|
||||
<div class="tab-magnetometer toolbar_fixed_bottom">
|
||||
<div class="content_wrapper">
|
||||
<div class="tab_title" data-i18n="tabMagnetometer">Magnetometer</div>
|
||||
<div class="note spacebottom">
|
||||
<div class="note_spacer">
|
||||
<p i18n="magnetometerHelp"></p>
|
||||
</div>
|
||||
</div>
|
||||
<div style="height: calc(100% - 150px);">
|
||||
<div id="model">
|
||||
<div class="model-and-info">
|
||||
<div id="interactive_block">
|
||||
<div id="canvas_wrapper">
|
||||
<canvas id="canvas"></canvas>
|
||||
<div class="cf_column tab-magnetometer-left-wrapper">
|
||||
<div class="model-and-info">
|
||||
<div id="interactive_block">
|
||||
<div id="canvas_wrapper">
|
||||
<canvas id="canvas"></canvas>
|
||||
<div class="attitude_info">
|
||||
<dl>
|
||||
<dt>Heading:</dt>
|
||||
<dd class="heading"> </dd>
|
||||
<dt>Pitch:</dt>
|
||||
<dd class="pitch"> </dd>
|
||||
<dt>Roll:</dt>
|
||||
<dd class="roll"> </dd>
|
||||
</dl>
|
||||
</div>
|
||||
<a class="reset" href="#" data-i18n="initialSetupButtonResetZaxis"></a>
|
||||
<div class="attitude_note1" >(Values according to <b>saved</b> settings)</div>
|
||||
<div class="attitude_note2" >(North: 0, East: 90, South: 180, West: 270)</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="config-section gui_box grey">
|
||||
<div class="spacer_box">
|
||||
<div id="alignment-info" class="info-box">
|
||||
<span data-i18n="magnetometerInfo"></span>
|
||||
</div>
|
||||
<div class="select" style="display: flex; justify-content: left;">
|
||||
<select id="magalign" class="magalign">
|
||||
<option value="0">Default</option>
|
||||
<!-- list generated here -->
|
||||
</select>
|
||||
<label for="magalign" data-i18n="magnetometerOrientationPreset"></label>
|
||||
</div>
|
||||
<div class="select" style="display: flex; justify-content: left;">
|
||||
<select id="element_to_show">
|
||||
<option value="0" selected>Magnetometer</option>
|
||||
<option value="1">XYZ</option>
|
||||
<!-- list generated here -->
|
||||
</select>
|
||||
<label for="element_to_show" data-i18n="magnetometerElementToShow"></label>
|
||||
</div>
|
||||
<div class="cf_column tab-magnetometer-right-wrapper">
|
||||
<div class="config-section gui_box grey">
|
||||
<div class="spacer_box">
|
||||
<div id="board-alignment-info" class="info-box">
|
||||
<span data-i18n="boardInfo"></span>
|
||||
</div>
|
||||
|
||||
<table class="axis-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<td style="width: 5%; padding-bottom: 10px;">
|
||||
<p class="table-title">
|
||||
<span data-i18n="axisTableTitleAxis"></span>
|
||||
</p>
|
||||
</td>
|
||||
<td style="width: 90%; padding-bottom: 10px;">
|
||||
<p class="table-title">
|
||||
<span data-i18n="axisTableTitleSlider"></span>
|
||||
</p>
|
||||
</td>
|
||||
<td style="width: 5%; padding-bottom: 10px;">
|
||||
<a class="table-title">
|
||||
<span data-i18n="axisTableTitleValue"></span>
|
||||
</a>
|
||||
<table class="axis-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<td style="width: 5%; padding-bottom: 10px;">
|
||||
<p class="table-title">
|
||||
<span data-i18n="axisTableTitleAxis"></span>
|
||||
</p>
|
||||
</td>
|
||||
<td style="width: 90%; padding-bottom: 10px;">
|
||||
<p class="table-title">
|
||||
<span data-i18n="axisTableTitleSlider"></span>
|
||||
</p>
|
||||
</td>
|
||||
<td style="width: 5%; padding-bottom: 10px;">
|
||||
<a class="table-title">
|
||||
<span data-i18n="axisTableTitleValue"></span>
|
||||
</a>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="info">
|
||||
<p class="title" data-i18n="configurationSensorAlignmentMagPitch"></p>
|
||||
</td>
|
||||
<td>
|
||||
<div id="roll_slider" class="slider"></div>
|
||||
</td>
|
||||
<td>
|
||||
<input type="number" id="alignRoll" class="tab-magnetometer" data-setting="tz_offset" data-setting-multiplier="1" step="1" min="-180" max="180" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="info">
|
||||
<p class="title" data-i18n="configurationSensorAlignmentMagRoll"></p>
|
||||
</td>
|
||||
<td>
|
||||
<div id="pitch_slider" class="slider"></div>
|
||||
</td>
|
||||
<td>
|
||||
<input type="number" id="alignPitch" class="tab-magnetometer" data-setting="tz_offset" data-setting-multiplier="1" step="1" min="-180" max="180" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="info">
|
||||
<p class="title" data-i18n="configurationSensorAlignmentMagYaw"></p>
|
||||
</td>
|
||||
<td>
|
||||
<div id="yaw_slider" class="slider"></div>
|
||||
</td>
|
||||
<td>
|
||||
<input type="number" id="alignYaw" class="tab-magnetometer" data-setting="tz_offset" data-setting-multiplier="1" step="1" min="-180" max="360" />
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="info">
|
||||
<p class="title" data-i18n="configurationSensorAlignmentMagRoll"></p>
|
||||
</td>
|
||||
<td>
|
||||
<div id="board_roll_slider" class="slider"></div>
|
||||
</td>
|
||||
<td>
|
||||
<input type="number" id="boardAlignRoll" class="tab-magnetometer" data-setting="tz_offset" data-setting-multiplier="1" step="1" min="-180" max="360" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="info">
|
||||
<p class="title" data-i18n="configurationSensorAlignmentMagPitch" style="margin: 5px"></p>
|
||||
</td>
|
||||
<td>
|
||||
<div id="board_pitch_slider" class="slider"></div>
|
||||
</td>
|
||||
<td>
|
||||
<input type="number" id="boardAlignPitch" class="tab-magnetometer" data-setting="tz_offset" data-setting-multiplier="1" step="1" min="-180" max="360" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="info">
|
||||
<p class="title" data-i18n="configurationSensorAlignmentMagYaw"></p>
|
||||
</td>
|
||||
<td>
|
||||
<div id="board_yaw_slider" class="slider"></div>
|
||||
</td>
|
||||
<td>
|
||||
<input type="number" id="boardAlignYaw" class="tab-magnetometer" data-setting="tz_offset" data-setting-multiplier="1" step="1" min="-180" max="360" />
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="config-section gui_box grey">
|
||||
<div class="spacer_box">
|
||||
<div id="alignment-info" class="info-box">
|
||||
<span data-i18n="magnetometerInfo"></span>
|
||||
</div>
|
||||
<div class="select" style="display: flex; justify-content: left;">
|
||||
<select id="magalign" class="magalign">
|
||||
<option value="0">Default</option>
|
||||
<!-- list generated here -->
|
||||
</select>
|
||||
<label for="magalign" data-i18n="magnetometerOrientationPreset"></label>
|
||||
</div>
|
||||
<div class="select" style="display: flex; justify-content: left;">
|
||||
<select id="element_to_show">
|
||||
<option value="0" selected>Magnetometer</option>
|
||||
<option value="1">XYZ</option>
|
||||
<!-- list generated here -->
|
||||
</select>
|
||||
<label for="element_to_show" data-i18n="magnetometerElementToShow"></label>
|
||||
</div>
|
||||
|
||||
<table class="axis-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<td style="width: 5%; padding-bottom: 10px;">
|
||||
<p class="table-title">
|
||||
<span data-i18n="axisTableTitleAxis"></span>
|
||||
</p>
|
||||
</td>
|
||||
<td style="width: 90%; padding-bottom: 10px;">
|
||||
<p class="table-title">
|
||||
<span data-i18n="axisTableTitleSlider"></span>
|
||||
</p>
|
||||
</td>
|
||||
<td style="width: 5%; padding-bottom: 10px;">
|
||||
<a class="table-title">
|
||||
<span data-i18n="axisTableTitleValue"></span>
|
||||
</a>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="info">
|
||||
<p class="title" data-i18n="configurationSensorAlignmentMagRoll"></p>
|
||||
</td>
|
||||
<td>
|
||||
<div id="roll_slider" class="slider"></div>
|
||||
</td>
|
||||
<td>
|
||||
<input type="number" id="alignRoll" class="tab-magnetometer" data-setting="tz_offset" data-setting-multiplier="1" step="1" min="-180" max="360" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="info">
|
||||
<p class="title" data-i18n="configurationSensorAlignmentMagPitch" style="margin: 5px"></p>
|
||||
</td>
|
||||
<td>
|
||||
<div id="pitch_slider" class="slider"></div>
|
||||
</td>
|
||||
<td>
|
||||
<input type="number" id="alignPitch" class="tab-magnetometer" data-setting="tz_offset" data-setting-multiplier="1" step="1" min="-180" max="360" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="info">
|
||||
<p class="title" data-i18n="configurationSensorAlignmentMagYaw"></p>
|
||||
</td>
|
||||
<td>
|
||||
<div id="yaw_slider" class="slider"></div>
|
||||
</td>
|
||||
<td>
|
||||
<input type="number" id="alignYaw" class="tab-magnetometer" data-setting="tz_offset" data-setting-multiplier="1" step="1" min="-180" max="360" />
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content_toolbar">
|
||||
<div class="btn save_btn">
|
||||
<a class="save" href="#" data-i18n="configurationButtonSave"></a>
|
||||
</div>
|
||||
<div class="clear-both"></div>
|
||||
</div>
|
||||
<div class="content_toolbar supported hide">
|
||||
<div class="btn save_btn">
|
||||
<a class="save" href="#" data-i18n="configurationButtonSave"></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div id="tab-auxiliary-templates">
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
'use strict';
|
||||
/*global chrome,GUI,TABS,nwdialog,$*/
|
||||
/*global chrome,GUI,BOARD_ALIGNMENT,TABS,nwdialog,helper,$*/
|
||||
|
||||
TABS.magnetometer = {};
|
||||
|
||||
|
@ -18,6 +18,12 @@ TABS.magnetometer.initialize = function (callback) {
|
|||
yaw: 0
|
||||
};
|
||||
|
||||
self.boardAlignmentConfig = {
|
||||
pitch: 0,
|
||||
roll: 0,
|
||||
yaw: 0
|
||||
};
|
||||
|
||||
self.pageElements = {};
|
||||
self.isSavePreset = true;
|
||||
self.showMagnetometer = true;
|
||||
|
@ -28,6 +34,13 @@ TABS.magnetometer.initialize = function (callback) {
|
|||
|
||||
var loadChain = [
|
||||
mspHelper.loadMixerConfig,
|
||||
mspHelper.loadBoardAlignment,
|
||||
function (callback) {
|
||||
self.boardAlignmentConfig.pitch = Math.round(BOARD_ALIGNMENT.pitch / 10);
|
||||
self.boardAlignmentConfig.roll = Math.round(BOARD_ALIGNMENT.roll / 10);
|
||||
self.boardAlignmentConfig.yaw = Math.round(BOARD_ALIGNMENT.yaw / 10);
|
||||
callback();
|
||||
},
|
||||
mspHelper.loadSensorAlignment,
|
||||
// Pitch and roll must be inverted
|
||||
function (callback) {
|
||||
|
@ -37,7 +50,7 @@ TABS.magnetometer.initialize = function (callback) {
|
|||
},
|
||||
function (callback) {
|
||||
mspHelper.getSetting("align_mag_pitch").then(function (data) {
|
||||
self.alignmentConfig.pitch = (parseInt(data.value, 10) / 10) - 180;
|
||||
self.alignmentConfig.pitch = parseInt(data.value, 10) / 10;
|
||||
}).then(callback)
|
||||
},
|
||||
function (callback) {
|
||||
|
@ -51,12 +64,27 @@ TABS.magnetometer.initialize = function (callback) {
|
|||
loadChainer.setExitPoint(load_html);
|
||||
loadChainer.execute();
|
||||
|
||||
function areAnglesZero() {
|
||||
return self.alignmentConfig.pitch === 0 && self.alignmentConfig.roll === 0 && self.alignmentConfig.yaw === 0
|
||||
}
|
||||
|
||||
function isBoardAlignmentZero() {
|
||||
return (self.boardAlignmentConfig.pitch == 0 ) && (self.boardAlignmentConfig.roll == 0 ) && (self.boardAlignmentConfig.yaw == 0);
|
||||
}
|
||||
|
||||
//========================
|
||||
// Save chain
|
||||
// =======================
|
||||
var saveChainer = new MSPChainerClass();
|
||||
|
||||
var saveChain = [
|
||||
function (callback) {
|
||||
BOARD_ALIGNMENT.pitch = self.boardAlignmentConfig.pitch * 10;
|
||||
BOARD_ALIGNMENT.roll = self.boardAlignmentConfig.roll * 10;
|
||||
BOARD_ALIGNMENT.yaw = self.boardAlignmentConfig.yaw * 10;
|
||||
callback();
|
||||
},
|
||||
mspHelper.saveBoardAlignment,
|
||||
// Magnetometer alignment
|
||||
function (callback) {
|
||||
let orientation_mag_e = $('select.magalign');
|
||||
|
@ -65,7 +93,7 @@ TABS.magnetometer.initialize = function (callback) {
|
|||
},
|
||||
mspHelper.saveSensorAlignment,
|
||||
// Pitch/Roll/Yaw
|
||||
// Pitch and roll must be inverted
|
||||
// Pitch and roll must be inverted - ???
|
||||
function (callback) {
|
||||
if (self.isSavePreset)
|
||||
mspHelper.setSetting("align_mag_roll", 0, callback);
|
||||
|
@ -76,14 +104,19 @@ TABS.magnetometer.initialize = function (callback) {
|
|||
if (self.isSavePreset)
|
||||
mspHelper.setSetting("align_mag_pitch", 0, callback);
|
||||
else
|
||||
mspHelper.setSetting("align_mag_pitch", (180 + self.alignmentConfig.pitch) * 10, callback);
|
||||
mspHelper.setSetting("align_mag_pitch", self.alignmentConfig.pitch * 10, callback);
|
||||
|
||||
},
|
||||
function (callback) {
|
||||
if (self.isSavePreset)
|
||||
mspHelper.setSetting("align_mag_yaw", 0, callback);
|
||||
else
|
||||
mspHelper.setSetting("align_mag_yaw", self.alignmentConfig.yaw * 10, callback);
|
||||
else {
|
||||
var fix = 0;
|
||||
if ( areAnglesZero() ) {
|
||||
fix = 1; //if all angles are 0, then we have to save yaw = 1 (0.1 deg) to enforce usage of angles, not a usage of preset
|
||||
}
|
||||
mspHelper.setSetting("align_mag_yaw", self.alignmentConfig.yaw * 10 + fix, callback);
|
||||
}
|
||||
},
|
||||
mspHelper.saveToEeprom
|
||||
];
|
||||
|
@ -117,35 +150,98 @@ TABS.magnetometer.initialize = function (callback) {
|
|||
return arr;
|
||||
}
|
||||
|
||||
function toUpperRange(input, max) {
|
||||
while (input > max) input -= 360;
|
||||
while (input + 360 <= max) input += 360;
|
||||
return input;
|
||||
}
|
||||
|
||||
/*
|
||||
Returns pitch, roll and yaw in degree by the id of a preset.
|
||||
Degree are the ones used in the slider
|
||||
*/
|
||||
function getAxisDegreeWithPreset(selectedPreset) {
|
||||
//pitch, roll, yaw
|
||||
switch (selectedPreset) {
|
||||
case 1: //CW0_DEG = 1
|
||||
return [180, 0, 0];
|
||||
case 2: //CW90_DEG = 2
|
||||
return [180, 0, 90];
|
||||
case 3: //CW180_DEG = 3
|
||||
return [180, 0, 180];
|
||||
case 4: //CW270_DEG = 4
|
||||
return [180, 0, 270];
|
||||
case 5: //CW0_DEG_FLIP = 5
|
||||
return [0, 0, 0];
|
||||
case 6: //CW90_DEG_FLIP = 5
|
||||
case 2: //CW90_DEG = 2
|
||||
return [0, 0, 90];
|
||||
case 7: //CW180_DEG_FLIP = 5
|
||||
case 3: //CW180_DEG = 3
|
||||
return [0, 0, 180];
|
||||
case 4: //CW270_DEG = 4
|
||||
return [0, 0, 270];
|
||||
case 5: //CW0_DEG_FLIP = 5
|
||||
return [180, 0, 0];
|
||||
case 6: //CW90_DEG_FLIP = 5
|
||||
return [180, 0, 90];
|
||||
case 7: //CW180_DEG_FLIP = 5
|
||||
return [180, 0, 180];
|
||||
case 0: //ALIGN_DEFAULT = 0
|
||||
case 8: //CW270_DEG_FLIP = 5
|
||||
default://If not recognized, returns defualt
|
||||
return [0, 0, 270];
|
||||
return [180, 0, 270];
|
||||
}
|
||||
}
|
||||
|
||||
function isUsingAPreset() {
|
||||
return self.alignmentConfig.pitch === -180 && self.alignmentConfig.roll === 0 && self.alignmentConfig.yaw === 0
|
||||
function getAxisDegreeWithPresetAndBoardOrientation(selectedPreset) {
|
||||
var degree = getAxisDegreeWithPreset(selectedPreset);
|
||||
|
||||
if (isBoardAlignmentZero()) {
|
||||
return degree;
|
||||
}
|
||||
|
||||
//degree[0] - pitch
|
||||
//degree[1] - roll
|
||||
//degree[2] - yaw
|
||||
//-(pitch-180), -180 - yaw, roll
|
||||
var magRotation = new THREE.Euler(-THREE.Math.degToRad(degree[0]-180), THREE.Math.degToRad(-180 - degree[2]), THREE.Math.degToRad(degree[1]), 'YXZ');
|
||||
var matrix = (new THREE.Matrix4()).makeRotationFromEuler(magRotation);
|
||||
|
||||
var boardRotation = new THREE.Euler( THREE.Math.degToRad( -self.boardAlignmentConfig.pitch ), THREE.Math.degToRad( -self.boardAlignmentConfig.yaw ), THREE.Math.degToRad( -self.boardAlignmentConfig.roll ), 'YXZ');
|
||||
var matrix1 = (new THREE.Matrix4()).makeRotationFromEuler(boardRotation);
|
||||
|
||||
matrix.premultiply(matrix1);
|
||||
|
||||
var euler = new THREE.Euler();
|
||||
euler.setFromRotationMatrix(matrix, 'YXZ');
|
||||
|
||||
var pitch = toUpperRange( Math.round( THREE.Math.radToDeg(-euler.x)) + 180, 180 );
|
||||
var yaw = toUpperRange( Math.round( -180 - THREE.Math.radToDeg(euler.y)), 359 );
|
||||
var roll = toUpperRange( Math.round( THREE.Math.radToDeg(euler.z)), 180 );
|
||||
|
||||
return [pitch, roll, yaw];
|
||||
}
|
||||
|
||||
function updateMagOrientationWithPreset() {
|
||||
if (self.isSavePreset) {
|
||||
const degrees = getAxisDegreeWithPresetAndBoardOrientation(SENSOR_ALIGNMENT.align_mag);
|
||||
presetUpdated(degrees);
|
||||
}
|
||||
}
|
||||
|
||||
function updateBoardRollAxis(value) {
|
||||
self.boardAlignmentConfig.roll = Number(value);
|
||||
self.pageElements.board_roll_slider.val(self.boardAlignmentConfig.roll);
|
||||
self.pageElements.orientation_board_roll.val(self.boardAlignmentConfig.roll);
|
||||
updateMagOrientationWithPreset();
|
||||
self.render3D();
|
||||
}
|
||||
|
||||
function updateBoardPitchAxis(value) {
|
||||
self.boardAlignmentConfig.pitch = Number(value);
|
||||
self.pageElements.board_pitch_slider.val(self.boardAlignmentConfig.pitch);
|
||||
self.pageElements.orientation_board_pitch.val(self.boardAlignmentConfig.pitch);
|
||||
updateMagOrientationWithPreset();
|
||||
self.render3D();
|
||||
}
|
||||
|
||||
function updateBoardYawAxis(value) {
|
||||
self.boardAlignmentConfig.yaw = Number(value);
|
||||
self.pageElements.board_yaw_slider.val(self.boardAlignmentConfig.yaw);
|
||||
self.pageElements.orientation_board_yaw.val(self.boardAlignmentConfig.yaw);
|
||||
updateMagOrientationWithPreset();
|
||||
self.render3D();
|
||||
}
|
||||
|
||||
//Called when roll values change
|
||||
|
@ -172,10 +268,22 @@ TABS.magnetometer.initialize = function (callback) {
|
|||
self.render3D();
|
||||
}
|
||||
|
||||
//Called when a preset is selected
|
||||
function presetUpdated(degrees) {
|
||||
function enableSavePreset() {
|
||||
self.isSavePreset = true;
|
||||
self.pageElements.orientation_mag_e.css("opacity", 1);
|
||||
self.pageElements.orientation_mag_e.css("text-decoration", "");
|
||||
}
|
||||
|
||||
function disableSavePreset() {
|
||||
self.isSavePreset = false;
|
||||
self.pageElements.orientation_mag_e.css("opacity", 0.5);
|
||||
self.pageElements.orientation_mag_e.css("text-decoration", "line-through");
|
||||
}
|
||||
|
||||
|
||||
//Called when a preset is selected
|
||||
function presetUpdated(degrees) {
|
||||
enableSavePreset();
|
||||
updatePitchAxis(degrees[0]);
|
||||
updateRollAxis(degrees[1]);
|
||||
updateYawAxis(degrees[2]);
|
||||
|
@ -183,12 +291,21 @@ TABS.magnetometer.initialize = function (callback) {
|
|||
|
||||
|
||||
function process_html() {
|
||||
|
||||
localize();
|
||||
|
||||
// initialize 3D
|
||||
self.initialize3D();
|
||||
|
||||
let alignments = FC.getSensorAlignments();
|
||||
|
||||
self.pageElements.orientation_board_roll = $('#boardAlignRoll');
|
||||
self.pageElements.orientation_board_pitch = $('#boardAlignPitch');
|
||||
self.pageElements.orientation_board_yaw = $('#boardAlignYaw');
|
||||
self.pageElements.board_roll_slider = $('#board_roll_slider');
|
||||
self.pageElements.board_pitch_slider = $('#board_pitch_slider');
|
||||
self.pageElements.board_yaw_slider = $('#board_yaw_slider');
|
||||
|
||||
self.pageElements.orientation_mag_e = $('select.magalign');
|
||||
self.pageElements.orientation_mag_roll = $('#alignRoll');
|
||||
self.pageElements.orientation_mag_pitch = $('#alignPitch');
|
||||
|
@ -197,28 +314,102 @@ TABS.magnetometer.initialize = function (callback) {
|
|||
self.pageElements.pitch_slider = $('#pitch_slider');
|
||||
self.pageElements.yaw_slider = $('#yaw_slider');
|
||||
|
||||
self.roll_e = $('dd.roll'),
|
||||
self.pitch_e = $('dd.pitch'),
|
||||
self.heading_e = $('dd.heading');
|
||||
|
||||
for (i = 0; i < alignments.length; i++) {
|
||||
self.pageElements.orientation_mag_e.append('<option value="' + (i + 1) + '">' + alignments[i] + '</option>');
|
||||
}
|
||||
self.pageElements.orientation_mag_e.val(SENSOR_ALIGNMENT.align_mag);
|
||||
|
||||
if (isUsingAPreset()) {
|
||||
if (areAnglesZero()) {
|
||||
//If using a preset, checking if custom values are equal to 0
|
||||
//Update the slider, but don't save the value until they will be not modified.
|
||||
const degrees = getAxisDegreeWithPreset(SENSOR_ALIGNMENT.align_mag);
|
||||
const degrees = getAxisDegreeWithPresetAndBoardOrientation(SENSOR_ALIGNMENT.align_mag);
|
||||
presetUpdated(degrees);
|
||||
}
|
||||
else {
|
||||
updateRollAxis(self.alignmentConfig.roll);
|
||||
updatePitchAxis(self.alignmentConfig.pitch);
|
||||
updateYawAxis(self.alignmentConfig.yaw);
|
||||
self.pageElements.orientation_mag_e.css("opacity", 0.5);
|
||||
disableSavePreset();
|
||||
}
|
||||
|
||||
|
||||
self.pageElements.orientation_board_roll.change(function () {
|
||||
updateBoardRollAxis(clamp(this, -180, 360));
|
||||
});
|
||||
|
||||
self.pageElements.orientation_board_pitch.change(function () {
|
||||
updateBoardPitchAxis(clamp(this, -180, 360));
|
||||
});
|
||||
|
||||
self.pageElements.orientation_board_yaw.change(function () {
|
||||
updateBoardYawAxis(clamp(this, -180, 360));
|
||||
});
|
||||
|
||||
self.pageElements.board_roll_slider.noUiSlider({
|
||||
start: [self.boardAlignmentConfig.roll],
|
||||
range: {
|
||||
'min': [-180],
|
||||
'max': [360]
|
||||
},
|
||||
step: 1,
|
||||
});
|
||||
self.pageElements.board_roll_slider.noUiSlider_pips({
|
||||
mode: 'values',
|
||||
values: generateRange(-180, 360, 45),
|
||||
density: 4,
|
||||
stepped: true
|
||||
});
|
||||
|
||||
self.pageElements.board_pitch_slider.noUiSlider({
|
||||
start: [self.boardAlignmentConfig.pitch],
|
||||
range: {
|
||||
'min': [-180],
|
||||
'max': [360]
|
||||
},
|
||||
step: 1,
|
||||
});
|
||||
self.pageElements.board_pitch_slider.noUiSlider_pips({
|
||||
mode: 'values',
|
||||
values: generateRange(-180, 360, 45),
|
||||
density: 4,
|
||||
stepped: true
|
||||
});
|
||||
|
||||
self.pageElements.board_yaw_slider.noUiSlider({
|
||||
start: [self.boardAlignmentConfig.yaw],
|
||||
range: {
|
||||
'min': [-180],
|
||||
'max': [360]
|
||||
},
|
||||
step: 1,
|
||||
});
|
||||
self.pageElements.board_yaw_slider.noUiSlider_pips({
|
||||
mode: 'values',
|
||||
values: generateRange(-180, 360, 45),
|
||||
density: 4,
|
||||
stepped: true
|
||||
});
|
||||
|
||||
|
||||
self.pageElements.board_pitch_slider.Link('lower').to((e) => {
|
||||
updateBoardPitchAxis(e);
|
||||
});
|
||||
self.pageElements.board_roll_slider.Link('lower').to((e) => {
|
||||
updateBoardRollAxis(e);
|
||||
});
|
||||
self.pageElements.board_yaw_slider.Link('lower').to((e) => {
|
||||
updateBoardYawAxis(e);
|
||||
});
|
||||
|
||||
const elementToShow = $("#element_to_show");
|
||||
elementToShow.change(function () {
|
||||
const value = parseInt($(this).val());
|
||||
self.showMagnetometer = (value == 0);
|
||||
self.render3D();
|
||||
});
|
||||
|
||||
function clamp(input, min, max) {
|
||||
|
@ -227,28 +418,28 @@ TABS.magnetometer.initialize = function (callback) {
|
|||
|
||||
self.pageElements.orientation_mag_e.change(function () {
|
||||
SENSOR_ALIGNMENT.align_mag = parseInt($(this).val());
|
||||
const degrees = getAxisDegreeWithPreset(SENSOR_ALIGNMENT.align_mag);
|
||||
const degrees = getAxisDegreeWithPresetAndBoardOrientation(SENSOR_ALIGNMENT.align_mag);
|
||||
presetUpdated(degrees);
|
||||
});
|
||||
|
||||
self.pageElements.orientation_mag_e.on('mousedown', function () {
|
||||
const degrees = getAxisDegreeWithPresetAndBoardOrientation(SENSOR_ALIGNMENT.align_mag);
|
||||
presetUpdated(degrees);
|
||||
});
|
||||
|
||||
self.pageElements.orientation_mag_roll.change(function () {
|
||||
self.isSavePreset = false;
|
||||
self.pageElements.orientation_mag_e.css("opacity", 0.5);
|
||||
updateRollAxis(clamp(this, -180, 180));
|
||||
disableSavePreset();
|
||||
updateRollAxis(clamp(this, -180, 360));
|
||||
});
|
||||
|
||||
self.pageElements.orientation_mag_pitch.change(function () {
|
||||
self.isSavePreset = false;
|
||||
self.pageElements.orientation_mag_e.css("opacity", 0.5);
|
||||
updatePitchAxis(clamp(this, -180, 180));
|
||||
|
||||
disableSavePreset();
|
||||
updatePitchAxis(clamp(this, -180, 360));
|
||||
});
|
||||
|
||||
self.pageElements.orientation_mag_yaw.change(function () {
|
||||
self.isSavePreset = false;
|
||||
self.pageElements.orientation_mag_e.css("opacity", 0.5);
|
||||
disableSavePreset();
|
||||
updateYawAxis(clamp(this, -180, 360));
|
||||
|
||||
});
|
||||
|
||||
$('a.save').click(function () {
|
||||
|
@ -259,13 +450,13 @@ TABS.magnetometer.initialize = function (callback) {
|
|||
start: [self.alignmentConfig.roll],
|
||||
range: {
|
||||
'min': [-180],
|
||||
'max': [180]
|
||||
'max': [360]
|
||||
},
|
||||
step: 1,
|
||||
});
|
||||
self.pageElements.roll_slider.noUiSlider_pips({
|
||||
mode: 'values',
|
||||
values: generateRange(-180, 180, 15),
|
||||
values: generateRange(-180, 360, 45),
|
||||
density: 4,
|
||||
stepped: true
|
||||
});
|
||||
|
@ -274,13 +465,13 @@ TABS.magnetometer.initialize = function (callback) {
|
|||
start: [self.alignmentConfig.pitch],
|
||||
range: {
|
||||
'min': [-180],
|
||||
'max': [180]
|
||||
'max': [360]
|
||||
},
|
||||
step: 1,
|
||||
});
|
||||
self.pageElements.pitch_slider.noUiSlider_pips({
|
||||
mode: 'values',
|
||||
values: generateRange(-180, 180, 15),
|
||||
values: generateRange(-180, 360, 45),
|
||||
density: 4,
|
||||
stepped: true
|
||||
});
|
||||
|
@ -291,7 +482,7 @@ TABS.magnetometer.initialize = function (callback) {
|
|||
'min': [-180],
|
||||
'max': [360]
|
||||
},
|
||||
step: 45,
|
||||
step: 1,
|
||||
});
|
||||
self.pageElements.yaw_slider.noUiSlider_pips({
|
||||
mode: 'values',
|
||||
|
@ -300,6 +491,7 @@ TABS.magnetometer.initialize = function (callback) {
|
|||
stepped: true
|
||||
});
|
||||
|
||||
|
||||
self.pageElements.pitch_slider.Link('lower').to((e) => {
|
||||
updatePitchAxis(e);
|
||||
});
|
||||
|
@ -310,19 +502,31 @@ TABS.magnetometer.initialize = function (callback) {
|
|||
updateYawAxis(e);
|
||||
});
|
||||
|
||||
self.pageElements.pitch_slider.change((e) => {
|
||||
self.isSavePreset = false;
|
||||
self.pageElements.orientation_mag_e.css("opacity", 0.5);
|
||||
self.pageElements.pitch_slider.on('slide', (e) => {
|
||||
disableSavePreset();
|
||||
});
|
||||
self.pageElements.roll_slider.change((e) => {
|
||||
self.isSavePreset = false;
|
||||
self.pageElements.orientation_mag_e.css("opacity", 0.5);
|
||||
self.pageElements.roll_slider.on('slide', (e) => {
|
||||
disableSavePreset();
|
||||
});
|
||||
self.pageElements.yaw_slider.change((e) => {
|
||||
self.isSavePreset = false;
|
||||
self.pageElements.orientation_mag_e.css("opacity", 0.5);
|
||||
self.pageElements.yaw_slider.on('slide', (e) => {
|
||||
disableSavePreset();
|
||||
});
|
||||
|
||||
function get_fast_data() {
|
||||
if (helper.mspQueue.shouldDrop()) {
|
||||
return;
|
||||
}
|
||||
|
||||
MSP.send_message(MSPCodes.MSP_ATTITUDE, false, false, function () {
|
||||
self.roll_e.text(chrome.i18n.getMessage('initialSetupAttitude', [SENSOR_DATA.kinematics[0]]));
|
||||
self.pitch_e.text(chrome.i18n.getMessage('initialSetupAttitude', [SENSOR_DATA.kinematics[1]]));
|
||||
self.heading_e.text(chrome.i18n.getMessage('initialSetupAttitude', [SENSOR_DATA.kinematics[2]]));
|
||||
self.render3D();
|
||||
});
|
||||
}
|
||||
|
||||
helper.mspBalancedInterval.add('setup_data_pull_fast', 40, 1, get_fast_data);
|
||||
|
||||
GUI.content_ready(callback);
|
||||
}
|
||||
|
||||
|
@ -341,6 +545,7 @@ TABS.magnetometer.initialize3D = function () {
|
|||
scene,
|
||||
gps,
|
||||
xyz,
|
||||
fc,
|
||||
useWebGlRenderer = false;
|
||||
|
||||
canvas = $('.model-and-info #canvas');
|
||||
|
@ -385,13 +590,27 @@ TABS.magnetometer.initialize3D = function () {
|
|||
|
||||
this.render3D = function () {
|
||||
|
||||
if (!gps || !xyz)
|
||||
if (!gps || !xyz || !fc)
|
||||
return;
|
||||
|
||||
gps.visible = self.showMagnetometer;
|
||||
xyz.visible = !self.showMagnetometer;
|
||||
gps.rotation.set(-THREE.Math.degToRad(self.alignmentConfig.pitch), THREE.Math.degToRad(-180 - self.alignmentConfig.yaw), THREE.Math.degToRad(self.alignmentConfig.roll), 'YXZ');
|
||||
xyz.rotation.set(-THREE.Math.degToRad(self.alignmentConfig.pitch), THREE.Math.degToRad(-180 - self.alignmentConfig.yaw), THREE.Math.degToRad(self.alignmentConfig.roll), 'YXZ');
|
||||
fc.visible = true;
|
||||
|
||||
var magRotation = new THREE.Euler(-THREE.Math.degToRad(self.alignmentConfig.pitch-180), THREE.Math.degToRad(-180 - self.alignmentConfig.yaw), THREE.Math.degToRad(self.alignmentConfig.roll), 'YXZ');
|
||||
var matrix = (new THREE.Matrix4()).makeRotationFromEuler(magRotation);
|
||||
|
||||
var boardRotation = new THREE.Euler( THREE.Math.degToRad( -self.boardAlignmentConfig.pitch ), THREE.Math.degToRad( -self.boardAlignmentConfig.yaw ), THREE.Math.degToRad( -self.boardAlignmentConfig.roll ), 'YXZ');
|
||||
var matrix1 = (new THREE.Matrix4()).makeRotationFromEuler(boardRotation);
|
||||
|
||||
/*
|
||||
if ( self.isSavePreset ) {
|
||||
matrix.premultiply(matrix1); //preset specifies orientation relative to FC, align_max_xxx specify absolute orientation
|
||||
}
|
||||
*/
|
||||
gps.rotation.setFromRotationMatrix(matrix);
|
||||
xyz.rotation.setFromRotationMatrix(matrix);
|
||||
fc.rotation.setFromRotationMatrix(matrix1);
|
||||
|
||||
// draw
|
||||
if (camera != null)
|
||||
|
@ -429,7 +648,7 @@ TABS.magnetometer.initialize3D = function () {
|
|||
case "twin_plane":
|
||||
case "vtail_plane":
|
||||
case "vtail_single_servo_plane":
|
||||
return [0, 1.4, 0];
|
||||
return [0, 1.6, 0];
|
||||
case "fallback":
|
||||
default:
|
||||
return [0, 2.5, 0];
|
||||
|
@ -479,7 +698,7 @@ TABS.magnetometer.initialize3D = function () {
|
|||
gps = obj.scene;
|
||||
const scaleFactor = 0.04;
|
||||
gps.scale.set(scaleFactor, scaleFactor, scaleFactor);
|
||||
gps.position.set(gpsOffset[0], gpsOffset[1], gpsOffset[2]);
|
||||
gps.position.set(gpsOffset[0], gpsOffset[1] + 0.5, gpsOffset[2]);
|
||||
gps.traverse(child => {
|
||||
if (child.material) child.material.metalness = 0;
|
||||
});
|
||||
|
@ -493,11 +712,23 @@ TABS.magnetometer.initialize3D = function () {
|
|||
xyz = obj.scene;
|
||||
const scaleFactor = 0.04;
|
||||
xyz.scale.set(scaleFactor, scaleFactor, scaleFactor);
|
||||
xyz.position.set(gpsOffset[0], gpsOffset[1], gpsOffset[2]);
|
||||
xyz.position.set(gpsOffset[0], gpsOffset[1] + 0.5, gpsOffset[2]);
|
||||
xyz.rotation.y = 3 * Math.PI / 2;
|
||||
model.add(xyz);
|
||||
this.render3D();
|
||||
});
|
||||
|
||||
//Load the FC model
|
||||
loader.load('./resources/models/fc.gltf', (obj) => {
|
||||
fc = obj.scene;
|
||||
const scaleFactor = 0.04;
|
||||
fc.scale.set(scaleFactor, scaleFactor, scaleFactor);
|
||||
fc.position.set(gpsOffset[0], gpsOffset[1] - 0.5, gpsOffset[2]);
|
||||
fc.rotation.y = 3 * Math.PI / 2;
|
||||
model.add(fc);
|
||||
this.render3D();
|
||||
});
|
||||
|
||||
});
|
||||
this.render3D();
|
||||
this.resize3D();
|
||||
|
|
|
@ -20,14 +20,21 @@
|
|||
<label for="motor_direction_inverted"><span data-i18n="motor_direction_inverted"></span></label>
|
||||
<div class="helpicon cf_tip" data-i18n_title="motor_direction_inverted_hint"></div>
|
||||
</div>
|
||||
<div class="select">
|
||||
<select id="output_mode" data-setting="output_mode"></select>
|
||||
<label for="output_mode">
|
||||
<span data-i18n="output_modeTitle"></span>
|
||||
</label>
|
||||
<div class="checkbox">
|
||||
<input id="mixer_pid_profile_linking" type="checkbox" class="toggle" data-setting="mixer_pid_profile_linking" />
|
||||
<label for="mixer_pid_profile_linking"><span data-i18n="mixer_pid_profile_linking"></span></label>
|
||||
<div class="helpicon cf_tip" data-i18n_title="mixer_pid_profile_linking_hint"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="platform-type gui_box grey">
|
||||
<div class="gui_box_titlebar">
|
||||
<div class="spacer_box_title" data-i18n="timerOutputs"></div>
|
||||
</div>
|
||||
<div class="spacer_box" id="timerOutputsList" style="padding: 0; width: calc(100% - 12px)"></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="rightWrapper">
|
||||
<div class="platform-type gui_box grey">
|
||||
|
|
|
@ -27,7 +27,8 @@ TABS.mixer.initialize = function (callback, scrollPosition) {
|
|||
mspHelper.loadMotors,
|
||||
mspHelper.loadServoMixRules,
|
||||
mspHelper.loadMotorMixRules,
|
||||
mspHelper.loadOutputMapping,
|
||||
mspHelper.loadOutputMappingExt,
|
||||
mspHelper.loadTimerOutputModes,
|
||||
mspHelper.loadLogicConditions
|
||||
]);
|
||||
loadChainer.setExitPoint(loadHtml);
|
||||
|
@ -37,6 +38,7 @@ TABS.mixer.initialize = function (callback, scrollPosition) {
|
|||
mspHelper.saveMixerConfig,
|
||||
mspHelper.sendServoMixer,
|
||||
mspHelper.sendMotorMixer,
|
||||
mspHelper.sendTimerOutputModes,
|
||||
saveSettings,
|
||||
mspHelper.saveToEeprom
|
||||
]);
|
||||
|
@ -72,9 +74,13 @@ TABS.mixer.initialize = function (callback, scrollPosition) {
|
|||
|
||||
$outputRow.append('<th data-i18n="mappingTableOutput"></th>');
|
||||
$functionRow.append('<th data-i18n="mappingTableFunction"></th>');
|
||||
|
||||
|
||||
for (let i = 1; i <= outputCount; i++) {
|
||||
$outputRow.append('<td>S' + i + '</td>');
|
||||
|
||||
let timerId = OUTPUT_MAPPING.getTimerId(i - 1);
|
||||
let color = OUTPUT_MAPPING.getOutputTimerColor(i - 1);
|
||||
|
||||
$outputRow.append('<td style="background-color: ' + color + '">S' + i + ' (Timer ' + (timerId + 1) + ')</td>');
|
||||
$functionRow.append('<td id="function-' + i +'">-</td>');
|
||||
}
|
||||
|
||||
|
@ -82,6 +88,44 @@ TABS.mixer.initialize = function (callback, scrollPosition) {
|
|||
|
||||
}
|
||||
|
||||
function updateTimerOverride() {
|
||||
let timers = OUTPUT_MAPPING.getUsedTimerIds();
|
||||
|
||||
for(let i =0; i < timers.length;++i) {
|
||||
let timerId = timers[i];
|
||||
$select = $('#timer-output-' + timerId);
|
||||
if(!$select) {
|
||||
continue;
|
||||
}
|
||||
OUTPUT_MAPPING.setTimerOverride(timerId, $select.val());
|
||||
}
|
||||
}
|
||||
|
||||
function renderTimerOverride() {
|
||||
let outputCount = OUTPUT_MAPPING.getOutputCount(),
|
||||
$container = $('#timerOutputsList'), timers = {};
|
||||
|
||||
|
||||
let usedTimers = OUTPUT_MAPPING.getUsedTimerIds();
|
||||
|
||||
for (t of usedTimers) {
|
||||
var usageMode = OUTPUT_MAPPING.getTimerOverride(t);
|
||||
$container.append(
|
||||
'<div class="select" style="padding: 5px; margin: 1px; background-color: ' + OUTPUT_MAPPING.getTimerColor(t) + '">' +
|
||||
'<select id="timer-output-' + t + '">' +
|
||||
'<option value=' + OUTPUT_MAPPING.TIMER_OUTPUT_MODE_AUTO + '' + (usageMode == OUTPUT_MAPPING.TIMER_OUTPUT_MODE_AUTO ? ' selected' : '')+ '>AUTO</option>'+
|
||||
'<option value=' + OUTPUT_MAPPING.TIMER_OUTPUT_MODE_MOTORS + '' + (usageMode == OUTPUT_MAPPING.TIMER_OUTPUT_MODE_MOTORS ? ' selected' : '')+ '>MOTORS</option>'+
|
||||
'<option value=' + OUTPUT_MAPPING.TIMER_OUTPUT_MODE_SERVOS + '' + (usageMode == OUTPUT_MAPPING.TIMER_OUTPUT_MODE_SERVOS ? ' selected' : '')+ '>SERVOS</option>'+
|
||||
'</select>' +
|
||||
'<label for="timer-output-' + t + '">' +
|
||||
'<span> Timer ' + (parseInt(t) + 1) + '</span>' +
|
||||
'</label>' +
|
||||
'</div>'
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function renderOutputMapping() {
|
||||
let outputMap = OUTPUT_MAPPING.getOutputTable(
|
||||
MIXER_CONFIG.platformType == PLATFORM_MULTIROTOR || MIXER_CONFIG.platformType == PLATFORM_TRICOPTER,
|
||||
|
@ -126,8 +170,9 @@ TABS.mixer.initialize = function (callback, scrollPosition) {
|
|||
motors.push(outputPad);
|
||||
} else {
|
||||
let servo = servoRules.getServoMixRuleFromTarget(omIndex[1]);
|
||||
if (servo == null) {continue;}
|
||||
let divID = "servoPreview" + omIndex[1];
|
||||
|
||||
|
||||
switch (parseInt(servo.getInput())) {
|
||||
case INPUT_STABILIZED_PITCH:
|
||||
case STABILIZED_PITCH_POSITIVE:
|
||||
|
@ -352,7 +397,6 @@ TABS.mixer.initialize = function (callback, scrollPosition) {
|
|||
const $fixedValueCalcInput = row.find(".mix-rule-fixed-value");
|
||||
if (FC.getServoMixInputNames()[$mixRuleInput.val()] === 'MAX') {
|
||||
$fixedValueCalcInput.show();
|
||||
row.find(".mix-rule-speed").prop('disabled', true);
|
||||
} else {
|
||||
$fixedValueCalcInput.hide();
|
||||
row.find(".mix-rule-speed").prop('disabled', false);
|
||||
|
@ -392,7 +436,10 @@ TABS.mixer.initialize = function (callback, scrollPosition) {
|
|||
$motorMixTableBody.append('\
|
||||
<tr>\
|
||||
<td><span class="mix-rule-motor"></span></td>\
|
||||
<td><input type="number" class="mix-rule-throttle" step="0.001" min="0" max="1" /></td>\
|
||||
<td>\
|
||||
<input type="number" class="mix-rule-throttle" step="0.001" min="-2" max="2" />\
|
||||
<div class="throttle-warning-text" data-i18n="mixerThrottleWarning" ></div>\
|
||||
</td>\
|
||||
<td><input type="number" class="mix-rule-roll" step="0.001" min="-2" max="2" /></td>\
|
||||
<td><input type="number" class="mix-rule-pitch" step="0.001" min="-2" max="2" /></td>\
|
||||
<td><input type="number" class="mix-rule-yaw" step="0.001" min="-2" max="2" /></td>\
|
||||
|
@ -403,9 +450,26 @@ TABS.mixer.initialize = function (callback, scrollPosition) {
|
|||
const $row = $motorMixTableBody.find('tr:last');
|
||||
|
||||
$row.find('.mix-rule-motor').html(index);
|
||||
$row.find('.mix-rule-throttle').val(rule.getThrottle()).change(function () {
|
||||
rule.setThrottle($(this).val());
|
||||
});
|
||||
const $throttleInput = $row.find('.mix-rule-throttle').val(rule.getThrottle());
|
||||
const $warningBox = $row.find('.throttle-warning-text');
|
||||
|
||||
// Function to update throttle and show/hide warning box
|
||||
function updateThrottle() {
|
||||
rule.setThrottle($throttleInput.val());
|
||||
// Change color if value exceeds 1
|
||||
if (parseFloat($throttleInput.val()) > 1 || parseFloat($throttleInput.val()) < 0) {
|
||||
$throttleInput.css('background-color', 'orange');
|
||||
// Show warning box
|
||||
$warningBox.show();
|
||||
} else {
|
||||
$throttleInput.css('background-color', ''); // Reset to default
|
||||
// Hide warning box
|
||||
$warningBox.hide();
|
||||
}
|
||||
}
|
||||
updateThrottle();
|
||||
$throttleInput.change(updateThrottle);
|
||||
|
||||
$row.find('.mix-rule-roll').val(rule.getRoll()).change(function () {
|
||||
rule.setRoll($(this).val());
|
||||
});
|
||||
|
@ -437,6 +501,9 @@ TABS.mixer.initialize = function (callback, scrollPosition) {
|
|||
SERVO_RULES.inflate();
|
||||
MOTOR_RULES.cleanup();
|
||||
MOTOR_RULES.inflate();
|
||||
|
||||
updateTimerOverride();
|
||||
|
||||
saveChainer.execute();
|
||||
}
|
||||
|
||||
|
@ -704,6 +771,7 @@ TABS.mixer.initialize = function (callback, scrollPosition) {
|
|||
|
||||
renderOutputTable();
|
||||
renderOutputMapping();
|
||||
renderTimerOverride();
|
||||
|
||||
LOGIC_CONDITIONS.init($('#logic-wrapper'));
|
||||
|
||||
|
|
|
@ -74,6 +74,11 @@
|
|||
<input type="text" id="pilot_name" data-setting="pilot_name" data-live="true" />
|
||||
<span data-i18n="osd_pilot_name"></span>
|
||||
</label>
|
||||
<div for="usePilotLogo" class="helpicon cf_tip osd_use_large_pilot_logo" data-i18n_title="osd_use_large_pilot_logo_help"></div>
|
||||
<label>
|
||||
<input type="checkbox" id="usePilotLogo" class="toggle update_preview" data-setting="osd_use_pilot_logo" data-live="true">
|
||||
<span data-i18n="osd_use_pilot_logo"></span>
|
||||
</label>
|
||||
<label class="craft_name">
|
||||
<input type="text" id="craft_name" data-setting="name" data-live="true" />
|
||||
<span data-i18n="osd_craft_name"></span>
|
||||
|
@ -88,8 +93,8 @@
|
|||
<span data-i18n="osd_main_voltage_decimals"></span>
|
||||
</label>
|
||||
<label>
|
||||
<select class="update_preview" data-setting="osd_mah_used_precision" data-live="true"></select>
|
||||
<span data-i18n="osd_mah_used_precision"></span>
|
||||
<select class="update_preview" data-setting="osd_mah_precision" data-live="true"></select>
|
||||
<span data-i18n="osd_mah_precision"></span>
|
||||
</label>
|
||||
<label>
|
||||
<select class="update_preview" data-setting="osd_coordinate_digits" data-live="true"></select>
|
||||
|
@ -114,11 +119,6 @@
|
|||
<select class="update_preview" data-setting="osd_crosshairs_style" data-live="true"></select>
|
||||
<span data-i18n="osd_crosshairs_style"></span>
|
||||
</label>
|
||||
<div for="osd_horizon_offset" class="helpicon cf_tip" data-i18n_title="osd_horizon_offset_help"></div>
|
||||
<label>
|
||||
<select class="update_preview" id="osd_horizon_offset" data-setting="osd_horizon_offset" data-setting-invert-select="true" data-live="true"></select>
|
||||
<span data-i18n="osd_horizon_offset"></span>
|
||||
</label>
|
||||
<label>
|
||||
<select class="update_preview" data-setting="osd_left_sidebar_scroll" data-live="true"></select>
|
||||
<span data-i18n="osd_left_sidebar_scroll"></span>
|
||||
|
@ -346,6 +346,59 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gui_box grey hud-settings-container">
|
||||
<div class="gui_box_titlebar">
|
||||
<div for="osd_hud_settings" class="helpicon cf_tip" data-i18n_title="osd_hud_settings_HELP"></div>
|
||||
<div class="spacer_box_title" data-i18n="osd_hud_settings"></div>
|
||||
</div>
|
||||
<div class="spacer_box settings">
|
||||
<div id="osd_hud_settings">
|
||||
<div for="osd_horizon_offset" class="helpicon cf_tip" data-i18n_title="osd_horizon_offset_help"></div>
|
||||
<label>
|
||||
<select class="update_preview" id="osd_horizon_offset" data-setting="osd_horizon_offset" data-setting-invert-select="true" data-live="true"></select>
|
||||
<span data-i18n="osd_horizon_offset"></span>
|
||||
</label>
|
||||
<div for="osd_hud_wp_disp" class="helpicon cf_tip" data-i18n_title="osd_hud_wp_disp_help"></div>
|
||||
<label>
|
||||
<input type="number" data-step="1" data-setting-multiplier="1" data-setting="osd_hud_wp_disp" class="toggle update_preview" data-live="true">
|
||||
<span data-i18n="osd_hud_wp_disp"></span>
|
||||
</label>
|
||||
<div for="osd_hud_radar_disp" class="helpicon cf_tip" data-i18n_title="osd_hud_radar_disp_help"></div>
|
||||
<label>
|
||||
<input type="number" data-step="1" data-setting-multiplier="1" data-setting="osd_hud_radar_disp" class="toggle update_preview" data-live="true">
|
||||
<span data-i18n="osd_hud_radar_disp"></span>
|
||||
</label>
|
||||
|
||||
<div for="osd_hud_radar_range_min" class="helpicon cf_tip" data-i18n_title="osd_hud_radar_range_min_help"></div>
|
||||
<label>
|
||||
<input type="number" data-step="1" data-unit="m" data-setting-multiplier="1" data-setting="osd_hud_radar_range_min" class="toggle update_preview" data-live="true">
|
||||
<span data-i18n="osd_hud_radar_range_min"></span>
|
||||
</label>
|
||||
<div for="osd_hud_radar_range_max" class="helpicon cf_tip" data-i18n_title="osd_hud_radar_range_max_help"></div>
|
||||
<label>
|
||||
<input type="number" data-step="1" data-unit="m" data-setting-multiplier="1" data-setting="osd_hud_radar_range_max" class="toggle update_preview" data-live="true">
|
||||
<span data-i18n="osd_hud_radar_range_max"></span>
|
||||
</label>
|
||||
|
||||
<div for="osd_camera_fov_h" class="helpicon cf_tip" data-i18n_title="osd_camera_fov_h_help"></div>
|
||||
<label>
|
||||
<input type="number" data-step="1" data-setting-multiplier="1" data-setting="osd_camera_fov_h" class="toggle update_preview" data-live="true">
|
||||
<span data-i18n="osd_camera_fov_h"></span>
|
||||
</label>
|
||||
<div for="osd_camera_fov_v" class="helpicon cf_tip" data-i18n_title="osd_camera_fov_v_help"></div>
|
||||
<label>
|
||||
<input type="number" data-step="1" data-setting-multiplier="1" data-setting="osd_camera_fov_v" class="toggle update_preview" data-live="true">
|
||||
<span data-i18n="osd_camera_fov_v"></span>
|
||||
</label>
|
||||
<div for="osd_camera_uptilt" class="helpicon cf_tip" data-i18n_title="osd_camera_uptilt_help"></div>
|
||||
<label>
|
||||
<input type="number" data-step="1" data-setting-multiplier="1" data-setting="osd_camera_uptilt" class="toggle update_preview" data-live="true">
|
||||
<span data-i18n="osd_camera_uptilt"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div id="fontmanagercontent" style="display:none; width:712px;">
|
||||
<div class="font-picker" style="margin-bottom: 10px;">
|
||||
|
|
53
tabs/osd.js
|
@ -112,8 +112,13 @@ SYM.GLIDE_RANGE = 0xD4;
|
|||
SYM.FLIGHT_MINS_REMAINING = 0xDA;
|
||||
SYM.FLIGHT_DIST_REMAINING = 0x167;
|
||||
SYM.GROUND_COURSE = 0xDC;
|
||||
SYM.ALERT = 0xDD;
|
||||
SYM.CROSS_TRACK_ERROR = 0xFC;
|
||||
SYM.PAN_SERVO_IS_OFFSET_L = 0x1C7;
|
||||
SYM.ODOMETER = 0X168;
|
||||
SYM.PILOT_LOGO_SML_L = 0x1D5;
|
||||
SYM.PILOT_LOGO_SML_C = 0x1D6;
|
||||
SYM.PILOT_LOGO_SML_R = 0x1D7;
|
||||
|
||||
SYM.AH_AIRCRAFT0 = 0x1A2;
|
||||
SYM.AH_AIRCRAFT1 = 0x1A3;
|
||||
|
@ -423,9 +428,11 @@ function osdMainBatteryPreview() {
|
|||
return FONT.symbol(SYM.BATT) + FONT.embed_dot(s);
|
||||
}
|
||||
|
||||
function osdmAhdrawnPreview() {
|
||||
let precision = Settings.getInputValue('osd_mah_used_precision');
|
||||
let preview = "1215075".substring(0, precision);
|
||||
function osdmAhPrecisionPreview() {
|
||||
let precision = Settings.getInputValue('osd_mah_precision');
|
||||
let rnd = (Math.floor(10000000000000 + Math.random() * 90000000000000)).toString();
|
||||
rnd = rnd.replace('0', '');
|
||||
let preview = rnd.substring(0, precision);
|
||||
|
||||
return preview + FONT.symbol(SYM.MAH);
|
||||
}
|
||||
|
@ -839,7 +846,6 @@ OSD.constants = {
|
|||
{
|
||||
name: 'THROTTLE_POSITION',
|
||||
id: 9,
|
||||
|
||||
preview: ' ' + FONT.symbol(SYM.THR) + ' 69'
|
||||
},
|
||||
{
|
||||
|
@ -857,6 +863,11 @@ OSD.constants = {
|
|||
id: 142,
|
||||
preview: '[PILOT_NAME]'
|
||||
},
|
||||
{
|
||||
name: 'PILOT_LOGO',
|
||||
id: 146,
|
||||
preview: FONT.symbol(SYM.PILOT_LOGO_SML_L) + FONT.symbol(SYM.PILOT_LOGO_SML_C) + FONT.symbol(SYM.PILOT_LOGO_SML_R)
|
||||
},
|
||||
{
|
||||
name: 'FLYMODE',
|
||||
id: 7,
|
||||
|
@ -997,6 +1008,12 @@ OSD.constants = {
|
|||
id: 119,
|
||||
min_version: '3.0.0',
|
||||
preview: 'INAV 2.7.0'
|
||||
},
|
||||
{
|
||||
name: 'MULTI FUNCTION STATUS',
|
||||
id: 144,
|
||||
min_version: '6.0.0',
|
||||
preview: '0 WARNINGS'
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -1306,7 +1323,7 @@ OSD.constants = {
|
|||
name: 'MAH_DRAWN',
|
||||
id: 12,
|
||||
preview: function() {
|
||||
return osdmAhdrawnPreview();
|
||||
return osdmAhPrecisionPreview();
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -1327,7 +1344,7 @@ OSD.constants = {
|
|||
name: 'MAIN_BATT_REMAINING_CAPACITY',
|
||||
id: 37,
|
||||
preview: function() {
|
||||
return '1276' + FONT.symbol(SYM.MAH); // 4 chars
|
||||
return osdmAhPrecisionPreview();
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -1556,6 +1573,22 @@ OSD.constants = {
|
|||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'ODOMETER',
|
||||
id: 145,
|
||||
min_version: '6.1.0',
|
||||
preview: function(osd_data) {
|
||||
switch (OSD.data.preferences.units) {
|
||||
case 0: // Imperial
|
||||
case 3: // UK
|
||||
return FONT.symbol(SYM.ODOMETER) + FONT.embed_dot('00016.9') + FONT.symbol(SYM.DIST_MI);
|
||||
case 4: // GA
|
||||
return FONT.symbol(SYM.ODOMETER) + FONT.embed_dot('00014.7') + FONT.symbol(SYM.DIST_NM);
|
||||
default: // Metric
|
||||
return FONT.symbol(SYM.ODOMETER) + FONT.embed_dot('00027.2') + FONT.symbol(SYM.DIST_KM);
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'GPS_HDOP',
|
||||
id: 31,
|
||||
|
@ -2156,7 +2189,7 @@ OSD.updateDisplaySize = function () {
|
|||
$('.third_left').toggleClass('preview_bfhdcompat_side', (video_type == 'BFHDCOMPAT'))
|
||||
$('.preview').toggleClass('preview_bfhdcompat cut43_left', (video_type == 'BFHDCOMPAT'))
|
||||
$('.third_right').toggleClass('preview_bfhdcompat_side', (video_type == 'BFHDCOMPAT'))
|
||||
|
||||
|
||||
OSD.GUI.updateGuidesView($('#videoGuides').find('input').is(':checked'));
|
||||
};
|
||||
|
||||
|
@ -3104,7 +3137,7 @@ TABS.osd.initialize = function (callback) {
|
|||
chrome.storage.local.get('showOSDGuides', function (result) {
|
||||
if (typeof result.showOSDGuides !== 'undefined') {
|
||||
isGuidesChecked = result.showOSDGuides;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Setup switch indicators
|
||||
|
@ -3356,7 +3389,7 @@ function refreshOSDSwitchIndicators() {
|
|||
function updatePilotAndCraftNames() {
|
||||
let foundPilotName = ($('#pilot_name').val() == undefined);
|
||||
let foundCraftName = ($('#craft_name').val() == undefined);
|
||||
|
||||
|
||||
let generalGroup = OSD.constants.ALL_DISPLAY_GROUPS.filter(function(e) {
|
||||
return e.name == "osdGroupGeneral";
|
||||
})[0];
|
||||
|
@ -3408,7 +3441,7 @@ function updatePanServoPreview() {
|
|||
let servoRules = SERVO_RULES;
|
||||
$('#panServoOutput option').each(function() {
|
||||
let servoIndex = $(this).val();
|
||||
|
||||
|
||||
if (servoIndex === "0") {
|
||||
$(this).text("OFF");
|
||||
} else {
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
|
||||
<div id="motor-stop-warning" data-i18n="motorStopWarning" class="warning-box"></div>
|
||||
<div class="checkbox">
|
||||
<input type="checkbox" data-bit="4" class="feature toggle" name="MOTOR_STOP" title="MOTOR_STOP" id="feature-4">
|
||||
<input id="feature-4" type="checkbox" class="toggle" data-setting="motorstop_on_low" />
|
||||
<label for="feature-4">
|
||||
<span data-i18n="featureMOTOR_STOP"></span>
|
||||
</label>
|
||||
|
|
|
@ -1,7 +1,14 @@
|
|||
<!--suppress ALL -->
|
||||
<div id="content-watermark"></div>
|
||||
<div class="tab-pid_tuning toolbar_fixed_bottom">
|
||||
<div class="content_wrapper">
|
||||
<div id="note-wrapper" class="content_wrapper">
|
||||
<div class="note spacebottom">
|
||||
<div class="note_spacer">
|
||||
<p i18n="ezTuneNote"></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="tuning-wrapper" class="content_wrapper">
|
||||
<div class="tab_title subtab__header">
|
||||
<span class="subtab__header_label subtab__header_label--current" for="subtab-pid" data-i18n="pidTuning_PIDgains"></span>
|
||||
<span class="subtab__header_label" for="subtab-rates" data-i18n="pidTuning_RatesAndExpo"></span>
|
||||
|
@ -339,6 +346,72 @@
|
|||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="clear-both"></div>
|
||||
<div class="tab_subtitle" style="margin-top: 1em;" data-i18n="pidTuning_RateDynamics"></div>
|
||||
<div class="clear-both"></div>
|
||||
<div class="cf_doc_version_bt"><a href="https://github.com/iNavFlight/inav/wiki/Rate-Dynamics" target="_blank" style="margin-top: -35px;">Rate Dynamics Documentation</a></div>
|
||||
|
||||
<div class="pid-sliders-axis" data-axis="roll">
|
||||
<h3 data-i18n="pidTuning_RateDynamics_Sensitivity"></h3>
|
||||
<div class="pid-slider-row">
|
||||
<span data-i18n="pidTuning_RateDynamics_Center"></span>
|
||||
<div class="number no-border">
|
||||
<input id="rate_dynamics_center_sensitivity" type="number"/>
|
||||
</div>
|
||||
<div class="clear-both"></div>
|
||||
</div>
|
||||
|
||||
<div class="pid-slider-row">
|
||||
<span data-i18n="pidTuning_RateDynamics_End"></span>
|
||||
<div class="number no-border">
|
||||
<input id="rate_dynamics_end_sensitivity" type="number"/>
|
||||
</div>
|
||||
<div class="clear-both"></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="pid-sliders-axis" data-axis="pitch">
|
||||
<h3 data-i18n="pidTuning_RateDynamics_Correction"></h3>
|
||||
<div class="pid-slider-row">
|
||||
<span data-i18n="pidTuning_RateDynamics_Center"></span>
|
||||
<div class="number no-border">
|
||||
<input id="rate_dynamics_center_correction" type="number"/>
|
||||
</div>
|
||||
<div class="clear-both"></div>
|
||||
</div>
|
||||
|
||||
<div class="pid-slider-row">
|
||||
<span data-i18n="pidTuning_RateDynamics_End"></span>
|
||||
<div class="number no-border">
|
||||
<input id="rate_dynamics_end_correction" type="number"/>
|
||||
</div>
|
||||
<div class="clear-both"></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="pid-sliders-axis" data-axis="yaw">
|
||||
<h3 data-i18n="pidTuning_RateDynamics_Weight"></h3>
|
||||
<div class="pid-slider-row">
|
||||
<span data-i18n="pidTuning_RateDynamics_Center"></span>
|
||||
<div class="number no-border">
|
||||
<input id="rate_dynamics_center_weight" type="number"/>
|
||||
</div>
|
||||
<div class="clear-both"></div>
|
||||
</div>
|
||||
|
||||
<div class="pid-slider-row">
|
||||
<span data-i18n="pidTuning_RateDynamics_End"></span>
|
||||
<div class="number no-border">
|
||||
<input id="rate_dynamics_end_weight" type="number"/>
|
||||
</div>
|
||||
<div class="clear-both"></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div id="subtab-filters" class="subtab__content">
|
||||
|
@ -617,7 +690,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="clear-both"></div>
|
||||
<div class="content_toolbar">
|
||||
<div id="tuning-footer" class="content_toolbar">
|
||||
<div class="btn save_btn">
|
||||
<a class="update" href="#" data-i18n="pidTuning_ButtonSave"></a>
|
||||
</div>
|
||||
|
|
|
@ -15,7 +15,9 @@ TABS.pid_tuning.initialize = function (callback) {
|
|||
mspHelper.loadINAVPidConfig,
|
||||
mspHelper.loadPidAdvanced,
|
||||
mspHelper.loadFilterConfig,
|
||||
mspHelper.loadFeatures
|
||||
mspHelper.loadFeatures,
|
||||
mspHelper.loadRateDynamics,
|
||||
mspHelper.loadEzTune
|
||||
];
|
||||
loadChain.push(mspHelper.loadRateProfileData);
|
||||
|
||||
|
@ -92,6 +94,15 @@ TABS.pid_tuning.initialize = function (callback) {
|
|||
RC_tuning.manual_roll_rate = $('#rate-manual-roll').val();
|
||||
RC_tuning.manual_pitch_rate = $('#rate-manual-pitch').val();
|
||||
RC_tuning.manual_yaw_rate = $('#rate-manual-yaw').val();
|
||||
|
||||
// Rate Dynamics
|
||||
RATE_DYNAMICS.sensitivityCenter = parseInt($('#rate_dynamics_center_sensitivity').val());
|
||||
RATE_DYNAMICS.sensitivityEnd = parseInt($('#rate_dynamics_end_sensitivity').val());
|
||||
RATE_DYNAMICS.correctionCenter = parseInt($('#rate_dynamics_center_correction').val());
|
||||
RATE_DYNAMICS.correctionEnd = parseInt($('#rate_dynamics_end_correction').val());
|
||||
RATE_DYNAMICS.weightCenter = parseInt($('#rate_dynamics_center_weight').val());
|
||||
RATE_DYNAMICS.weightEnd = parseInt($('#rate_dynamics_end_weight').val());
|
||||
|
||||
}
|
||||
function hideUnusedPids(sensors_detected) {
|
||||
$('.tab-pid_tuning table.pid_tuning').hide();
|
||||
|
@ -115,6 +126,15 @@ TABS.pid_tuning.initialize = function (callback) {
|
|||
}
|
||||
function process_html() {
|
||||
// translate to user-selected language
|
||||
|
||||
if (EZ_TUNE.enabled) {
|
||||
$("#tuning-wrapper").remove();
|
||||
$("#tuning-footer").remove();
|
||||
$('#note-wrapper').show();
|
||||
} else {
|
||||
$("#note-wrapper").remove();
|
||||
}
|
||||
|
||||
localize();
|
||||
|
||||
helper.tabs.init($('.tab-pid_tuning'));
|
||||
|
@ -232,6 +252,15 @@ TABS.pid_tuning.initialize = function (callback) {
|
|||
axis++;
|
||||
});
|
||||
|
||||
GUI.sliderize($('#rate_dynamics_center_sensitivity'), RATE_DYNAMICS.sensitivityCenter, 25, 175);
|
||||
GUI.sliderize($('#rate_dynamics_end_sensitivity'), RATE_DYNAMICS.sensitivityEnd, 25, 175);
|
||||
|
||||
GUI.sliderize($('#rate_dynamics_center_correction'), RATE_DYNAMICS.correctionCenter, 10, 95);
|
||||
GUI.sliderize($('#rate_dynamics_end_correction'), RATE_DYNAMICS.correctionEnd, 10, 95);
|
||||
|
||||
GUI.sliderize($('#rate_dynamics_center_weight'), RATE_DYNAMICS.weightCenter, 0, 95);
|
||||
GUI.sliderize($('#rate_dynamics_end_weight'), RATE_DYNAMICS.weightEnd, 0, 95);
|
||||
|
||||
if (!FC.isRpyFfComponentUsed()) {
|
||||
$('.rpy_ff').prop('disabled', 'disabled');
|
||||
}
|
||||
|
@ -270,7 +299,11 @@ TABS.pid_tuning.initialize = function (callback) {
|
|||
}
|
||||
|
||||
function saveFilterConfig() {
|
||||
MSP.send_message(MSPCodes.MSP_SET_FILTER_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_FILTER_CONFIG), false, saveSettings);
|
||||
MSP.send_message(MSPCodes.MSP_SET_FILTER_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_FILTER_CONFIG), false, saveRateDynamics);
|
||||
}
|
||||
|
||||
function saveRateDynamics() {
|
||||
mspHelper.saveRateDynamics(saveSettings);
|
||||
}
|
||||
|
||||
function saveSettings() {
|
||||
|
|