1
0
Fork 0
mirror of https://github.com/iNavFlight/inav.git synced 2025-07-24 16:55:29 +03:00

Merge branch 'master' into release_7.1.2

This commit is contained in:
Pawel Spychalski (DzikuVx) 2024-06-04 15:50:27 +02:00
commit cfa0d23bb9
240 changed files with 8210 additions and 3984 deletions

View file

@ -100,7 +100,7 @@ jobs:
- name: Build SITL
run: |
mkdir -p build_SITL && cd build_SITL
cmake -DSITL=ON -DWARNINGS_AS_ERRORS=ON -G Ninja ..
cmake -DSITL=ON -DWARNINGS_AS_ERRORS=ON -DCMAKE_OSX_ARCHITECTURES="arm64;x86_64" -G Ninja ..
ninja
- name: Upload artifacts

1
.gitignore vendored
View file

@ -36,3 +36,4 @@ make/local.mk
launch.json
.vscode/tasks.json
.vscode/c_cpp_properties.json
/cmake-build-debug/

1
.vimrc
View file

@ -5,5 +5,6 @@ set expandtab
set bs=2
set sw=4
set ts=4
syn on

View file

@ -3,6 +3,8 @@
"chrono": "c",
"cmath": "c",
"ranges": "c",
"navigation.h": "c",
"rth_trackback.h": "c"
"platform.h": "c",
"timer.h": "c",
"bus.h": "c"

8
.vscode/tasks.json vendored
View file

@ -4,9 +4,9 @@
"version": "2.0.0",
"tasks": [
{
"label": "Build Matek F722-SE",
"label": "Build AOCODARCH7DUAL",
"type": "shell",
"command": "make MATEKF722SE",
"command": "make AOCODARCH7DUAL",
"group": "build",
"problemMatcher": [],
"options": {
@ -14,9 +14,9 @@
}
},
{
"label": "Build Matek F722",
"label": "Build AOCODARCH7DUAL",
"type": "shell",
"command": "make MATEKF722",
"command": "make AOCODARCH7DUAL",
"group": {
"kind": "build",
"isDefault": true

View file

@ -51,7 +51,7 @@ else()
endif()
endif()
project(INAV VERSION 7.1.2)
project(INAV VERSION 8.0.0)
enable_language(ASM)

View file

@ -21,7 +21,6 @@ doc_files=(
'Buzzer.md'
'Sonar.md'
'Profiles.md'
'Modes.md'
'Inflight Adjustments.md'
'Controls.md'
'Gtune.md'
@ -49,7 +48,7 @@ if which gimli >/dev/null; then
done
rm -f ${filename}.pdf
gimli -f ${filename}.md -stylesheet override.css \
-w '--toc --title "Cleanflight Manual" --footer-right "[page]" --toc-depth 1'
-w '--toc --title "INAV Manual" --footer-right "[page]" --toc-depth 1'
rm ${filename}.md
popd >/dev/null
else

View file

@ -2,21 +2,18 @@ include(gcc)
set(arm_none_eabi_triplet "arm-none-eabi")
# Keep version in sync with the distribution files below
set(arm_none_eabi_gcc_version "10.3.1")
set(arm_none_eabi_base_url "https://developer.arm.com/-/media/Files/downloads/gnu-rm/10.3-2021.10/gcc-arm-none-eabi-10.3-2021.10")
set(arm_none_eabi_gcc_version "13.2.1")
# This is the output directory "pretty" name and URI name prefix
set(base_dir_name "arm-gnu-toolchain-13.2.rel1")
# This is the name inside the archive, which is no longer evincible from URI, alas
set(archive_base_dir_name "arm-gnu-toolchain-13.2.Rel1")
set(arm_none_eabi_base_url "https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/${base_dir_name}")
# suffix and checksum
set(arm_none_eabi_win32 "win32.zip" 2bc8f0c4c4659f8259c8176223eeafc1)
set(arm_none_eabi_linux_amd64 "x86_64-linux.tar.bz2" 2383e4eb4ea23f248d33adc70dc3227e)
set(arm_none_eabi_linux_aarch64 "aarch64-linux.tar.bz2" 3fe3d8bb693bd0a6e4615b6569443d0d)
set(arm_none_eabi_gcc_macos "mac.tar.bz2" 7f2a7b7b23797302a9d6182c6e482449)
function(arm_none_eabi_gcc_distname var)
string(REPLACE "/" ";" url_parts ${arm_none_eabi_base_url})
list(LENGTH url_parts n)
math(EXPR last "${n} - 1")
list(GET url_parts ${last} basename)
set(${var} ${basename} PARENT_SCOPE)
endfunction()
set(arm_none_eabi_win32 "mingw-w64-i686-arm-none-eabi.zip" 7fd677088038cdf82f33f149e2e943ee)
set(arm_none_eabi_linux_amd64 "x86_64-arm-none-eabi.tar.xz" 791754852f8c18ea04da7139f153a5b7)
set(arm_none_eabi_linux_aarch64 "aarch64-arm-none-eabi.tar.xz" 5a08122e6d4caf97c6ccd1d29e62599c)
set(arm_none_eabi_darwin_amd64 "darwin-x86_64-arm-none-eabi.tar.xz" 41d49840b0fc676d2ae35aab21a58693)
set(arm_none_eabi_darwin_aarch64 "darwin-arm64-arm-none-eabi.tar.xz" 2c43e9d72206c1f81227b0a685df5ea6)
function(host_uname_machine var)
# We need to call uname -m manually, since at the point
@ -47,7 +44,14 @@ function(arm_none_eabi_gcc_install)
message("-- no precompiled ${arm_none_eabi_triplet} toolchain for machine ${machine}")
endif()
elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin")
set(dist ${arm_none_eabi_gcc_macos})
host_uname_machine(machine)
if(machine STREQUAL "x86_64" OR machine STREQUAL "amd64")
set(dist ${arm_none_eabi_darwin_amd64})
elseif(machine STREQUAL "aarch64" OR machine STREQUAL "arm64")
set(dist ${arm_none_eabi_darwin_aarch64})
else()
message("-- no precompiled ${arm_none_eabi_triplet} toolchain for machine ${machine}")
endif()
endif()
if(dist STREQUAL "")
@ -83,11 +87,27 @@ function(arm_none_eabi_gcc_install)
if(NOT status EQUAL 0)
message(FATAL_ERROR "error extracting ${basename}: ${status}")
endif()
string(REPLACE "." ";" url_parts ${dist_suffix})
list(GET url_parts 0 host_dir_name)
set(dir_name "${archive_base_dir_name}-${host_dir_name}")
file(REMOVE_RECURSE "${TOOLS_DIR}/${base_dir_name}")
file(RENAME "${TOOLS_DIR}/${dir_name}" "${TOOLS_DIR}/${base_dir_name}")
# This is **somewhat ugly**
# the newlib distributed by ARM generates suprious warnings from re-entrant POSIX functions
# that INAV doesn't use. These "harmless" warnings can be surpressed by removing the
# errant section from the only libnosys used by INAV ...
# So look the other way ... while this is "fixed"
execute_process(COMMAND arm-none-eabi-objcopy -w -R .gnu.warning.* "${TOOLS_DIR}/${base_dir_name}/arm-none-eabi/lib/thumb/v7e-m+fp/hard/libnosys.a"
RESULT_VARIABLE status
WORKING_DIRECTORY ${TOOLS_DIR}
)
if(NOT status EQUAL 0)
message(FATAL_ERROR "error fixing libnosys.a: ${status}")
endif()
endfunction()
function(arm_none_eabi_gcc_add_path)
arm_none_eabi_gcc_distname(dist_name)
set(gcc_path "${TOOLS_DIR}/${dist_name}/bin")
set(gcc_path "${TOOLS_DIR}/${base_dir_name}/bin")
if(CMAKE_HOST_SYSTEM MATCHES ".*Windows.*")
set(sep "\\;")
else()
@ -110,7 +130,7 @@ function(arm_none_eabi_gcc_check)
message("-- found ${prog} ${version} at ${prog_path}")
if(COMPILER_VERSION_CHECK AND NOT arm_none_eabi_gcc_version STREQUAL version)
message("-- expecting ${prog} version ${arm_none_eabi_gcc_version}, but got version ${version} instead")
arm_none_eabi_gcc_install()
arm_none_eabi_gcc_install()
return()
endif()
endfunction()

View file

@ -9,7 +9,7 @@ option(SEMIHOSTING "Enable semihosting")
message("-- DEBUG_HARDFAULTS: ${DEBUG_HARDFAULTS}, SEMIHOSTING: ${SEMIHOSTING}")
set(CMSIS_DIR "${MAIN_LIB_DIR}/lib/main/AT32F43x/Drivers/CMSIS")
set(CMSIS_INCLUDE_DIR "${CMSIS_DIR}/cm4/core_support")
set(CMSIS_INCLUDE_DIR "${CMSIS_DIR}/cm4/core_support")
# DSP use common
set(CMSIS_DSP_DIR "${MAIN_LIB_DIR}/main/CMSIS/DSP")
set(CMSIS_DSP_INCLUDE_DIR "${CMSIS_DSP_DIR}/Include")
@ -50,8 +50,8 @@ main_sources(AT32_ASYNCFATFS_SRC
)
main_sources(AT32_MSC_SRC
msc/at32_msc_diskio.c
msc/emfat.c
msc/at32_msc_diskio.c
msc/emfat.c
msc/emfat_file.c
)
@ -92,6 +92,7 @@ set(AT32_LINK_OPTIONS
-Wl,--cref
-Wl,--no-wchar-size-warning
-Wl,--print-memory-usage
-Wl,--no-warn-rwx-segments
)
# Get target features
macro(get_at32_target_features output_var dir target_name)
@ -264,7 +265,7 @@ function(add_at32_executable)
endif()
endfunction()
# Main function of AT32
# Main function of AT32
function(target_at32)
if(NOT arm-none-eabi STREQUAL TOOLCHAIN)
return()
@ -325,6 +326,11 @@ function(target_at32)
math(EXPR hse_value "${hse_mhz} * 1000000")
list(APPEND target_definitions "HSE_VALUE=${hse_value}")
if (MSP_UART)
list(APPEND target_definitions "MSP_UART=${MSP_UART}")
endif()
if(args_COMPILE_DEFINITIONS)
list(APPEND target_definitions ${args_COMPILE_DEFINITIONS})
endif()

View file

@ -99,6 +99,10 @@ function (target_sitl name)
math(EXPR hse_value "${hse_mhz} * 1000000")
list(APPEND target_definitions "HSE_VALUE=${hse_value}")
if (MSP_UART)
list(APPEND target_definitions "MSP_UART=${MSP_UART}")
endif()
string(TOLOWER ${PROJECT_NAME} lowercase_project_name)
set(binary_name ${lowercase_project_name}_${FIRMWARE_VERSION}_${name})
if(DEFINED BUILD_SUFFIX AND NOT "" STREQUAL "${BUILD_SUFFIX}")

View file

@ -333,6 +333,11 @@ function(target_stm32)
math(EXPR hse_value "${hse_mhz} * 1000000")
list(APPEND target_definitions "HSE_VALUE=${hse_value}")
if (MSP_UART)
list(APPEND target_definitions "MSP_UART=${MSP_UART}")
endif()
if(args_COMPILE_DEFINITIONS)
list(APPEND target_definitions ${args_COMPILE_DEFINITIONS})
endif()

17
docs/ADSB.md Normal file
View file

@ -0,0 +1,17 @@
# ADS-B
[Automatic Dependent Surveillance Broadcast](https://en.wikipedia.org/wiki/Automatic_Dependent_Surveillance%E2%80%93Broadcast)
is an air traffic surveillance technology that enables aircraft to be accurately tracked by air traffic controllers and other pilots without the need for conventional radar.
## Current state
OSD can be configured to shows the closest aircraft.
## Hardware
All ADSB receivers which can send Mavlink [ADSB_VEHICLE](https://mavlink.io/en/messages/common.html#ADSB_VEHICLE) message are supported
* [PINGRX](https://uavionix.com/product/pingrx-pro/) (not tested)
* [TT-SC1](https://www.aerobits.pl/product/aero/) (tested)

View file

@ -23,7 +23,7 @@ Unassigned slots have rangeStartStep == rangeEndStep. Each element contains the
| Data | Type | Notes |
|------|------|-------|
| permanentId | uint8 | See Modes.md for a definition of the permanent ids |
| permanentId | uint8 | See [Modes in the wiki](https://github.com/iNavFlight/inav/wiki/Modes) for a definition of the permanent ids |
| auxChannelIndex | uint8 | The Aux switch number (indexed from 0) |
| rangeStartStep | uint8 | The start value for this element in 'blocks' of 25 where 0 == 900 and 48 == 2100 |
| rangeEndStep | uint8 | The end value for this element in 'blocks' of 25 where 0 == 900 and 48 == 2100 |
@ -45,7 +45,7 @@ sending this message for all auxiliary slots.
| Data | Type | Notes |
|------|------|-------|
| sequence id | uint8 | A monotonically increasing ID, from 0 to the number of slots -1 |
| permanentId | uint8 | See Modes.md for a definition of the permanent ids |
| permanentId | uint8 | See [Modes in the wiki](https://github.com/iNavFlight/inav/wiki/Modes) for a definition of the permanent ids |
| auxChannelIndex | uint8 | The Aux channel number (indexed from 0) |
| rangeStartStep | uint8 | The start value for this element in 'blocks' of 25 where 0 == 900 and 48 == 2100 |
| rangeEndStep | uint8 | The end value for this element in 'blocks' of 25 where 0 == 900 and 48 == 2100 |
@ -157,5 +157,5 @@ INAV.
See also
--------
Modes.md describes the user visible implementation for the INAV
[The wiki](https://github.com/iNavFlight/inav/wiki/Modes) describes the user visible implementation for the INAV
modes extension.

View file

@ -201,7 +201,6 @@ Up to 3 battery profiles are supported. You can select the battery profile from
- `vbat_max_cell_voltage`
- `vbat_warning_cell_voltage`
- `vbat_min_cell_voltage`
- `battery_capacity_unit`
- `battery_capacity`
- `battery_capacity_warning`
- `battery_capacity_critical`
@ -253,7 +252,6 @@ feature BAT_PROF_AUTOSWITCH
battery_profile 1
set bat_cells = 3
set battery_capacity_unit = MAH
set battery_capacity = 2200
set battery_capacity_warning = 440
set battery_capacity_critical = 220
@ -262,7 +260,6 @@ set battery_capacity_critical = 220
battery_profile 2
set bat_cells = 4
set battery_capacity_unit = MAH
set battery_capacity = 1500
set battery_capacity_warning = 300
set battery_capacity_critical = 150

View file

@ -1,50 +0,0 @@
# Betaflight 4.3 compatible MSP DisplayPort OSD (DJI O3 "Canvas Mode")
INAV 6.0 includes a special mode for MSP DisplayPort that supports incomplete implementations of MSP DisplayPort that only support BetaFlight, like the DJI O3 Air Unit. INAV 6.1 expands this to include HD canvas sizes from BetaFlight 4.4.
Different flight controllers have different OSD symbols and elements and require different fonts. BetaFlight's font is a single page and supports a maximum of 256 glyphs, INAV's font is currently 2 pages and supports up to 512 different glyphs.
While there is some overlap between the glyphs in BetaFlight and INAV, it is not possible to perform a 1 to 1 mapping for all the them. In cases where there is no suitable glyph in the BetaFlight font, a question mark `?` will be displayed.
This mode can be enabled by selecting BF43COMPAT or BFHDCOMPAT as video format in the OSD tab of the configurator or by typing the following command on the CLI:
`set osd_video_system = BF43COMPAT`
or
`set osd_video_system = BFHDCOMPAT`
## Limitations
* Canvas size needs to be manually changed to HD on the Display menu in DJI's goggles (you may need a firmware update) and set as BFHDCOMPAT in the OSD tab of the configurator.
* Unsupported Glyphs show up as `?`
## FAQ
### I see a lot of `?` on my OSD.
That is expected, when your INAV OSD widgets use glyphs that don't have a suitable mapping in BetaFlight's font.
### Does it work with the G2 and Original Air Unit/Vista?
Yes.
### Is this a replacement for WTFOS?
Not exactly. WTFOS is a full implementation of MSP-Displayport for rooted Air Unit/Vista/Googles V2 and actually works much better than BetaFlight compatibility mode, being able to display all INAV's glyphs.
### Can INAV fix DJI's product?
No. OSD renderinng happens on the googles/air unit side of things. Please ask DJI to fix their incomplete MSP DisplayPort implemenation. You can probably request it in [DJI's forum](https://forum.dji.com/forum.php?mod=forumdisplay&fid=129&filter=typeid&typeid=767).
### BetaFlight X.Y now has more symbols, can you update INAV?
Maybe. If a future version of BetaFlight includes more Glyphs that can be mapped into INAV it is fairly simple to add the mapping, but the problem with DJI's implemenation persists. Even if we update the mapping, if DJI does not update the fonts on their side the problem will persist.
### Can you replace glyph `X` with text `x description`?
While it might technically be possible to replace some glyphs with text in multiple cells, it will introduce a lot of complexity in the OSD rendering and configuration for something we hope is a temporary workaround.
### Does DJI support Canvas Mode?
Actually, no. What DJI calls Canvas Mode is actually MSP DisplayPort and is a character based OSD.

View file

@ -12,6 +12,9 @@ These boards are well tested with INAV and are known to be of good quality and r
| [Holybro Kakute H7](https://inavflight.com/shop/s/bg/1914066) | H7 | KAKUTEH7 | All | All | All | All | All | SERIAL, SD |
It's possible to find more supported and tested boards [here](https://github.com/iNavFlight/inav/wiki/Welcome-to-INAV,-useful-links-and-products)
There is also a [full list of all supported boards](https://github.com/iNavFlight/inav/wiki/Boards,-Targets-and-PWM-allocations).
### Boards documentation
See the [docs/boards](https://github.com/iNavFlight/inav/tree/master/docs/boards) folder for additional information regards to many targets in INAV, to example help in finding pinout and features. _Feel free to help improve the docs._

View file

@ -0,0 +1,79 @@
# Broken USB recovery
It is possible to flash INAV without USB over UART 1 or 3.
## Prerequisites:
- USB/UART adapter (FT232, CP2102, etc.)
- STM32 Cube Programmer (https://www.st.com/en/development-tools/stm32cubeprog.html)
To gain access to the FC via Configurator, MSP must be activated on a UART as standard. Some FCs already have this enabled by default, if not a custom firmware must be created.
The following targets have MSP activated on a UART by default:
| Target | Standard MSP Port |
|-----------| ----------- |
| AOCODARCF4V3 | UART5 |
| ATOMRCF405NAVI_DELUXE | UART1 |
| FF_F35_LIGHTNING | UART1 |
| FLYCOLORF7V2 | UART4 |
| GEPRCF405_BT_HD | UART5* |
| GEPRCF722_BT_HD | UART4* |
| IFLIGHT_BLITZ_F7_AIO | UART1 |
| JHEMCUF405WING | UART6 |
| JHEMCUH743HD | UART4 |
| KAKUTEH7 | UART1 and UART2* |
| KAKUTEH7WING | UART6 |
| MAMBAF405_2022A | UART4 |
| MAMBAF405US | UART4 |
| MAMBAF722 | UART4 |
| MAMBAF722 APP | UART4*|
| MAMBAF722WING | UART4 |
| MAMBAF722_X8 | UART4 |
| MAMBAH743 | UART4* |
| MATEKF405SE | UART1 |
| NEUTRONRCH743BT | UART3* |
| SDMODELH7V1 | UART1 and UART2 |
| SKYSTARSH743HD | UART4 |
| SPEEDYBEEF4 | UART5* |
| SPEEDYBEEF405MINI | UART4* |
| SPEEDYBEEF405V3 | UART4* |
| SPEEDYBEEF405V4 | UART4* |
| SPEEDYBEEF405WING | UART6 |
| SPEEDYBEEF7 | UART6 |
| SPRACINGF4EVO | UART1 |
| TMOTORF7V2 | UART5 |
(*) No Pads/Pins, Port is used interally (Bluetooth)
## Custom firmware:
If the FC does not have MSP activated on a UART by default or does not have a connector for it, a custom firmware must be built.
The following procedure describes the process under Windows 10/11:
Please read [Building in Windows 2010 or 11 with Linux Subsystem](https://github.com/iNavFlight/inav/blob/master/docs/development/Building%20in%20Windows%2010%20or%2011%20with%20Linux%20Subsystem.md)
and follow the instructions up to "Building with Make".
In the step 'prepare build environment' add the option `-DMSP_UART=SERIAL_PORT_USARTX` to `cmake`
Replace the X in SERIAL_PORT_USARTX with the number of UART/serial port on which MSP is to be activated.
Example:
For UART 2: `cmake -DMSP_UART=SERIAL_PORT_USART2 ..`
For UART 3: `cmake -DMSP_UART=SERIAL_PORT_USART3 ..`
etc.
Build the firmware as described in the document above (`make [YOUR_TARGET]`).
## Flashing via Uart:
1. Disconnect ALL peripherals and the USB Cable from the FC. To power the FC use a battery or use the 5V provided from the USB/Serial Converter.
2. Connect UART 1 or 3 (other UARTS will not work) and GND to the USB/Serial converter (RX -> TX, TX -> RX)
3. Keep the boot/dfu button pressed
4. Switch on the FC / supply with power
5. Start STM32 CubeProgrammer and go to "Erasing & Programming", second option in the menu.
6. Select UART (blue dropdown field) and select the COM port of the USB/Serial adapter and press "Connect". The corresponding processor should now be displayed below.
7. Click on "Full flash erase". This is also necessary if you are flashing the same firmware version that was previously on the FC, otherwise MSP may not be activated on the UART.
8. Under "Download" load the previously created firmware (`INAV_X.X.X_[Your Target].hex`) or the standard firmware if UART is already activated there. The option "Verify programming" is optional but recommended. Make sure that "Skip flash erase while programming" is NOT activated.
9. Click "Start Programming"
After the process is completed, switch the FC off and on again and then the Configurator can connect to the FC via USB/serial adapter and the previously configured UART.

View file

@ -0,0 +1,50 @@
# DJI compatible MSP DisplayPort OSD (DJI O3 "Canvas Mode")
INAV 6.0 includes a special mode for MSP DisplayPort that supports DJI's incomplete implementations of MSP DisplayPort. This can be found on products like the DJI O3 Air Unit. INAV 6.1 expands this to include HD canvas sizes from BetaFlight 4.4.
Different flight controller firmware have different OSD symbols and elements and require different fonts. BetaFlight's font is a single page and supports a maximum of 256 glyphs, INAV's font is currently 2 pages and supports up to 512 different glyphs. DJI's font is single page and based, but not the same as, BetaFlight's font.
While there is some overlap between the glyphs in DJI and INAV, it is not possible to perform a 1 to 1 mapping for all the them. In cases where there is no suitable glyph in the DJI font, a question mark `?` will be displayed.
This mode can be enabled by selecting DJI43COMPAT or DJIHDCOMPAT as video format in the OSD tab of the configurator or by typing the following command on the CLI:
`set osd_video_system = DJI43COMPAT`
or
`set osd_video_system = DJIHDCOMPAT`
## Limitations
* Canvas size needs to be manually changed to HD on the Display menu in DJI's goggles (you may need a firmware update) and set as DJIHDCOMPAT in the OSD tab of the configurator.
* Unsupported Glyphs show up as `?`
## FAQ
### I see a lot of `?` on my OSD.
That is expected. When your INAV OSD widgets use glyphs that don't have a suitable mapping in DJI's font.
### Does it work with the G2 and Original Air Unit/Vista?
Yes.
### Is this a replacement for WTFOS?
Not exactly. WTFOS is a full implementation of MSP-Displayport for rooted Air Unit/Vista/Googles V2 and actually works much better than DJI compatibility mode. It can use all of INAV's OSD elements as intended. If you have the option of WTFOS or DJI compatability mode. WTFOS is the best option.
### Can INAV fix DJI's product?
No. OSD renderinng happens on the googles/air unit side of things. Please ask DJI to fix their incomplete MSP DisplayPort implemenation. You can probably request it in [DJI's forum](https://forum.dji.com/forum.php?mod=forumdisplay&fid=129&filter=typeid&typeid=767). To see what you're missing out on with O3. Check out what WTFOS did with the original system. Not only could the pilots upload the fonts of their choosing (who doesn't want a cool SneakyFPV font on their OSD). But there were no problems supporting and firmware. Plus, there was even an option to save the OSD to a file and overlay that over your DVR video. If you're reading this far. Please recommend to DJI that they fix their product, to at least what was possible with WTFOS.
### DJI's font now has more symbols, can you update INAV?
Maybe. If a future version of DJI's font includes more Glyphs that can be mapped into INAV. It is fairly simple to add the mapping. However, the best solution would be full support of MSP DisplayPort by DJI. Then there will never be an issue with missing icons. As the latest INAV font would be able to be uploaded on to the goggles.
### Can you replace glyph `X` with text `x description`?
While it might technically be possible to replace some glyphs with text in multiple cells, it will introduce a lot of complexity in the OSD rendering and configuration for something we hope is a temporary workaround.
### Does DJI support Canvas Mode?
Actually, no. What DJI calls Canvas Mode is actually MSP DisplayPort and is a character based OSD. Currently, the only true implementaion of Canvas Mode is with FrSKY PixelOSD. This was found on some F722 flight controllers from Matek.

View file

@ -13,7 +13,7 @@ INAV support the following ESC protocols:
ESC protocol can be selected in Configurator. No special configuration is required.
Check ESC documentation of the list of protocols that it is supporting.
Check the ESC documentation for the list of protocols that are supported.
## Servo outputs
@ -28,23 +28,8 @@ While motors are usually ordered sequentially, here is no standard output layout
## Modifying output mapping
### Modifying all outputs at the same time
Since INAV 5, it has been possible to force *ALL* outputs to be `MOTORS` or `SERVOS`.
Traditional ESCs usually can be controlled via a servo output, but would require calibration.
This can be done with the `output_mode` CLI setting. Allowed values:
* `AUTO` assigns outputs according to the default mapping
* `SERVOS` assigns all outputs to servos
* `MOTORS` assigns all outputs to motors
### Modifying only some outputs
INAV 7 introduced extra functionality that let you force only some outputs to be either *MOTORS* or *SERVOS*, with some restrictions dictated by the hardware.
The mains restrictions is that outputs need to be associated with timers, which are usually shared between multiple outputs. Two outputs on the same timer need to have the same function.
The main restrictions is that outputs are associated with timers, which can be shared between multiple outputs and two outputs on the same timer need to have the same function.
The easiest way to modify outputs, is to use the Mixer tab in the Configurator, as it will clearly show you which timer is used by all outputs, but you can also use `timer_output_mode` on the cli.
This can be used in conjunction to the previous method, in that cass all outputs will follow `output_mode` and `timer_output_mode` overrides are applied after that.

View file

@ -82,6 +82,23 @@ In degrees. Min: 0, Max: 45, Default: 0
* `nav_fw_land_max_tailwind`: Max. tailwind if no landing direction with downwind is available. Wind strengths below this value are ignored (error tolerance in the wind measurement). Landing then takes place in the main direction. If, for example, 90 degrees is configured, landing takes place in this direction, NOT in 270 degrees (see above).
In cm/s. Min: 0; Max: 3000, Default: 140
### General paramters and tuning tips
* `nav_fw_wp_tracking_accuracy`: Its highly recommended that this parameter is used and tuned well. Only with WP-Tracking enabled, the Aircraft will try to precisely align with the runway during approach.
If WP-Tracking is not used, the Plane will head straight to the landiung location without flying in line with the intended landing strip. Wind can intensively alter the final landing heading.
* `nav_fw_pitch2thr`: The navigation throttle modifier has to be tuned well to allow stable navigation during climbs and descents to prevent a stall. Make sure your plane maintains Ground or Airspeed, when climbing in any navigation mode.
The Craft should not get slower and not speed ub significantly during a navigation climb, if P2T is tuned properly.
* `nav_wp_radius`: This parameter might be too high if you have set up your craft with INAV 6 or INAV 7. With a too high value, the turning points for the Crosswind-Leg and Final Approach are hit too early and make it difficult for the plane to align to the runway or cut short the approach.
Make sure this parameter is not set greater than 1000 (cm). The better your craft and navigation system is tuned, the lower this value can be. We recommend to start with 1000 for flying wings and 800 for a Plane with Tail.
* Test your Navigation-Tuning: A better Navigation-Tune will reward you with smoother and more reliable landings. To test your nav systems limit, we recommend to create a waypoint missions with many 90° turn angles with shorter and shorter tracks.
With this Method, you can find out how well your plane can follow a navigation path and how long it takes to align to a waypoint track. A well tuned plane should be able to pull of a WP Mission that looks like this, where the distance between WP6 and WP7 si recommended to be the minimum approach length:
![Test Waypoint Track](https://github.com/iNavFlight/inav/assets/33039058/a929cd0c-80b1-42d6-815d-89a90e9daa1b)
## Waypoint missions
Only one landing waypoint per mission can be active and saved and the landing waypoint must be the last waypoint of the mission.

132
docs/GPS_fix_estimation.md Normal file
View file

@ -0,0 +1,132 @@
# GPS Fix estimation (dead reconing, RTH without GPS) for fixed wing
Video demonstration
[![IMAGE ALT TEXT HERE](https://img.youtube.com/vi/wzvgRpXCS4U/0.jpg)](https://www.youtube.com/watch?v=wzvgRpXCS4U)
There is possibility to allow plane to estimate it's position when GPS fix is lost.
The main purpose is RTH without GPS.
It works for fixed wing only.
Plane should have the following sensors:
- acceleromenter, gyroscope
- barometer
- GPS
- magnethometer (optional, highly recommended)
- pitot (optional)
By befault, all navigation modes are disabled when GPS fix is lost. If RC signal is lost also, plane will not be able to enable RTH. Plane will switch to LANDING instead. When flying above unreachable spaces, plane will be lost.
GPS fix estimation allows to recover plane using magnetometer and baromener only.
GPS Fix is also estimated on GPS Sensor timeouts (hardware failures).
Note, that GPS fix estimation is not a solution for navigation without GPS. Without GPS fix, position error accumulates quickly. But it is acceptable for RTH. This is not a solution for flying under spoofing also. GPS is the most trusted sensor in Inav. It's output is not validated.
# How it works ?
In normal situation, plane is receiving it's position from GPS sensor. This way it is able to hold course, RTH or navigate by waypoints.
Without GPS fix, plane has nose heading from magnetometer and height from barometer only.
To navigate without GPS fix, we make the following assumptions:
- plane is flying in the direction where nose is pointing
- (if pitot tube is not installed) plane is flying with constant airspeed, specified in settings
It is possible to roughly estimate position using theese assumptions. To increase accuracy, plane will use information about wind direction and speed, estimated before GPS fix was lost. To increase groundspeed estimation accuracy, plane will use pitot tube data(if available).
From estimated heading direction and speed, plane is able to **roughly** estimate it's position.
It is assumed, that plane will fly in roughly estimated direction to home position untill either GPS fix or RC signal is recovered.
*Plane has to acquire GPS fix and store home position before takeoff. Estimation completely without GPS fix will not work*.
# Estimation without magnethometer
Without magnethometer, navigation accuracy is very poor. The problem is heading drift.
The longer plane flies without magnethometer or GPS, the bigger is course estimation error.
After few minutes and few turns, "North" direction estimation can be completely broken.
In general, accuracy is enough to perform RTH U-turn when both RC controls and GPS are lost, and roughtly keep RTH direction in areas with occasional GPS outages.
![image](https://github.com/RomanLut/inav/assets/11955117/3d5c5d10-f43a-45f9-a647-af3cca87c4da)
(purple line - estimated position, black line - real position).
It is recommened to use GPS fix estimation without magnethometer as last resort only. For example, if plane is flying above lake, landing means loss of plane. With GPS Fix estimation, plane will try to do RTH in very rought direction, instead of landing.
It is up to user to estimate the risk of fly-away.
# Settings
GPS Fix estimation is enabled with CLI command:
```set inav_allow_gps_fix_estimation=ON```
Also you have to specify cruise airspeed of the plane.
To find out cruise airspeed, make a test flight. Enable ground speed display on OSD. Flight in CRUISE mode in two opposite directions. Take average speed.
Cruise airspeed is specified in cm/s.
To convert km/h to m/s, multiply by 27.77.
Example: 100 km/h = 100 * 27.77 = 2777 cm/s
```set fw_reference_airspeed=2777```
*It is important, that plane fly with specified speed in CRUISE mode. If you have set option "Increase cruise speed with throttle" - do not use it without GPS Fix.*
*If pitot is available, pitot sensor data will be used instead of constant. It is not necessary to specify fw_reference_airspeed. However, it is still adviced to specify for the case of pitot failure.*
*Note related command: to continue mission without RC signal, see command ```set failsafe_mission_delay=-1```.*
**After entering CLI command, make sure that settings are saved:**
```save```
# Disabling GPS sensor from RC controller
![](Screenshots/programming_disable_gps_sensor_fix.png)
For testing purposes, it is possible to disable GPS sensor fix from RC controller in programming tab:
*GPS can be disabled only after: 1) initial GPS fix is acquired 2) in ARMED mode.*
# Allowing wp missions with GPS Fix estimation
```failsafe_gps_fix_estimation_delay```
Controls whether waypoint mission is allowed to proceed with gps fix estimation. Sets the time delay in seconds between gps fix lost event and RTH activation. Minimum delay is 7 seconds. If set to -1 the mission will continue until the end. With default setting(7), waypoint mission is aborted and switched to RTH with 7 seconds delay. RTH is done with GPS Fix estimation. RTH is trigerred regradless of failsafe procedure selected in configurator.
# Expected error (mag + baro)
Realistic expected error is up to 200m per 1km of flight path. In tests, 500m drift per 5km path was seen.
To dicrease drift:
- fly one large circle with GPS available to get good wind estimation
- use airspeed sensor. If airspeed sensor is not installed, fly in cruise mode without throttle override.
- do smooth, large turns
- make sure compass is pointing in nose direction precicely
- calibrate compass correctly
This video shows real world test where GPS was disabled occasionally. Wind is 10km/h south-west:
https://github.com/RomanLut/inav/assets/11955117/0599a3c3-df06-4d40-a32a-4d8f96140592
Purple line shows estimated position. Black line shows real position. "EST ERR" sensor shows estimation error in metters. Estimation is running when satellite icon displays "ES". Estimated position snaps to real position when GPS fix is reaquired.
# Is it possible to implement this for multirotor ?
There are some ideas, but there is no solution now. We can not make assumptions with multirotor which we can make with a fixed wing.
# Links
INAV HITL https://github.com/RomanLut/INAV-X-Plane-HITL

View file

@ -70,7 +70,7 @@ Now, there are two ways to [configure CF](Configuration.md); via the Configurat
* Verify the range of each channel goes from ~1000 to ~2000. See also [controls](Controls.md). and `rx_min_usec` and `rx_max_usec`.
* You can also set EXPO here instead of your Tx.
* Click Save!
* Modes tab: Setup the desired modes. See the [modes](Modes.md) chapter for what each mode does, but for the beginning you mainly need HORIZON, if any.
* Modes tab: Setup the desired modes. See the [Modes in the wiki](https://github.com/iNavFlight/inav/wiki/Modes) for what each mode does.
* Before finishing this section, you should calibrate the ESCs, install the FC to the frame, and connect the RSSI cable, buzzer and battery if you have chosen to use those.

View file

@ -19,155 +19,156 @@ Not all OSDs are created equally. This table shows the differences between the d
## OSD Elements
Here are the OSD Elements provided by INAV.
| ID | Element | Added |
|-----|--------------------------------------------------|--------|
| 0 | OSD_RSSI_VALUE | 1.0.0 |
| 1 | OSD_MAIN_BATT_VOLTAGE | 1.0.0 |
| 2 | OSD_CROSSHAIRS | 1.0.0 |
| 3 | OSD_ARTIFICIAL_HORIZON | 1.0.0 |
| 4 | OSD_HORIZON_SIDEBARS | 1.0.0 |
| 5 | OSD_ONTIME | 1.0.0 |
| 6 | OSD_FLYTIME | 1.0.0 |
| 7 | OSD_FLYMODE | 1.0.0 |
| 8 | OSD_CRAFT_NAME | 1.0.0 |
| 9 | OSD_THROTTLE_POS | 1.0.0 |
| 10 | OSD_VTX_CHANNEL | 1.0.0 |
| 11 | OSD_CURRENT_DRAW | 1.0.0 |
| 12 | OSD_MAH_DRAWN | 1.0.0 |
| 13 | OSD_GPS_SPEED | 1.0.0 |
| 14 | OSD_GPS_SATS | 1.0.0 |
| 15 | OSD_ALTITUDE | 1.0.0 |
| 16 | OSD_ROLL_PIDS | 1.6.0 |
| 17 | OSD_PITCH_PIDS | 1.6.0 |
| 18 | OSD_YAW_PIDS | 1.6.0 |
| 19 | OSD_POWER | 1.6.0 |
| 20 | OSD_GPS_LON | 1.6.0 |
| 21 | OSD_GPS_LAT | 1.6.0 |
| 22 | OSD_HOME_DIR | 1.6.0 |
| 23 | OSD_HOME_DIST | 1.6.0 |
| 24 | OSD_HEADING | 1.6.0 |
| 25 | OSD_VARIO | 1.6.0 |
| 26 | OSD_VARIO_NUM | 1.6.0 |
| 27 | OSD_AIR_SPEED | 1.7.3 |
| 28 | OSD_ONTIME_FLYTIME | 1.8.0 |
| 29 | OSD_RTC_TIME | 1.8.0 |
| 30 | OSD_MESSAGES | 1.8.0 |
| 31 | OSD_GPS_HDOP | 1.8.0 |
| 32 | OSD_MAIN_BATT_CELL_VOLTAGE | 1.8.0 |
| 33 | OSD_SCALED_THROTTLE_POS | 1.8.0 |
| 34 | OSD_HEADING_GRAPH | 1.8.0 |
| 35 | OSD_EFFICIENCY_MAH_PER_KM | 1.9.0 |
| 36 | OSD_WH_DRAWN | 1.9.0 |
| 37 | OSD_BATTERY_REMAINING_CAPACITY | 1.9.0 |
| 38 | OSD_BATTERY_REMAINING_PERCENT | 1.9.0 |
| 39 | OSD_EFFICIENCY_WH_PER_KM | 1.9.0 |
| 40 | OSD_TRIP_DIST | 1.9.1 |
| 41 | OSD_ATTITUDE_PITCH | 2.0.0 |
| 42 | OSD_ATTITUDE_ROLL | 2.0.0 |
| 43 | OSD_MAP_NORTH | 2.0.0 |
| 44 | OSD_MAP_TAKEOFF | 2.0.0 |
| 45 | OSD_RADAR | 2.0.0 |
| 46 | OSD_WIND_SPEED_HORIZONTAL | 2.0.0 |
| 47 | OSD_WIND_SPEED_VERTICAL | 2.0.0 |
| 48 | OSD_REMAINING_FLIGHT_TIME_BEFORE_RTH | 2.0.0 |
| 49 | OSD_REMAINING_DISTANCE_BEFORE_RTH | 2.0.0 |
| 50 | OSD_HOME_HEADING_ERROR | 2.0.0 |
| 51 | OSD_COURSE_HOLD_ERROR | 2.0.0 |
| 52 | OSD_COURSE_HOLD_ADJUSTMENT | 2.0.0 |
| 53 | OSD_SAG_COMPENSATED_MAIN_BATT_VOLTAGE | 2.0.0 |
| 54 | OSD_MAIN_BATT_SAG_COMPENSATED_CELL_VOLTAGE | 2.0.0 |
| 55 | OSD_POWER_SUPPLY_IMPEDANCE | 2.0.0 |
| 56 | OSD_LEVEL_PIDS | 2.0.0 |
| 57 | OSD_POS_XY_PIDS | 2.0.0 |
| 58 | OSD_POS_Z_PIDS | 2.0.0 |
| 59 | OSD_VEL_XY_PIDS | 2.0.0 |
| 60 | OSD_VEL_Z_PIDS | 2.0.0 |
| 61 | OSD_HEADING_P | 2.0.0 |
| 62 | OSD_BOARD_ALIGN_ROLL | 2.0.0 |
| 63 | OSD_BOARD_ALIGN_PITCH | 2.0.0 |
| 64 | OSD_RC_EXPO | 2.0.0 |
| 65 | OSD_RC_YAW_EXPO | 2.0.0 |
| 66 | OSD_THROTTLE_EXPO | 2.0.0 |
| 67 | OSD_PITCH_RATE | 2.0.0 |
| 68 | OSD_ROLL_RATE | 2.0.0 |
| 69 | OSD_YAW_RATE | 2.0.0 |
| 70 | OSD_MANUAL_RC_EXPO | 2.0.0 |
| 71 | OSD_MANUAL_RC_YAW_EXPO | 2.0.0 |
| 72 | OSD_MANUAL_PITCH_RATE | 2.0.0 |
| 73 | OSD_MANUAL_ROLL_RATE | 2.0.0 |
| 74 | OSD_MANUAL_YAW_RATE | 2.0.0 |
| 75 | OSD_NAV_FW_CRUISE_THR | 2.0.0 |
| 76 | OSD_NAV_FW_PITCH2THR | 2.0.0 |
| 77 | OSD_FW_MIN_THROTTLE_DOWN_PITCH_ANGLE | 2.0.0 |
| 78 | OSD_DEBUG | 2.0.0 |
| 79 | OSD_FW_ALT_PID_OUTPUTS | 2.0.0 |
| 80 | OSD_FW_POS_PID_OUTPUTS | 2.0.0 |
| 81 | OSD_MC_VEL_X_PID_OUTPUTS | 2.0.0 |
| 82 | OSD_MC_VEL_Y_PID_OUTPUTS | 2.0.0 |
| 83 | OSD_MC_VEL_Z_PID_OUTPUTS | 2.0.0 |
| 84 | OSD_MC_POS_XYZ_P_OUTPUTS | 2.0.0 |
| 85 | OSD_3D_SPEED | 2.1.0 |
| 86 | OSD_IMU_TEMPERATURE | 2.1.0 |
| 87 | OSD_BARO_TEMPERATURE | 2.1.0 |
| 88 | OSD_TEMP_SENSOR_0_TEMPERATURE | 2.1.0 |
| 89 | OSD_TEMP_SENSOR_1_TEMPERATURE | 2.1.0 |
| 90 | OSD_TEMP_SENSOR_2_TEMPERATURE | 2.1.0 |
| 91 | OSD_TEMP_SENSOR_3_TEMPERATURE | 2.1.0 |
| 92 | OSD_TEMP_SENSOR_4_TEMPERATURE | 2.1.0 |
| 93 | OSD_TEMP_SENSOR_5_TEMPERATURE | 2.1.0 |
| 94 | OSD_TEMP_SENSOR_6_TEMPERATURE | 2.1.0 |
| 95 | OSD_TEMP_SENSOR_7_TEMPERATURE | 2.1.0 |
| 96 | OSD_ALTITUDE_MSL | 2.1.0 |
| 97 | OSD_PLUS_CODE | 2.1.0 |
| 98 | OSD_MAP_SCALE | 2.2.0 |
| 99 | OSD_MAP_REFERENCE | 2.2.0 |
| 100 | OSD_GFORCE | 2.2.0 |
| 101 | OSD_GFORCE_X | 2.2.0 |
| 102 | OSD_GFORCE_Y | 2.2.0 |
| 103 | OSD_GFORCE_Z | 2.2.0 |
| 104 | OSD_RC_SOURCE | 2.2.0 |
| 105 | OSD_VTX_POWER | 2.2.0 |
| 106 | OSD_ESC_RPM | 2.3.0 |
| 107 | OSD_ESC_TEMPERATURE | 2.5.0 |
| 108 | OSD_AZIMUTH | 2.6.0 |
| 109 | OSD_CRSF_RSSI_DBM | 2.6.0 |
| 110 | OSD_CRSF_LQ | 2.6.0 |
| 111 | OSD_CRSF_SNR_DB | 2.6.0 |
| 112 | OSD_CRSF_TX_POWER | 2.6.0 |
| 113 | OSD_GVAR_0 | 2.6.0 |
| 114 | OSD_GVAR_1 | 2.6.0 |
| 115 | OSD_GVAR_2 | 2.6.0 |
| 116 | OSD_GVAR_3 | 2.6.0 |
| 117 | OSD_TPA | 2.6.0 |
| 118 | OSD_NAV_FW_CONTROL_SMOOTHNESS | 2.6.0 |
| 119 | OSD_VERSION | 3.0.0 |
| 120 | OSD_RANGEFINDER | 3.0.0 |
| 121 | OSD_PLIMIT_REMAINING_BURST_TIME | 3.0.0 |
| 122 | OSD_PLIMIT_ACTIVE_CURRENT_LIMIT | 3.0.0 |
| 123 | OSD_PLIMIT_ACTIVE_POWER_LIMIT | 3.0.0 |
| 124 | OSD_GLIDESLOPE | 3.0.1 |
| 125 | OSD_GPS_MAX_SPEED | 4.0.0 |
| 126 | OSD_3D_MAX_SPEED | 4.0.0 |
| 127 | OSD_AIR_MAX_SPEED | 4.0.0 |
| 128 | OSD_ACTIVE_PROFILE | 4.0.0 |
| 129 | OSD_MISSION | 4.0.0 |
| 130 | OSD_SWITCH_INDICATOR_0 | 5.0.0 |
| 131 | OSD_SWITCH_INDICATOR_1 | 5.0.0 |
| 132 | OSD_SWITCH_INDICATOR_2 | 5.0.0 |
| 133 | OSD_SWITCH_INDICATOR_3 | 5.0.0 |
| 134 | OSD_TPA_TIME_CONSTANT | 5.0.0 |
| 135 | OSD_FW_LEVEL_TRIM | 5.0.0 |
| 136 | OSD_GLIDE_TIME_REMAINING | 6.0.0 |
| 137 | OSD_GLIDE_RANGE | 6.0.0 |
| 138 | OSD_CLIMB_EFFICIENCY | 6.0.0 |
| 139 | OSD_NAV_WP_MULTI_MISSION_INDEX | 6.0.0 |
| 140 | OSD_GROUND_COURSE | 6.0.0 |
| 141 | OSD_CROSS_TRACK_ERROR | 6.0.0 |
| 142 | OSD_PILOT_NAME | 6.0.0 |
| 143 | OSD_PAN_SERVO_CENTRED | 6.0.0 |
| 144 | OSD_MULTI_FUNCTION | 7.0.0 |
| 145 | OSD_ODOMETER | 7.0.0 |
| 146 | OSD_PILOT_LOGO | 7.0.0 |
| ID | Element | Added | Notes |
|-----|--------------------------------------------------|--------|-------|
| 0 | OSD_RSSI_VALUE | 1.0.0 | |
| 1 | OSD_MAIN_BATT_VOLTAGE | 1.0.0 | |
| 2 | OSD_CROSSHAIRS | 1.0.0 | |
| 3 | OSD_ARTIFICIAL_HORIZON | 1.0.0 | |
| 4 | OSD_HORIZON_SIDEBARS | 1.0.0 | |
| 5 | OSD_ONTIME | 1.0.0 | |
| 6 | OSD_FLYTIME | 1.0.0 | |
| 7 | OSD_FLYMODE | 1.0.0 | |
| 8 | OSD_CRAFT_NAME | 1.0.0 | |
| 9 | OSD_THROTTLE_POS | 1.0.0 | |
| 10 | OSD_VTX_CHANNEL | 1.0.0 | |
| 11 | OSD_CURRENT_DRAW | 1.0.0 | |
| 12 | OSD_MAH_DRAWN | 1.0.0 | |
| 13 | OSD_GPS_SPEED | 1.0.0 | |
| 14 | OSD_GPS_SATS | 1.0.0 | |
| 15 | OSD_ALTITUDE | 1.0.0 | |
| 16 | OSD_ROLL_PIDS | 1.6.0 | |
| 17 | OSD_PITCH_PIDS | 1.6.0 | |
| 18 | OSD_YAW_PIDS | 1.6.0 | |
| 19 | OSD_POWER | 1.6.0 | |
| 20 | OSD_GPS_LON | 1.6.0 | |
| 21 | OSD_GPS_LAT | 1.6.0 | |
| 22 | OSD_HOME_DIR | 1.6.0 | |
| 23 | OSD_HOME_DIST | 1.6.0 | |
| 24 | OSD_HEADING | 1.6.0 | |
| 25 | OSD_VARIO | 1.6.0 | |
| 26 | OSD_VARIO_NUM | 1.6.0 | |
| 27 | OSD_AIR_SPEED | 1.7.3 | |
| 28 | OSD_ONTIME_FLYTIME | 1.8.0 | |
| 29 | OSD_RTC_TIME | 1.8.0 | |
| 30 | OSD_MESSAGES | 1.8.0 | |
| 31 | OSD_GPS_HDOP | 1.8.0 | |
| 32 | OSD_MAIN_BATT_CELL_VOLTAGE | 1.8.0 | |
| 33 | OSD_SCALED_THROTTLE_POS | 1.8.0 | |
| 34 | OSD_HEADING_GRAPH | 1.8.0 | |
| 35 | OSD_EFFICIENCY_MAH_PER_KM | 1.9.0 | |
| 36 | OSD_WH_DRAWN | 1.9.0 | |
| 37 | OSD_BATTERY_REMAINING_CAPACITY | 1.9.0 | |
| 38 | OSD_BATTERY_REMAINING_PERCENT | 1.9.0 | |
| 39 | OSD_EFFICIENCY_WH_PER_KM | 1.9.0 | |
| 40 | OSD_TRIP_DIST | 1.9.1 | |
| 41 | OSD_ATTITUDE_PITCH | 2.0.0 | |
| 42 | OSD_ATTITUDE_ROLL | 2.0.0 | |
| 43 | OSD_MAP_NORTH | 2.0.0 | |
| 44 | OSD_MAP_TAKEOFF | 2.0.0 | |
| 45 | OSD_RADAR | 2.0.0 | |
| 46 | OSD_WIND_SPEED_HORIZONTAL | 2.0.0 | |
| 47 | OSD_WIND_SPEED_VERTICAL | 2.0.0 | |
| 48 | OSD_REMAINING_FLIGHT_TIME_BEFORE_RTH | 2.0.0 | |
| 49 | OSD_REMAINING_DISTANCE_BEFORE_RTH | 2.0.0 | |
| 50 | OSD_HOME_HEADING_ERROR | 2.0.0 | |
| 51 | OSD_COURSE_HOLD_ERROR | 2.0.0 | |
| 52 | OSD_COURSE_HOLD_ADJUSTMENT | 2.0.0 | |
| 53 | OSD_SAG_COMPENSATED_MAIN_BATT_VOLTAGE | 2.0.0 | |
| 54 | OSD_MAIN_BATT_SAG_COMPENSATED_CELL_VOLTAGE | 2.0.0 | |
| 55 | OSD_POWER_SUPPLY_IMPEDANCE | 2.0.0 | |
| 56 | OSD_LEVEL_PIDS | 2.0.0 | |
| 57 | OSD_POS_XY_PIDS | 2.0.0 | |
| 58 | OSD_POS_Z_PIDS | 2.0.0 | |
| 59 | OSD_VEL_XY_PIDS | 2.0.0 | |
| 60 | OSD_VEL_Z_PIDS | 2.0.0 | |
| 61 | OSD_HEADING_P | 2.0.0 | |
| 62 | OSD_BOARD_ALIGN_ROLL | 2.0.0 | |
| 63 | OSD_BOARD_ALIGN_PITCH | 2.0.0 | |
| 64 | OSD_RC_EXPO | 2.0.0 | |
| 65 | OSD_RC_YAW_EXPO | 2.0.0 | |
| 66 | OSD_THROTTLE_EXPO | 2.0.0 | |
| 67 | OSD_PITCH_RATE | 2.0.0 | |
| 68 | OSD_ROLL_RATE | 2.0.0 | |
| 69 | OSD_YAW_RATE | 2.0.0 | |
| 70 | OSD_MANUAL_RC_EXPO | 2.0.0 | |
| 71 | OSD_MANUAL_RC_YAW_EXPO | 2.0.0 | |
| 72 | OSD_MANUAL_PITCH_RATE | 2.0.0 | |
| 73 | OSD_MANUAL_ROLL_RATE | 2.0.0 | |
| 74 | OSD_MANUAL_YAW_RATE | 2.0.0 | |
| 75 | OSD_NAV_FW_CRUISE_THR | 2.0.0 | |
| 76 | OSD_NAV_FW_PITCH2THR | 2.0.0 | |
| 77 | OSD_FW_MIN_THROTTLE_DOWN_PITCH_ANGLE | 2.0.0 | |
| 78 | OSD_DEBUG | 2.0.0 | |
| 79 | OSD_FW_ALT_PID_OUTPUTS | 2.0.0 | |
| 80 | OSD_FW_POS_PID_OUTPUTS | 2.0.0 | |
| 81 | OSD_MC_VEL_X_PID_OUTPUTS | 2.0.0 | |
| 82 | OSD_MC_VEL_Y_PID_OUTPUTS | 2.0.0 | |
| 83 | OSD_MC_VEL_Z_PID_OUTPUTS | 2.0.0 | |
| 84 | OSD_MC_POS_XYZ_P_OUTPUTS | 2.0.0 | |
| 85 | OSD_3D_SPEED | 2.1.0 | |
| 86 | OSD_IMU_TEMPERATURE | 2.1.0 | |
| 87 | OSD_BARO_TEMPERATURE | 2.1.0 | |
| 88 | OSD_TEMP_SENSOR_0_TEMPERATURE | 2.1.0 | |
| 89 | OSD_TEMP_SENSOR_1_TEMPERATURE | 2.1.0 | |
| 90 | OSD_TEMP_SENSOR_2_TEMPERATURE | 2.1.0 | |
| 91 | OSD_TEMP_SENSOR_3_TEMPERATURE | 2.1.0 | |
| 92 | OSD_TEMP_SENSOR_4_TEMPERATURE | 2.1.0 | |
| 93 | OSD_TEMP_SENSOR_5_TEMPERATURE | 2.1.0 | |
| 94 | OSD_TEMP_SENSOR_6_TEMPERATURE | 2.1.0 | |
| 95 | OSD_TEMP_SENSOR_7_TEMPERATURE | 2.1.0 | |
| 96 | OSD_ALTITUDE_MSL | 2.1.0 | |
| 97 | OSD_PLUS_CODE | 2.1.0 | |
| 98 | OSD_MAP_SCALE | 2.2.0 | |
| 99 | OSD_MAP_REFERENCE | 2.2.0 | |
| 100 | OSD_GFORCE | 2.2.0 | |
| 101 | OSD_GFORCE_X | 2.2.0 | |
| 102 | OSD_GFORCE_Y | 2.2.0 | |
| 103 | OSD_GFORCE_Z | 2.2.0 | |
| 104 | OSD_RC_SOURCE | 2.2.0 | |
| 105 | OSD_VTX_POWER | 2.2.0 | |
| 106 | OSD_ESC_RPM | 2.3.0 | |
| 107 | OSD_ESC_TEMPERATURE | 2.5.0 | |
| 108 | OSD_AZIMUTH | 2.6.0 | |
| 109 | OSD_CRSF_RSSI_DBM | 2.6.0 | |
| 110 | OSD_CRSF_LQ | 2.6.0 | |
| 111 | OSD_CRSF_SNR_DB | 2.6.0 | |
| 112 | OSD_CRSF_TX_POWER | 2.6.0 | |
| 113 | OSD_GVAR_0 | 2.6.0 | |
| 114 | OSD_GVAR_1 | 2.6.0 | |
| 115 | OSD_GVAR_2 | 2.6.0 | |
| 116 | OSD_GVAR_3 | 2.6.0 | |
| 117 | OSD_TPA | 2.6.0 | |
| 118 | OSD_NAV_FW_CONTROL_SMOOTHNESS | 2.6.0 | |
| 119 | OSD_VERSION | 3.0.0 | |
| 120 | OSD_RANGEFINDER | 3.0.0 | |
| 121 | OSD_PLIMIT_REMAINING_BURST_TIME | 3.0.0 | |
| 122 | OSD_PLIMIT_ACTIVE_CURRENT_LIMIT | 3.0.0 | |
| 123 | OSD_PLIMIT_ACTIVE_POWER_LIMIT | 3.0.0 | |
| 124 | OSD_GLIDESLOPE | 3.0.1 | |
| 125 | OSD_GPS_MAX_SPEED | 4.0.0 | |
| 126 | OSD_3D_MAX_SPEED | 4.0.0 | |
| 127 | OSD_AIR_MAX_SPEED | 4.0.0 | |
| 128 | OSD_ACTIVE_PROFILE | 4.0.0 | |
| 129 | OSD_MISSION | 4.0.0 | |
| 130 | OSD_SWITCH_INDICATOR_0 | 5.0.0 | |
| 131 | OSD_SWITCH_INDICATOR_1 | 5.0.0 | |
| 132 | OSD_SWITCH_INDICATOR_2 | 5.0.0 | |
| 133 | OSD_SWITCH_INDICATOR_3 | 5.0.0 | |
| 134 | OSD_TPA_TIME_CONSTANT | 5.0.0 | |
| 135 | OSD_FW_LEVEL_TRIM | 5.0.0 | |
| 136 | OSD_GLIDE_TIME_REMAINING | 6.0.0 | |
| 137 | OSD_GLIDE_RANGE | 6.0.0 | |
| 138 | OSD_CLIMB_EFFICIENCY | 6.0.0 | |
| 139 | OSD_NAV_WP_MULTI_MISSION_INDEX | 6.0.0 | |
| 140 | OSD_GROUND_COURSE | 6.0.0 | |
| 141 | OSD_CROSS_TRACK_ERROR | 6.0.0 | |
| 142 | OSD_PILOT_NAME | 6.0.0 | |
| 143 | OSD_PAN_SERVO_CENTRED | 6.0.0 | |
| 144 | OSD_MULTI_FUNCTION | 7.0.0 | |
| 145 | OSD_ODOMETER | 7.0.0 | For this to work correctly, stats must be enabled (`set stats=ON`). Otherwise, this will show the total flight distance. |
| 146 | OSD_PILOT_LOGO | 7.0.0 | |
| 147 | OSD_BLACKBOX | 8.0.0 | The element will be hidden unless blackbox recording is attempted. |
# Pilot Logos
@ -192,3 +193,43 @@ This is an example of the arming screen with the pilot logo enabled. This is usi
This is an example of setting the `osd_inav_to_pilot_logo_spacing` to 0. This will allow a larger, single logo.
![Power on screen example with 0 spacing between logos](https://user-images.githubusercontent.com/17590174/271817352-6206402c-9da4-4682-9d83-790cc2396b00.png)
# Post Flight Statistics
The post flight statistcs are set in the firmware. Statistics are only hidden if the supporting hardware is not present. Due to size contraints. The post flight statistics are spread over 2 pages on analogue systems.
## Statistics shown
| Statistic | Requirement | Page | |
|-------------------------------|-----------------------|-------|-|
| Flight Time | | 1 | The total time from arm to disarm. |
| Flight Distance | | 1 | |
| Maximum Distance From Home | GPS | 1 | |
| Maximum Speed | GPS | 1 | |
| Average Speed | GPS | 1 | |
| Maximum Altitude | Baro/GPS | 1 | |
| Minimum Average Cell Voltage | | 1 | |
| Minimum Pack Voltage | | 1 | |
| Maximum Current | Current Sensor | 1 | |
| Maximum Power | Current Sensor | 1 | |
| Energy Used (Flight) | Current Sensor | 1 | |
| Energy Used (Battery Total) | Current Sensor | 1 | This data is not reset on arming. |
| Average Efficiency | Current Sensor & GPS | 1 | |
| Minimum RSSI | | 2 | |
| Minimum LQ | CRSF | 2 | |
| Minmum dBm | CRSF | 2 | |
| Minimum Satellites | GPS | 2 | |
| Maximum Satellites | GPS | 2 | |
| Minimum ESC Temperature | ESC Telemetry | 2 | |
| Maximum ESC Temperature | ESC Telemetry | 2 | |
| Maximum G-Force | | 2 | |
| Minimum Z axis G-Force | | 2 | |
| Maximum Z axis G-Force | | 2 | |
| Blackbox file number | Blackbox recording | 2 | |
| Disarm method | | 1 & 2 | |
| Settings save status | | 1 & 2 | Shows a message if the settings are being saved or have been saved on disarm. |
## Configuration
There are a couple of settings that allow you to adjust parts of the post flights statistics.
- `osd_stats_page_auto_swap_time` allows you to specify how long each stats page is displayed [seconds]. Reverts to manual control when Roll stick used to change pages. Disabled when set to 0.
- `osd_stats_energy_unit` allows you to choose the unit used for the drawn energy in the OSD stats [MAH/WH] (milliAmpere hour/ Watt hour). Default is MAH.
- `osd_stats_show_metric_efficiency` if you use non-metric units on your OSD. Enabling this option will also show the efficiency in metric.

View file

@ -20,6 +20,23 @@ Following rangefinders are supported:
* UIB - experimental
* MSP - experimental
* TOF10120 - small & lightweight laser range sensor, usable up to 200cm
* TERARANGER EVO - 30cm to 600cm, depends on version https://www.terabee.com/sensors-modules/lidar-tof-range-finders/#individual-distance-measurement-sensors
* NRA15/NRA24 - experimental, UART version
#### NRA15/NRA24
NRA15/NRA24 from nanoradar use US-D1_V0 or NRA protocol, it depends which firmware you use. Radar can be set by firmware
to two different resolutions. See table below.
| Radar | Protocol | Resolution | Name in configurator |
|-------|----------|-----------------|----------------------|
| NRA15 | US-D1_V0 | 0-30m (+-4cm) | USD1_V0 |
| NRA15 | NRA | 0-30m (+-4cm) | NRA |
| NRA15 | NRA | 0-100m (+-10cm) | NRA |
| NRA24 | US-D1_V0 | 0-50m (+-4cm) | USD1_V0 |
| NRA24 | US-D1_V0 | 0-200m (+-10cm) | USD1_V0 |
| NRA24 | NRA | 0-50m (+-4cm) | NRA |
| NRA24 | NRA | 0-200m (+-10cm) | NRA |
## Connections

View file

@ -16,6 +16,10 @@ Currently supported are
INAV SITL communicates for sensor data and control directly with the corresponding simulator, see the documentation of the individual simulators and the Configurator or the command line options.
AS SITL is still an inav software, but running on PC, it is possible to use HITL interface for communication.
INAV-X-Plane-HITL plugin https://github.com/RomanLut/INAV-X-Plane-HITL can be used with SITL.
## Sensors
The following sensors are emulated:
- IMU (Gyro, Accelerometer)
@ -30,13 +34,18 @@ The following sensors are emulated:
Select "FAKE" as type for all mentioned, so that they receive the data from the simulator.
## Serial ports+
UARTs are replaced by TCP starting with port 5760 ascending. UART 1 port 5760, UART2 5761, ...
By default, UART1 and UART2 are available as MSP connections. Other UARTs will have TCP listeners if they have an INAV function assigned.
To connect the Configurator to SITL: Select TCP and connect to ```localhost:5760``` (or ```127.0.0.1:5760``` if your OS doesn't understand `localhost`) (if SITL is running on the same machine).
## Serial ports
UARTs are replaced by TCP starting with port 5760 ascending. UART1 is mapped to port 5760, UART2 to 5761, etc.
By default, UART1 and UART2 are configured for MSP connections. Other UARTs will have TCP listeners if they have an INAV function assigned.
To connect the Configurator to SITL, select "SITL".
Alternativelly, select "TCP" and connect to ```localhost:5760``` (or ```127.0.0.1:5760``` if your OS doesn't understand `localhost`) (if SITL is running on the same machine).
IPv4 and IPv6 are supported, either raw addresses or host-name lookup.
The assignment and status of user UART/TCP connections is displayed on the console.
The assignment and status of used UART/TCP connections is displayed on the console.
```
INAV 6.1.0 SITL
@ -51,39 +60,73 @@ INAV 6.1.0 SITL
All other interfaces (I2C, SPI, etc.) are not emulated.
## Remote control
MSP_RX (TCP/IP) or joystick (via simulator) or serial receiver via USB/Serial interface are supported.
Multiple methods for connecting RC Controllers are available:
- MSP_RX (TCP/IP)
- joystick (via simulator)
- serial receiver via USB to serial converter
- any receiver with proxy flight controller
### MSP_RX
MSP_RX is the default, 18 channels are supported over TCP/IP serial emulation.
MSP_RX is the default, 18 channels are supported over TCP/IP connection.
### Joystick interface
Only 8 channels are supported.
Select "SIM (SITL)" as the receiver and set up a joystick in the simulator, details of which can be found in the documentation for the individual simulators.
Select "SIM (SITL)" as the receiver and set up a joystick in the simulator.
*Not available with INAV-X-Plane-HITL plugin.*
### Serial Receiver via USB
Connect a serial receiver (e.g. SBUS) to the PC via a UART/USB adapter. Configure the receiver in the Configurator as usual.
- Connect a serial receiver to the PC via a USB-to-serial adapter
- Configure the receiver in the SITL as usual
- While starting SITL from configurator, enable "Serial receiver" option
The Configurator offers a built-in option for forwarding the serial data to the SITL TCP port, if SITL is started manually the following option can be used:
The SITL offers a built-in option for forwarding the host's serial port to the SITL UART.
The connection can then be established with a programme that forwards the serial data unaltered to TCP, e.g. with the Python script tcp_serial_redirect.py (https://github.com/Scavanger/TCP-Serial-Redirect)
If necessary, please download the required runtime environment from https://www.python.org/.
Please use the linked version, which has a smaller buffer, otherwise the control response is relatively slow.
Please note that 100000(SBUS) and 420000(CRSF) are non-standart baud rates which may not be supported by some USB-to-serial adapters. FDTI and CH340 should work. CP2102/9 does not work.
### Example SBUS:
For this you need a FT232 module. With FT-Prog (https://ftdichip.com/utilities/) the signals can be inverted: Devices->Scan and Parse, then Hardware Specific -> Invert RS232 Signals -> Invert RXD.
#### Example SBUS:
For this you need a USB-to-serial adapter, receiver with inverter, or receiver which can output inverted SBUS (normal UART).
SBUS protocol is inverted UART.
Receiver's SBUS output should be connected to the USB-to-serial adapter's RX pin (via inverter).
With FT-Prog (https://ftdichip.com/utilities/) the signal can be inverted by adapter: Devices->Scan and Parse, then Hardware Specific -> Invert RS232 Signals -> Invert RXD.
![SITL-SBUS-FT232](assets/SITL-SBUS-FT232.png)
For SBUS, the command line arguments of the python script are:
```python tcp_serial_redirect.py --parity E --stopbits 2 -c 127.0.0.1:[INAV-UART-PORT] COMXX 100000```
![SITL-SBUS](assets/serial_receiver_sbus.png)
### Telemtry
### Telemetry
In the SITL configuration, enable serial receiver on some port and configure receiver type "Serial", "SBUS".
LTM and MAVLink telemetry are supported, either as a discrete function or shared with MSP.
#### Example CRSF:
On receiver side, CRSF is normal UART.
Connect receiver's RX/TX pins (and GND, 5V of course) to USB-To-Serial adapter's TX/RX pins (RX to TX, TX to RX).
![SITL-SBUS](assets/serial_receiver_crsf.png)
In the SITL configuration, enable serial receiver on some port and configure receiver type "Serial", "CRSF".
### Proxy Flight controller
The last, but probably the most easiest way to connect receiver to the SITL, is to use any inav/betaflight Flight controler as proxy.
Connect receiver of any type to FC and configure FC to the point where channels are correctly updated in the "Receiver" tab. Inav and Betaflight are supported.
You also can use your plane/quad ( if receiver is powered from USB).
![SITL-SBUS](assets/serial_receiver_proxy.png)
In the SITL configuration, select "Receiver type: SIM" regardles of the kind of receiver used.
RX Telemetry via a return channel through the receiver is not yet supported by SITL.
## OSD
For the OSD the program INAV-Sim-OSD is available: https://github.com/Scavanger/INAV-SIM-OSD.
@ -91,6 +134,8 @@ For this, activate MSP-Displayport on a UART/TCP port and connect to the corresp
Note: INAV-Sim-OSD only works if the simulator is in window mode.
*With INAV-X-Plane-HITL plugin, OSD is supported natively.*
## Command line
The command line options are only necessary if the SITL executable is started by hand.
@ -103,7 +148,7 @@ If SITL is started without command line options, only a serial MSP / CLI connect
```--path``` Path and file name to config file. If not present, eeprom.bin in the current directory is used. Example: ```C:\INAV_SITL\flying-wing.bin```, ```/home/user/sitl-eeproms/test-eeprom.bin```.
```--sim=[sim]``` Select the simulator. xp = X-Plane, rf = RealFlight. Example: ```--sim=xp```
```--sim=[sim]``` Select the simulator. xp = X-Plane, rf = RealFlight. Example: ```--sim=xp```. If not specified, configurator-only mode is started. Omit for usage with INAV-X-Plane-HITL plugin.
```--simip=[ip]``` Hostname or IP address of the simulator, if you specify a simulator with "--sim" and omit this option IPv4 localhost (`127.0.0.1`) will be used. Example: ```--simip=172.65.21.15```, ```--simip acme-sims.org```, ```--sim ::1```.
@ -118,6 +163,18 @@ To assign motor1 to virtual receiver channel 1, servo 1 to channel 2, and servo2
```--chanmap:M01-01,S01-02,S02-03```
Please also read the documentation of the individual simulators.
```--serialport``` Use serial receiver or proxy FC connected to host's serial port, f.e. ```--serialportCOM5``` or ```--serialportdev/ttyACM3```
```--serialuart``` Map serial receiver to SITL UART, f.e. ```--serialuart=3``` for UART3. Omit if using ```--fcproxy```.
```--baudrate``` Serial receiver baudrate (default: 115200)
```--stopbits=[None|One|Two]``` Serial receiver stopbits (default: One)
```--parity=[Even|None|Odd]``` Serial receiver parity (default: None)
```--fcproxy``` Use inav/betaflight FC as a proxy for serial receiver.
```--help``` Displays help for the command line options.
For options that take an argument, either form `--flag=value` or `--flag value` may be used.
@ -125,46 +182,13 @@ For options that take an argument, either form `--flag=value` or `--flag value`
## Running SITL
It is recommended to start the tools in the following order:
1. Simulator, aircraft should be ready for take-off
2. INAV-SITL
2. SITL
3. OSD
4. serial redirect for RC input
## Compile
For INav-X-Plane-HITL plugin:
1. SITL (Run in configurator-only mode)
2. X-Plane
### Linux and FreeBSD:
Almost like normal, ruby, cmake and make are also required.
With cmake, the option "-DSITL=ON" must be specified.
# #Forwarding serial data for other UART
```
mkdir build_SITL
cd build_SITL
cmake -DSITL=ON ..
make
```
### Windows:
Compile under cygwin, then as in Linux.
Copy cygwin1.dll into the directory, or include cygwin's /bin/ directory in the environment variable PATH.
If the build fails (segfault, possibly out of memory), adding `-DCMAKE_BUILD_TYPE=MinRelSize` to the `cmake` command may help.
#### Build manager
`ninja` may also be used (parallel builds without `-j $(nproc)`):
```
cmake -GNinja -DSITL=ON ..
ninja
```
### Compiler requirements
* Modern GCC. Must be a *real* GCC, macOS faking it with clang will not work. GCC 10 to GCC 13 are known to work.
* Unix sockets networking. Cygwin is required on Windows (vice `winsock`).
* Pthreads
## Supported environments
* Linux on x86_64, ia-32, Aarch64 (e.g. Rpi4), RISCV64 (e.g. VisionFive2)
* Windows on x86_64
* FreeBSD (x86_64 at least).
Other UARTs can then be mapped to host's serial port using external tool, which can be found in directories ```inav-configurator\resources\sitl\linux\Ser2TCP```, ```inav-configurator\resources\sitl\windows\Ser2TCP.exe```

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

View file

@ -6,7 +6,7 @@ As many can attest, multirotors and RC models in general can be very dangerous,
## Before Installing
Please consult the [Cli](Cli.md), [Controls](Controls.md), [Failsafe](Failsafe.md) and [Modes](Modes.md)
Please consult the [Cli](Cli.md), [Controls](Controls.md), [Failsafe](Failsafe.md) and [Modes](https://github.com/iNavFlight/inav/wiki/Modes)
pages for further important information.
You are highly advised to use the Receiver tab in the INAV Configurator, making sure your Rx channel

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View file

@ -104,7 +104,7 @@ Specifies the type of the software LPF of the acc signals. BIQUAD gives better f
### acc_notch_cutoff
_// TODO_
Frequency of the software notch filter to remove mechanical vibrations from the accelerometer measurements. Value is cutoff frequency (Hz)
| Default | Min | Max |
| --- | --- | --- |
@ -114,7 +114,7 @@ _// TODO_
### acc_notch_hz
_// TODO_
Frequency of the software notch filter to remove mechanical vibrations from the accelerometer measurements. Value is center frequency (Hz)
| Default | Min | Max |
| --- | --- | --- |
@ -394,7 +394,7 @@ Defines the deadband of throttle during alt_hold [r/c points]
### antigravity_accelerator
_// TODO_
Multiplier for Antigravity gain. The bigger is the difference between actual and filtered throttle input, the bigger Antigravity gain
| Default | Min | Max |
| --- | --- | --- |
@ -552,16 +552,6 @@ Blackbox logging rate numerator. Use num/denom settings to decide if a frame sho
---
### control_deadband
Stick deadband in [r/c points], applied after r/c deadband and expo. Used to check if sticks are centered.
| Default | Min | Max |
| --- | --- | --- |
| 10 | 2 | 250 |
---
### controlrate_profile
Control rate profile to switch to when the battery profile is selected, 0 to disable and keep the currently selected control rate profile
@ -572,16 +562,6 @@ Control rate profile to switch to when the battery profile is selected, 0 to dis
---
### cpu_underclock
This option is only available on certain architectures (F3 CPUs at the moment). It makes CPU clock lower to reduce interference to long-range RC systems working at 433MHz
| Default | Min | Max |
| --- | --- | --- |
| OFF | OFF | ON |
---
### cruise_power
Power draw at cruise throttle used for remaining flight time/distance estimation in 0.01W unit
@ -634,7 +614,7 @@ ADC , VIRTUAL, NONE. The virtual current sensor, once calibrated, estimates the
### d_boost_gyro_delta_lpf_hz
_// TODO_
Cutoff frequency for the low pass filter applied to the gyro delta signal used for D-term boost. Lower value will produce a smoother D-term boost signal, but it will be more delayed.
| Default | Min | Max |
| --- | --- | --- |
@ -644,7 +624,7 @@ _// TODO_
### d_boost_max
_// TODO_
D-term multiplier when rapid external conditions are detected. Lower values give sharper response to stick input, higher values give smoother response by scaling D-gains up.
| Default | Min | Max |
| --- | --- | --- |
@ -654,7 +634,7 @@ _// TODO_
### d_boost_max_at_acceleration
_// TODO_
Acceleration threshold for D-term multiplier. When acceleration is above this value, D-term multiplier is set to `d_boost_max`
| Default | Min | Max |
| --- | --- | --- |
@ -664,7 +644,7 @@ _// TODO_
### d_boost_min
_// TODO_
D-term multiplier when pilot provides rapid stick input. Lower values give sharper response to stick input, higher values give smoother response.
| Default | Min | Max |
| --- | --- | --- |
@ -678,7 +658,7 @@ These are values (in us) by how much RC input can be different before it's consi
| Default | Min | Max |
| --- | --- | --- |
| 5 | 0 | 32 |
| 2 | 0 | 32 |
---
@ -692,9 +672,9 @@ Defines debug values exposed in debug variables (developer / debugging setting)
---
### disarm_kill_switch
### disarm_always
Disarms the motors independently of throttle value. Setting to OFF reverts to the old behaviour of disarming only when the throttle is low. Only applies when arming and disarming with an AUX channel.
Disarms the motors independently of throttle value. Setting to OFF reverts to the old behaviour of disarming only when the throttle is low.
| Default | Min | Max |
| --- | --- | --- |
@ -772,16 +752,6 @@ Re-purpose the craft name field for messages.
---
### dji_workarounds
Enables workarounds for different versions of MSP protocol used
| Default | Min | Max |
| --- | --- | --- |
| 1 | 0 | 255 |
---
### dshot_beeper_enabled
Whether using DShot motors as beepers is enabled
@ -962,6 +932,16 @@ EzTune response
---
### ez_snappiness
EzTune snappiness
| Default | Min | Max |
| --- | --- | --- |
| 0 | 0 | 100 |
---
### ez_stability
EzTune stability
@ -1012,6 +992,16 @@ Requested yaw rate to execute when `LAND` (or old `SET-THR`) failsafe is active
---
### failsafe_gps_fix_estimation_delay
Controls whether waypoint mission is allowed to proceed with gps fix estimation. Sets the time delay in seconds between gps fix lost event and RTH activation. Minimum delay is 7 seconds. If set to -1 the mission will continue until the end. With default setting(7), waypoint mission is aborted and switched to RTH with 7 seconds delay. RTH is done with GPS Fix estimation.
| Default | Min | Max |
| --- | --- | --- |
| 7 | -1 | 600 |
---
### failsafe_lights
Enable or disable the lights when the `FAILSAFE` flight mode is enabled. The target needs to be compiled with `USE_LIGHTS` [ON/OFF].
@ -1154,7 +1144,7 @@ Defines throw range in us for both ailerons that will be passed to servo mixer v
### fpv_mix_degrees
_// TODO_
The tilt angle of the FPV camera in degrees, used by the FPV ANGLE MIX mode
| Default | Min | Max |
| --- | --- | --- |
@ -1312,13 +1302,33 @@ Fixed-wing rate stabilisation I-gain for YAW
---
### fw_iterm_limit_stick_position
### fw_iterm_lock_engage_threshold
Iterm is not allowed to grow when stick position is above threshold. This solves the problem of bounceback or followthrough when full stick deflection is applied on poorely tuned fixed wings. In other words, stabilization is partialy disabled when pilot is actively controlling the aircraft and active when sticks are not touched. `0` mean stick is in center position, `1` means it is fully deflected to either side
Defines error rate (in percents of max rate) when Iterm Lock is engaged when sticks are release. Iterm Lock will stay active until error drops below this number
| Default | Min | Max |
| --- | --- | --- |
| 0.5 | 0 | 1 |
| 10 | 5 | 25 |
---
### fw_iterm_lock_rate_threshold
Defines rate percentage when full P I and D attenuation should happen. 100 disables Iterm Lock for P and D term
| Default | Min | Max |
| --- | --- | --- |
| 40 | 10 | 100 |
---
### fw_iterm_lock_time_max_ms
Defines max time in milliseconds for how long ITerm Lock will shut down Iterm after sticks are release
| Default | Min | Max |
| --- | --- | --- |
| 500 | 100 | 1000 |
---
@ -1582,16 +1592,6 @@ Gyro processing anti-aliasing filter cutoff frequency. In normal operation this
---
### gyro_anti_aliasing_lpf_type
Specifies the type of the software LPF of the gyro signals.
| Default | Min | Max |
| --- | --- | --- |
| PT1 | | |
---
### gyro_dyn_lpf_curve_expo
Expo value for the throttle-to-frequency mapping for Dynamic LPF
@ -1622,16 +1622,6 @@ Minimum frequency of the gyro Dynamic LPF
---
### gyro_hardware_lpf
Hardware lowpass filter for gyro. This value should never be changed without a very strong reason! If you have to set gyro lpf below 256HZ, it means the frame is vibrating too much, and that should be fixed first.
| Default | Min | Max |
| --- | --- | --- |
| 256HZ | | |
---
### gyro_main_lpf_hz
Software based gyro main lowpass filter. Value is cutoff frequency (Hz)
@ -1642,19 +1632,9 @@ Software based gyro main lowpass filter. Value is cutoff frequency (Hz)
---
### gyro_main_lpf_type
Defines the type of the main gyro LPF filter. Possible values: `PT1`, `BIQUAD`. `PT1` offers faster filter response while `BIQUAD` better attenuation.
| Default | Min | Max |
| --- | --- | --- |
| BIQUAD | | |
---
### gyro_to_use
_// TODO_
On multi-gyro targets, allows to choose which gyro to use. 0 = first gyro, 1 = second gyro
| Default | Min | Max |
| --- | --- | --- |
@ -1772,6 +1752,16 @@ Defines if INAV will dead-reckon over short GPS outages. May also be useful for
---
### inav_allow_gps_fix_estimation
Defines if inav will estimate GPS fix with magnetometer and barometer on GPS outages. Enables navigation and RTH without GPS fix on fixed wing. Also see failsafe_gps_fix_estimation_delay.
| Default | Min | Max |
| --- | --- | --- |
| OFF | OFF | ON |
---
### inav_auto_mag_decl
Automatic setting of magnetic declination based on GPS position. When used manual magnetic declination is ignored.
@ -1842,26 +1832,6 @@ Allows to chose when the home position is reset. Can help prevent resetting home
---
### inav_use_gps_no_baro
Defines if INAV should use only use GPS data for altitude estimation and not barometer. If set to ON, INAV will allow GPS assisted modes and RTH even when there is no barometer installed.
| Default | Min | Max |
| --- | --- | --- |
| OFF | OFF | ON |
---
### inav_use_gps_velned
Defined if INAV should use velocity data provided by GPS module for doing position and speed estimation. If set to OFF INAV will fallback to calculating velocity from GPS coordinates. Using native velocity data may improve performance on some GPS modules. Some GPS modules introduce significant delay and using native velocity may actually result in much worse performance.
| Default | Min | Max |
| --- | --- | --- |
| ON | OFF | ON |
---
### inav_w_acc_bias
Weight for accelerometer drift estimation
@ -1874,7 +1844,7 @@ Weight for accelerometer drift estimation
### inav_w_xy_flow_p
_// TODO_
Weight of optical flow measurements in estimated UAV position.
| Default | Min | Max |
| --- | --- | --- |
@ -1884,7 +1854,7 @@ _// TODO_
### inav_w_xy_flow_v
_// TODO_
Weight of optical flow measurements in estimated UAV speed.
| Default | Min | Max |
| --- | --- | --- |
@ -1964,7 +1934,7 @@ Decay coefficient for estimated climb rate when baro/GPS reference for altitude
### inav_w_z_surface_p
_// TODO_
Weight of rangefinder measurements in estimated altitude. Setting is used on both airplanes and multirotors when rangefinder is present and Surface mode enabled
| Default | Min | Max |
| --- | --- | --- |
@ -1974,7 +1944,7 @@ _// TODO_
### inav_w_z_surface_v
_// TODO_
Weight of rangefinder measurements in estimated climb rate. Setting is used on both airplanes and multirotors when rangefinder is present and Surface mode enabled
| Default | Min | Max |
| --- | --- | --- |
@ -2022,16 +1992,6 @@ PWM mode of LED pin.
---
### ledstrip_visual_beeper
_// TODO_
| Default | Min | Max |
| --- | --- | --- |
| OFF | OFF | ON |
---
### limit_attn_filter_cutoff
Throttle attenuation PI control output filter cutoff frequency
@ -2334,7 +2294,7 @@ Servo travel multiplier for the YAW axis in `MANUAL` flight mode [0-100]%
### mavlink_ext_status_rate
_// TODO_
Rate of the extended status message for MAVLink telemetry
| Default | Min | Max |
| --- | --- | --- |
@ -2344,7 +2304,7 @@ _// TODO_
### mavlink_extra1_rate
_// TODO_
Rate of the extra1 message for MAVLink telemetry
| Default | Min | Max |
| --- | --- | --- |
@ -2354,7 +2314,7 @@ _// TODO_
### mavlink_extra2_rate
_// TODO_
Rate of the extra2 message for MAVLink telemetry
| Default | Min | Max |
| --- | --- | --- |
@ -2364,7 +2324,7 @@ _// TODO_
### mavlink_extra3_rate
_// TODO_
Rate of the extra3 message for MAVLink telemetry
| Default | Min | Max |
| --- | --- | --- |
@ -2374,7 +2334,7 @@ _// TODO_
### mavlink_pos_rate
_// TODO_
Rate of the position message for MAVLink telemetry
| Default | Min | Max |
| --- | --- | --- |
@ -2384,7 +2344,7 @@ _// TODO_
### mavlink_rc_chan_rate
_// TODO_
Rate of the RC channels message for MAVLink telemetry
| Default | Min | Max |
| --- | --- | --- |
@ -2432,16 +2392,6 @@ These are min/max values (in us) which, when a channel is smaller (min) or large
---
### max_throttle
This is the maximum value (in us) sent to esc when armed. Default of 1850 are OK for everyone (legacy). For modern ESCs, higher values (c. 2000) may be more appropriate. If you have brushed motors, the value should be set to 2000.
| Default | Min | Max |
| --- | --- | --- |
| 1850 | PWM_RANGE_MIN | PWM_RANGE_MAX |
---
### mc_cd_lpf_hz
Cutoff frequency for Control Derivative. This controls the cutoff for the LPF that is applied to the CD (Feed Forward) signal to the PID controller. Lower value will produce a smoother CD gain to the controller, but it will be more delayed. Higher values will produce CD gain that may have more noise in the signal depending on your RC link but wil be less delayed.
@ -2564,7 +2514,7 @@ Multicopter rate stabilisation I-gain for YAW
### mc_iterm_relax
_// TODO_
Iterm relax type. When enabled, Iterm will be relaxed when stick is centered. This will help to reduce bounceback and followthrough on multirotors. It is recommended to enable this feature on all multirotors.
| Default | Min | Max |
| --- | --- | --- |
@ -2574,7 +2524,7 @@ _// TODO_
### mc_iterm_relax_cutoff
_// TODO_
Iterm relax cutoff frequency.
| Default | Min | Max |
| --- | --- | --- |
@ -2762,16 +2712,6 @@ Craft name
---
### nav_auto_climb_rate
Maximum climb/descent rate that UAV is allowed to reach during navigation modes. [cm/s]
| Default | Min | Max |
| --- | --- | --- |
| 500 | 10 | 2000 |
---
### nav_auto_disarm_delay
Delay before craft disarms when `nav_disarm_on_landing` is set (ms)
@ -2798,7 +2738,7 @@ Max YAW rate when NAV COURSE HOLD/CRUISE mode is enabled. Set to 0 to disable on
| Default | Min | Max |
| --- | --- | --- |
| 20 | 0 | 120 |
| 60 | 0 | 120 |
---
@ -2842,6 +2782,26 @@ Enable the possibility to manually increase the throttle in auto throttle contro
---
### nav_fw_alt_control_response
Adjusts the deceleration response of fixed wing altitude control as the target altitude is approached. Decrease value to help avoid overshooting the target altitude.
| Default | Min | Max |
| --- | --- | --- |
| 20 | 5 | 100 |
---
### nav_fw_auto_climb_rate
Maximum climb/descent rate that UAV is allowed to reach during navigation modes. [cm/s]
| Default | Min | Max |
| --- | --- | --- |
| 500 | 10 | 2000 |
---
### nav_fw_bank_angle
Max roll angle when rolling / turning in GPS assisted modes, is also restrained by global max_angle_inclination_rll
@ -2994,11 +2954,11 @@ Max. tailwind (in cm/s) if no landing direction with downwind is available
### nav_fw_launch_accel
Forward acceleration threshold for bungee launch of throw launch [cm/s/s], 1G = 981 cm/s/s
Forward acceleration threshold for bungee launch or throw launch [cm/s/s], 1G = 981 cm/s/s
| Default | Min | Max |
| --- | --- | --- |
| 1863 | 1000 | 20000 |
| 1863 | 1500 | 20000 |
---
@ -3152,6 +3112,16 @@ Forward velocity threshold for swing-launch detection [cm/s]
---
### nav_fw_launch_wiggle_to_wake_idle
Trigger the idle throttle by wiggling the plane. 0 = disabled. 1 and 2 signify 1 or 2 yaw wiggles to activate. 1 wiggle has a higher detection point, for airplanes without a tail. 2 wiggles has a lower detection point, but requires the repeated action. This is intended for larger models and airplanes with tails.
| Default | Min | Max |
| --- | --- | --- |
| 0 | 0 | 2 |
---
### nav_fw_loiter_radius
PosHold radius. 3000 to 7500 is a good value (30-75m) [cm]
@ -3162,6 +3132,16 @@ PosHold radius. 3000 to 7500 is a good value (30-75m) [cm]
---
### nav_fw_manual_climb_rate
Maximum climb/descent rate firmware is allowed when processing pilot input for ALTHOLD control mode [cm/s]
| Default | Min | Max |
| --- | --- | --- |
| 300 | 10 | 2500 |
---
### nav_fw_max_thr
Maximum throttle for flying wing in GPS assisted modes
@ -3432,16 +3412,6 @@ Allows immediate landing detection based on G bump at touchdown when set to ON.
---
### nav_manual_climb_rate
Maximum climb/descent rate firmware is allowed when processing pilot input for ALTHOLD control mode [cm/s]
| Default | Min | Max |
| --- | --- | --- |
| 200 | 10 | 2000 |
---
### nav_manual_speed
Maximum speed allowed when processing pilot input for POSHOLD/CRUISE control mode [cm/s] [Multirotor only]
@ -3492,6 +3462,16 @@ If set to STICK the FC remembers the throttle stick position when enabling ALTHO
---
### nav_mc_auto_climb_rate
Maximum climb/descent rate that UAV is allowed to reach during navigation modes. [cm/s]
| Default | Min | Max |
| --- | --- | --- |
| 500 | 10 | 2000 |
---
### nav_mc_bank_angle
Maximum banking angle (deg) that multicopter navigation is allowed to set. Machine must be able to satisfy this angle without loosing altitude
@ -3602,6 +3582,16 @@ Multicopter hover throttle hint for altitude controller. Should be set to approx
---
### nav_mc_manual_climb_rate
Maximum climb/descent rate firmware is allowed when processing pilot input for ALTHOLD control mode [cm/s]
| Default | Min | Max |
| --- | --- | --- |
| 200 | 10 | 2000 |
---
### nav_mc_pos_deceleration_time
Used for stoping distance calculation. Stop position is computed as _speed_ * _nav_mc_pos_deceleration_time_ from the place where sticks are released. Braking mode overrides this setting
@ -3684,7 +3674,7 @@ A point (in percent of both target and current horizontal velocity) where nav_mc
### nav_mc_vel_xy_dterm_lpf_hz
_// TODO_
D-term low pass filter cutoff frequency for horizontal velocity PID controller (Multirotor). It allows to smooth the PosHold CRUISE, WP and RTH when Multirotor is traveling at full speed. Dterm is not attenuated at low speeds, breaking and accelerating.
| Default | Min | Max |
| --- | --- | --- |
@ -3694,7 +3684,7 @@ _// TODO_
### nav_mc_vel_xy_ff
_// TODO_
FF gain of Position-Rate (Velocity to Acceleration)
| Default | Min | Max |
| --- | --- | --- |
@ -4064,7 +4054,7 @@ Selection of OPFLOW hardware.
### opflow_scale
_// TODO_
Optical flow module scale factor
| Default | Min | Max |
| --- | --- | --- |
@ -4072,6 +4062,36 @@ _// TODO_
---
### osd_adsb_distance_alert
Distance inside which ADSB data flashes for proximity warning
| Default | Min | Max |
| --- | --- | --- |
| 3000 | 1 | 64000 |
---
### osd_adsb_distance_warning
Distance in meters of ADSB aircraft that is displayed
| Default | Min | Max |
| --- | --- | --- |
| 20000 | 1 | 64000 |
---
### osd_adsb_ignore_plane_above_me_limit
Ignore adsb planes above, limit, 0 disabled (meters)
| Default | Min | Max |
| --- | --- | --- |
| 0 | 0 | 64000 |
---
### osd_ahi_bordered
Shows a border/corners around the AHI region (pixel OSD only)
@ -4254,7 +4274,7 @@ Set the camera uptilt for the FPV camera in degres, positive is up, negative is
### osd_coordinate_digits
_// TODO_
Number of digits for the coordinates displayed in the OSD [8-11].
| Default | Min | Max |
| --- | --- | --- |
@ -4342,6 +4362,16 @@ Use wind estimation for remaining flight time/distance estimation
---
### osd_estimations_wind_mps
Wind speed estimation in m/s
| Default | Min | Max |
| --- | --- | --- |
| OFF | OFF | ON |
---
### osd_failsafe_switch_layout
If enabled the OSD automatically switches to the first layout during failsafe
@ -4392,6 +4422,16 @@ Value under which the OSD axis g force indicators will blink (g)
---
### osd_highlight_djis_missing_font_symbols
Show question marks where there is no symbol in the DJI font to represent the INAV OSD element's symbol. When off, blank spaces will be used. Only relevent for DJICOMPAT modes.
| Default | Min | Max |
| --- | --- | --- |
| ON | OFF | ON |
---
### osd_home_position_arm_screen
Should home position coordinates be displayed on the arming screen.
@ -4604,7 +4644,7 @@ PWM value for UP key
### osd_left_sidebar_scroll
_// TODO_
Scroll type for the left sidebar
| Default | Min | Max |
| --- | --- | --- |
@ -4734,7 +4774,7 @@ Number of leading digits removed from plus code. Removing 2, 4 and 6 digits requ
### osd_right_sidebar_scroll
_// TODO_
Scroll type for the right sidebar
| Default | Min | Max |
| --- | --- | --- |
@ -4824,7 +4864,7 @@ Sidebar horizontal offset from default position. Positive values move the sideba
### osd_sidebar_scroll_arrows
_// TODO_
Show arrows for scrolling the sidebars
| Default | Min | Max |
| --- | --- | --- |
@ -4862,16 +4902,6 @@ Unit used for the drawn energy in the OSD stats [MAH/WH] (milliAmpere hour/ Watt
---
### osd_stats_min_voltage_unit
Display minimum voltage of the `BATTERY` or the average per `CELL` in the OSD stats.
| Default | Min | Max |
| --- | --- | --- |
| BATTERY | | |
---
### osd_stats_page_auto_swap_time
Auto swap display time interval between disarm stats pages (seconds). Reverts to manual control when Roll stick used to change pages. Disabled when set to 0.
@ -4882,6 +4912,16 @@ Auto swap display time interval between disarm stats pages (seconds). Reverts to
---
### osd_stats_show_metric_efficiency
Enabling this option will show metric efficiency statistics on the post flight stats screen. In addition to the efficiency statistics in your chosen units.
| Default | Min | Max |
| --- | --- | --- |
| OFF | OFF | ON |
---
### osd_switch_indicator_one_channel
RC Channel to use for OSD switch indicator 1.
@ -5062,26 +5102,6 @@ Allows to set type of PID controller used in control loop. Possible values: `NON
---
### pidsum_limit
A limitation to overall amount of correction Flight PID can request on each axis (Roll/Pitch). If when doing a hard maneuver on one axis machine looses orientation on other axis - reducing this parameter may help
| Default | Min | Max |
| --- | --- | --- |
| 500 | PID_SUM_LIMIT_MIN | PID_SUM_LIMIT_MAX |
---
### pidsum_limit_yaw
A limitation to overall amount of correction Flight PID can request on each axis (Yaw). If when doing a hard maneuver on one axis machine looses orientation on other axis - reducing this parameter may help
| Default | Min | Max |
| --- | --- | --- |
| 350 | PID_SUM_LIMIT_MIN | PID_SUM_LIMIT_MAX |
---
### pilot_name
Pilot name
@ -5154,7 +5174,7 @@ Selection of pitot hardware.
### pitot_lpf_milli_hz
_// TODO_
Pitot tube lowpass filter cutoff frequency. Lower cutoff frequencies result in smoother response at expense of command control delay
| Default | Min | Max |
| --- | --- | --- |
@ -5164,7 +5184,7 @@ _// TODO_
### pitot_scale
_// TODO_
Pitot tube scale factor
| Default | Min | Max |
| --- | --- | --- |
@ -5534,7 +5554,7 @@ Used to control when safehomes will be used. Possible values are `OFF`, `RTH` an
### sbus_sync_interval
_// TODO_
SBUS sync interval in us. Default value is 3000us. Lower values may cause issues with some receivers.
| Default | Min | Max |
| --- | --- | --- |
@ -5928,7 +5948,7 @@ The percentage of the throttle range (`max_throttle` - `min_command`) above `min
| Default | Min | Max |
| --- | --- | --- |
| 15 | 0 | 30 |
| 8 | 0 | 30 |
---
@ -6154,7 +6174,7 @@ Some VTXes may report max power incorrectly (i.e. 200mW for a 600mW VTX). Use th
### vtx_pit_mode_chan
_// TODO_
Pit mode channel.
| Default | Min | Max |
| --- | --- | --- |
@ -6218,7 +6238,7 @@ These are values (in us) by how much RC input can be different before it's consi
| Default | Min | Max |
| --- | --- | --- |
| 5 | 0 | 100 |
| 2 | 0 | 100 |
---

Binary file not shown.

After

Width:  |  Height:  |  Size: 286 KiB

View file

@ -0,0 +1,10 @@
# Board - [KAKUTEH7WING](https://holybro.com/products/kakute-h743-wing)
[manufacturer manual](https://cdn.shopify.com/s/files/1/0604/5905/7341/files/Holybro_KakuteH743-Wing_Manual_v1.0_C.pdf?v=1693393206)
Note that this board has two i2c plugs.
The six-pin plug should be used for GPS and compass.
The 4-pin plug should be used for other i2c sesors such as i2c pitot (airspeed sensor), rangefinder, and external
temperature sensors.
![KAKUTEH7WING wiring diagram](../assets/images/KAKUTEH7WING-wiring-diagram.webp)

View file

@ -1,6 +1,6 @@
# SpeedyBee F405 V3
> Notice: At the moment, DSHOT is not supported on SpeedyBe F405 V3. Use Multishot instead
> Notice: DSHOT on SpeedyBe F405 V3 requires INAV 7.0.0 or later. If you are using an older version, use MULTISHOT instead.
> Notice: The analog OSD and the SD card (blackbox) share the same SPI bus, which can cause problems when trying to use analog OSD and blackbox at the same time.

View file

@ -566,7 +566,6 @@ The log end marker is an optional Event ("E") frame of type 0xFF whose payload i
<li> Sticks</li>
<li> Switch_3D</li>
<li> Switch</li>
<li> Killswitch</li>
<li> Failsafe</li>
<li> Navigation</li>
</ol>

View file

@ -0,0 +1,39 @@
## Building SITL
### Linux and FreeBSD:
Almost like normal, ruby, cmake and make are also required.
With cmake, the option "-DSITL=ON" must be specified.
```
mkdir build_SITL
cd build_SITL
cmake -DSITL=ON ..
make
```
### Windows:
Compile under cygwin, then as in Linux.
Copy cygwin1.dll into the directory, or include cygwin's /bin/ directory in the environment variable PATH.
If the build fails (segfault, possibly out of memory), adding `-DCMAKE_BUILD_TYPE=MinRelSize` to the `cmake` command may help.
#### Build manager
`ninja` may also be used (parallel builds without `-j $(nproc)`):
```
cmake -GNinja -DSITL=ON ..
ninja
```
### Compiler requirements
* Modern GCC. Must be a *real* GCC, macOS faking it with clang will not work. GCC 10 to GCC 13 are known to work.
* Unix sockets networking. Cygwin is required on Windows (vice `winsock`).
* Pthreads
## Supported environments
* Linux on x86_64, ia-32, Aarch64 (e.g. Rpi4), RISCV64 (e.g. VisionFive2)
* Windows on x86_64
* FreeBSD (x86_64 at least).

View file

@ -1,5 +1,7 @@
# Building with Docker
> **On Windows building with this method is not advised and should be used only if Windows Linux Subsystem can not be used. In all other cases all Windows users should be using Linux Subsystem (WSL) instead**
Building with [Docker](https://www.docker.com/) is remarkably easy: an isolated container will hold all the needed compilation tools so that they won't interfere with your system and you won't need to install and manage them by yourself. You'll only need to have Docker itself [installed](https://docs.docker.com/install/).
The first time that you'll run a build it will take a little more time than following executions since it will be building its base image first. Once this initial process is completed, the firmware will be always built immediately.

View file

@ -0,0 +1,19 @@
# Building in Gitpod
Gitpod offers an online build environment for building INAV targets.
## Setting up the environment and building targets
1. Go to https://gitpod.io/new
1. Paste `https://github.com/iNavFlight/inav/tree/[version]` into the field called "Select a repository".
1. Ensure that you substitute [version] (e.g. 7.1.0) with the version number of INAV that you want to build.
1. Cick on the link that shows in the drop down and Gitpod will atomatically selects the adequate Editor and Browser.
1. Leave the other fields as default and click "Continue". Your build environment will be created.
1. At the bottom of the page, you will see a command line. Type `make [TARGET]` and wait for the target to be built.
1. Once the build has finished, navigate to the build folder using `cd build`.
1. Once in the folder, run `objcopy -O ihex -R .eeprom [TARGET].elf [TARGET].hex` to convert the `.elf` file to a `.hex` file.
1. Your new target `.hex` binary will be located in a folder called `bin`, which can be found at the top left of the page.
NOTE: You can use this method to build your forks as well. Just paste in the link to your fork and follow the rest of the steps.
You are done!

View file

@ -1,5 +1,7 @@
# Building with Vagrant
> **On Windows building with this method is not advised and should be used only if Windows Linux Subsystem can not be used. In all other cases all Windows users should be using Linux Subsystem (WSL) instead**
Setting up build environment with Vagrant is remarkably simple, but you still need to have some basic knowlage of your OS.
## Installing Vagrant

View file

@ -1,6 +1,6 @@
# Building in Windows 10 with Linux subsystem [Recommended]
# Building in Windows 10/11 with Linux subsystem (WSL) [Recommended]
Linux subsystem for Windows 10 is probably the simplest way of building INAV under Windows 10.
Linux subsystem for Windows (WSL) 10/11 is probably the simplest way of building INAV under Windows.
## Setting up the environment
@ -9,7 +9,6 @@ run `windows features`
enable `windows subsytem for linux`
reboot
Install Ubuntu:
1. Go to Microsoft store https://www.microsoft.com/en-gb/store/b/home
1. Search and install most recent Ubuntu LTS version
@ -56,12 +55,12 @@ You can fix this with by remounting the drive using the following commands
1. `sudo umount /mnt/c`
2. `sudo mount -t drvfs C: /mnt/c -o metadata`
## Building (example):
## Building with Make (example):
For detailed build instrusctions see [Building in Linux](Building%20in%20Linux.md)
For detailed build instructions see [Building in Linux](Building%20in%20Linux.md)
Launch Ubuntu:
Click Windows Start button then scroll and lauch "Ubuntu"
Click Windows Start button then scroll and launch "Ubuntu"
Building from Ubuntu command line
@ -80,6 +79,39 @@ cd build
make MATEKF722
```
## Building with Ninja (example):
[Ninja](https://ninja-build.org/) is a popular cross-platform tool. It is both lightweight and executes parallel builds by default. It is advantageous to use this over the old _make_ method. There are detailed instructions for building with Ninja in [Building in Linux](Building%20in%20Linux.md#building-with-ninja).
Launch Ubuntu:
Click Windows Start button. Then scroll and launch **Ubuntu**.
> [!TIP]
> Before using Ninja, you will need to install it. From the Ubuntu command prompt type `sudo apt-get install ninja-build -y` and press enter.
Building from the command line:
First, change to the INAV directory with
```cd /mnt/c/inav```
Before building, you will need to prepare the build environment. You only need to do this once, unless you reinstall WSL or cmake.
```
mkdir build
cd build
cmake -GNinja ..
```
From then on, you can build your target by calling the following from inside the build directory.
```
ninja MATEKF722
```
If you want to build multiple targets. You can use:
```
ninja MATEKF722 MATEKF405SE SPEEDYBEEF405
```
## Updating the documents
```
cd /mnt/c/inav

View file

@ -1,4 +1,7 @@
# Building in Windows with MSYS2
> **Building with this method is not advised and should be used only if Windows Linux Subsystem can not be used. In all other cases all Windows users should be using Linux Subsystem (WSL) instead**
- This environment does not require installing WSL, which may not be available or would get in the way of other virtualization and/or anti-cheat software
- It is also much faster to install and get set up because of its small size(~3.65 GB total after building hex file as of 6.0.0)
## Setting up the environment

View file

@ -1,4 +1,8 @@
# Building in windows light [Deprecated]
> **Building with this method is deprecated and not advised. All Windows users should be using
Linux Subsystem (WSL) instead**
no cygwin and no path changes
## Install Git for windows

View file

@ -98,10 +98,13 @@ LOG_BUF_DEBUG(TEMPERATURE, &tstruct, sizeof(tstruct));
Log messages are transmitted through the `FUNCTION_LOG` serial port as MSP messages (`MSP_DEBUGMSG`). It is possible to use any serial terminal to display these messages, however it is advisable to use an application that understands `MSP_DEBUGMSG` in order to maintain readability (in a raw serial terminal the MSP message envelope may result in the display of strange characters). `MSP_DEBUGMSG` aware applications include:
* [msp-tool](https://github.com/fiam/msp-tool)
* [mwp](https://github.com/stronnag/mwptools)
* [dbg-tool](https://github.com/stronnag/mwptools)
* [dbg-tool](https://codeberg.org/stronnag/dbg-tool)
* [INAV Configurator](https://github.com/iNavFlight/inav-configurator)
* [mwp](https://github.com/stronnag/mwptools)
In addtion:
* [msp-tool](https://github.com/fiam/msp-tool) is obsolete and has limited OS support.
For example, with the final lines of `src/main/fc/fc_init.c` set to:
@ -121,10 +124,16 @@ set log_topics = 4294967295
The output will be formatted as follows:
```
# msp-tool
[DEBUG] [ 3.967] Init is complete
# dbg-tool
[dbg-tool] 12:46:49.909079 DBG: [ 3.967] Init is complete
# mwp (stderr log file)
2020-02-02T19:09:02+0000 DEBUG:[ 3.968] Init is complete
# msp-tool
[DEBUG] [ 3.967] Init is complete
```
The numeric value in square brackets is the FC uptime in seconds.
For the Configurator, debug messages are shown in the developer console log.
Note: The numeric value in square brackets is the FC uptime in seconds.

View file

@ -13,7 +13,16 @@ The format is defined the XSD schema here.
* The `mwp` tag was introduced by the eponymous mission planner. Other mission planners may consider that reusing some of the tags (`cx`, `cy` - centre location, `zoom` TMS zoom level, `home-x`, `home-y` - home location) is useful.
* `meta` may be used as a synonym for `mwp`.
* The `version` tag may be intepreted by mission planners as they see fit. For example, the (obsolete) Android 'ez-gui' application requires '2.3-pre8'. For multi-mission files it is recommended to use another `version`.
* the `mwp` / `meta` element may be interleaved with `missionitem` in a multi-mission file to provide mission segment specific home, centre locations and zoom.
* The `mwp` / `meta` element may be interleaved with `missionitem` in a multi-mission file to provide mission segment specific home, centre locations and zoom.
* The `fwapproach` element defines INAV 7.1.0 and later Autoland parameters for the mission.
## Validation
You can check that your files validate using the open source `xmlint` tool.
```
xmllint --schema docs/development/wp_mission_schema/mw-mission.xsd test.mission --noout
```
## Examples

View file

@ -12,6 +12,7 @@
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element ref="missionitem"/>
<xs:element ref="mwp"/>
<xs:element ref="fwapproach"/>
</xs:choice>
</xs:sequence>
</xs:complexType>
@ -21,6 +22,25 @@
<xs:attribute name="value" use="required"/>
</xs:complexType>
</xs:element>
<xs:element name="fwapproach">
<xs:complexType>
<xs:attribute name="no" use="required" type="xs:integer"/>
<xs:attribute name="index" use="required" type="xs:integer"/>
<xs:attribute name="approachalt" use="required" type="xs:integer"/>
<xs:attribute name="landalt" use="required" type="xs:integer"/>
<xs:attribute name="landheading1" use="required" type="xs:integer"/>
<xs:attribute name="landheading2" use="required" type="xs:integer"/>
<xs:attribute name="approachdirection" use="required">
<xs:simpleType>
<xs:restriction base="xs:token">
<xs:enumeration value="left"/>
<xs:enumeration value="right"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="sealevelref" use="required" type="xs:boolean"/>
</xs:complexType>
</xs:element>
<xs:element name="missionitem">
<xs:complexType>
<xs:attribute name="action" use="required">

View file

@ -23,8 +23,8 @@ New targets are accepted into INAV code if any of the following conditions is sa
3. The new target must meet the following minimal requirements:
* On-board sensors include at least the IMU (gyroscope + accelerometer)
* At least 2 hardware serial ports are available with both TX and RX pins
* At least 512K of firmware flash memory and at least of 64K of RAM available
* At least 3 hardware serial ports are available with both TX and RX pads. 2 serial ports may be accepted if there is an onboard serial RX.
* At least 512K of firmware flash memory and at least of 128K of RAM available
* At least one I2C bus broken out (SCL and SDA pins) and not shared with other functions
## New hardware support

View file

@ -48,7 +48,7 @@ typedef enum FIRMWARE_VERSION_TYPE
} FIRMWARE_VERSION_TYPE;
#endif
/** @brief Flags to report failure cases over the high latency telemtry. */
/** @brief Flags to report failure cases over the high latency telemetry. */
#ifndef HAVE_ENUM_HL_FAILURE_FLAG
#define HAVE_ENUM_HL_FAILURE_FLAG
typedef enum HL_FAILURE_FLAG

View file

@ -6,6 +6,10 @@
> INAV 7 is the last INAV official release available for F411 based flight controllers. The next milestone, INAV 8 will not be available for F411 boards.
# ICM426xx IMUs PSA
> The filtering settings for the ICM426xx has changed to match what is used by Ardupilot and Betaflight in INAV 7.1. When upgrading from older versions you may need to recalibrate the Accelerometer and if you are not using INAV's default tune you may also want to check if the tune is still good.
![INAV](http://static.rcgroups.net/forums/attachments/6/1/0/3/7/6/a9088858-102-inav.png)
# PosHold, Navigation and RTH without compass PSA
@ -37,8 +41,9 @@ Fly safe, fly smart with INAV 7.1 and a compass by your side!
## Features
* Runs on the most popular F4, F7 and H7 flight controllers
* MSP Displayport for all the HD Digital FPV systems: DJI, Walksnail and HDZero
* Runs on the most popular F4, AT32, F7 and H7 flight controllers
* On Screen Display (OSD) - both character and pixel style
* DJI OSD integration: all elements, system messages and warnings
* Outstanding performance out of the box
* Position Hold, Altitude Hold, Return To Home and Waypoint Missions
* Excellent support for fixed wing UAVs: airplanes, flying wings
@ -50,7 +55,6 @@ Fly safe, fly smart with INAV 7.1 and a compass by your side!
* SmartAudio and IRC Tramp VTX support
* Telemetry: SmartPort, FPort, MAVlink, LTM, CRSF
* Multi-color RGB LED Strip support
* On Screen Display (OSD) - both character and pixel style
* And many more!
For a list of features, changes and some discussion please review consult the releases [page](https://github.com/iNavFlight/inav/releases) and the documentation.

View file

@ -1,3 +1,4 @@
main_sources(COMMON_SRC
main.c
@ -237,6 +238,8 @@ main_sources(COMMON_SRC
drivers/rangefinder/rangefinder_us42.h
drivers/rangefinder/rangefinder_tof10120_i2c.c
drivers/rangefinder/rangefinder_tof10120_i2c.h
drivers/rangefinder/rangefinder_teraranger_evo.c
drivers/rangefinder/rangefinder_teraranger_evo.h
drivers/resource.c
drivers/resource.h
@ -344,6 +347,7 @@ main_sources(COMMON_SRC
flight/ez_tune.c
flight/ez_tune.h
io/adsb.c
io/beeper.c
io/beeper.h
io/servo_sbus.c
@ -482,6 +486,8 @@ main_sources(COMMON_SRC
io/rangefinder.h
io/rangefinder_msp.c
io/rangefinder_benewake.c
io/rangefinder_usd1_v0.c
io/rangefinder_nanoradar.c
io/rangefinder_fake.c
io/opflow.h
io/opflow_cxof.c
@ -494,8 +500,8 @@ main_sources(COMMON_SRC
io/displayport_max7456.h
io/displayport_msp.c
io/displayport_msp.h
io/displayport_msp_bf_compat.c
io/displayport_msp_bf_compat.h
io/displayport_msp_dji_compat.c
io/displayport_msp_dji_compat.h
io/displayport_oled.c
io/displayport_oled.h
io/displayport_msp_osd.c
@ -560,6 +566,8 @@ main_sources(COMMON_SRC
navigation/navigation_rover_boat.c
navigation/sqrt_controller.c
navigation/sqrt_controller.h
navigation/rth_trackback.c
navigation/rth_trackback.h
sensors/barometer.c
sensors/barometer.h

View file

@ -402,12 +402,21 @@ static const blackboxSimpleFieldDefinition_t blackboxGpsHFields[] = {
// Rarely-updated fields
static const blackboxSimpleFieldDefinition_t blackboxSlowFields[] = {
/* "flightModeFlags" renamed internally to more correct ref of rcModeFlags, since it logs rc boxmode selections,
* but name kept for external compatibility reasons.
* "activeFlightModeFlags" logs actual active flight modes rather than rc boxmodes.
* 'active' should at least distinguish it from the existing "flightModeFlags" */
{"activeWpNumber", -1, UNSIGNED, PREDICT(0), ENCODING(UNSIGNED_VB)},
{"flightModeFlags", -1, UNSIGNED, PREDICT(0), ENCODING(UNSIGNED_VB)},
{"flightModeFlags2", -1, UNSIGNED, PREDICT(0), ENCODING(UNSIGNED_VB)},
{"activeFlightModeFlags", -1, UNSIGNED, PREDICT(0), ENCODING(UNSIGNED_VB)},
{"stateFlags", -1, UNSIGNED, PREDICT(0), ENCODING(UNSIGNED_VB)},
{"failsafePhase", -1, UNSIGNED, PREDICT(0), ENCODING(TAG2_3S32)},
{"rxSignalReceived", -1, UNSIGNED, PREDICT(0), ENCODING(TAG2_3S32)},
{"rxFlightChannelsValid", -1, UNSIGNED, PREDICT(0), ENCODING(TAG2_3S32)},
{"rxUpdateRate", -1, UNSIGNED, PREDICT(PREVIOUS), ENCODING(UNSIGNED_VB)},
{"hwHealthStatus", -1, UNSIGNED, PREDICT(0), ENCODING(UNSIGNED_VB)},
{"powerSupplyImpedance", -1, UNSIGNED, PREDICT(0), ENCODING(UNSIGNED_VB)},
@ -436,8 +445,6 @@ static const blackboxSimpleFieldDefinition_t blackboxSlowFields[] = {
{"escRPM", -1, UNSIGNED, PREDICT(0), ENCODING(UNSIGNED_VB)},
{"escTemperature", -1, SIGNED, PREDICT(PREVIOUS), ENCODING(SIGNED_VB)},
#endif
{"rxUpdateRate", -1, UNSIGNED, PREDICT(PREVIOUS), ENCODING(UNSIGNED_VB)},
{"activeWpNumber", -1, UNSIGNED, PREDICT(0), ENCODING(UNSIGNED_VB)},
};
typedef enum BlackboxState {
@ -533,7 +540,9 @@ typedef struct blackboxGpsState_s {
// This data is updated really infrequently:
typedef struct blackboxSlowState_s {
uint32_t flightModeFlags; // extend this data size (from uint16_t)
uint32_t rcModeFlags;
uint32_t rcModeFlags2;
uint32_t activeFlightModeFlags;
uint32_t stateFlags;
uint8_t failsafePhase;
bool rxSignalReceived;
@ -566,7 +575,7 @@ extern boxBitmask_t rcModeActivationMask;
static BlackboxState blackboxState = BLACKBOX_STATE_DISABLED;
static uint32_t blackboxLastArmingBeep = 0;
static uint32_t blackboxLastFlightModeFlags = 0;
static uint32_t blackboxLastRcModeFlags = 0;
static struct {
uint32_t headerIndex;
@ -1260,7 +1269,10 @@ static void writeSlowFrame(void)
blackboxWrite('S');
blackboxWriteUnsignedVB(slowHistory.flightModeFlags);
blackboxWriteUnsignedVB(slowHistory.activeWpNumber);
blackboxWriteUnsignedVB(slowHistory.rcModeFlags);
blackboxWriteUnsignedVB(slowHistory.rcModeFlags2);
blackboxWriteUnsignedVB(slowHistory.activeFlightModeFlags);
blackboxWriteUnsignedVB(slowHistory.stateFlags);
/*
@ -1271,6 +1283,8 @@ static void writeSlowFrame(void)
values[2] = slowHistory.rxFlightChannelsValid ? 1 : 0;
blackboxWriteTag2_3S32(values);
blackboxWriteUnsignedVB(slowHistory.rxUpdateRate);
blackboxWriteUnsignedVB(slowHistory.hwHealthStatus);
blackboxWriteUnsignedVB(slowHistory.powerSupplyImpedance);
@ -1296,8 +1310,6 @@ static void writeSlowFrame(void)
blackboxWriteUnsignedVB(slowHistory.escRPM);
blackboxWriteSignedVB(slowHistory.escTemperature);
#endif
blackboxWriteUnsignedVB(slowHistory.rxUpdateRate);
blackboxWriteUnsignedVB(slowHistory.activeWpNumber);
blackboxSlowFrameIterationTimer = 0;
}
@ -1307,27 +1319,21 @@ static void writeSlowFrame(void)
*/
static void loadSlowState(blackboxSlowState_t *slow)
{
memcpy(&slow->flightModeFlags, &rcModeActivationMask, sizeof(slow->flightModeFlags)); //was flightModeFlags;
slow->activeWpNumber = getActiveWpNumber();
slow->rcModeFlags = rcModeActivationMask.bits[0]; // first 32 bits of boxId_e
slow->rcModeFlags2 = rcModeActivationMask.bits[1]; // remaining bits of boxId_e
// Also log Nav auto enabled flight modes rather than just those selected by boxmode
if (FLIGHT_MODE(ANGLE_MODE)) {
slow->flightModeFlags |= (1 << BOXANGLE);
}
if (FLIGHT_MODE(NAV_ALTHOLD_MODE)) {
slow->flightModeFlags |= (1 << BOXNAVALTHOLD);
}
if (FLIGHT_MODE(NAV_RTH_MODE)) {
slow->flightModeFlags |= (1 << BOXNAVRTH);
}
if (navigationGetHeadingControlState() == NAV_HEADING_CONTROL_AUTO) {
slow->flightModeFlags |= (1 << BOXHEADINGHOLD);
}
if (navigationRequiresTurnAssistance()) {
slow->flightModeFlags |= (1 << BOXTURNASSIST);
slow->rcModeFlags |= (1 << BOXHEADINGHOLD);
}
slow->activeFlightModeFlags = flightModeFlags;
slow->stateFlags = stateFlags;
slow->failsafePhase = failsafePhase();
slow->rxSignalReceived = rxIsReceivingSignal();
slow->rxFlightChannelsValid = rxAreFlightChannelsValid();
slow->rxUpdateRate = getRcUpdateFrequency();
slow->hwHealthStatus = (getHwGyroStatus() << 2 * 0) | // Pack hardware health status into a bit field.
(getHwAccelerometerStatus() << 2 * 1) | // Use raw hardwareSensorStatus_e values and pack them using 2 bits per value
(getHwCompassStatus() << 2 * 2) | // Report GYRO in 2 lowest bits, then ACC, COMPASS, BARO, GPS, RANGEFINDER and PITOT
@ -1379,9 +1385,6 @@ static void loadSlowState(blackboxSlowState_t *slow)
slow->escRPM = escSensor->rpm;
slow->escTemperature = escSensor->temperature;
#endif
slow->rxUpdateRate = getRcUpdateFrequency();
slow->activeWpNumber = getActiveWpNumber();
}
/**
@ -1498,7 +1501,7 @@ void blackboxStart(void)
* it finally plays the beep for this arming event.
*/
blackboxLastArmingBeep = getArmingBeepTimeMicros();
memcpy(&blackboxLastFlightModeFlags, &rcModeActivationMask, sizeof(blackboxLastFlightModeFlags)); // record startup status
memcpy(&blackboxLastRcModeFlags, &rcModeActivationMask, sizeof(blackboxLastRcModeFlags)); // record startup status
blackboxSetState(BLACKBOX_STATE_PREPARE_LOG_FILE);
}
@ -1850,9 +1853,9 @@ static bool blackboxWriteSysinfo(void)
BLACKBOX_PRINT_HEADER_LINE("Craft name", "%s", systemConfig()->craftName);
BLACKBOX_PRINT_HEADER_LINE("P interval", "%u/%u", blackboxConfig()->rate_num, blackboxConfig()->rate_denom);
BLACKBOX_PRINT_HEADER_LINE("minthrottle", "%d", getThrottleIdleValue());
BLACKBOX_PRINT_HEADER_LINE("maxthrottle", "%d", motorConfig()->maxthrottle);
BLACKBOX_PRINT_HEADER_LINE("maxthrottle", "%d", getMaxThrottle());
BLACKBOX_PRINT_HEADER_LINE("gyro_scale", "0x%x", castFloatBytesToInt(1.0f));
BLACKBOX_PRINT_HEADER_LINE("motorOutput", "%d,%d", getThrottleIdleValue(),motorConfig()->maxthrottle);
BLACKBOX_PRINT_HEADER_LINE("motorOutput", "%d,%d", getThrottleIdleValue(),getMaxThrottle());
BLACKBOX_PRINT_HEADER_LINE("acc_1G", "%u", acc.dev.acc_1G);
#ifdef USE_ADC
@ -1921,9 +1924,8 @@ static bool blackboxWriteSysinfo(void)
BLACKBOX_PRINT_HEADER_LINE("dterm_lpf_type", "%d", pidProfile()->dterm_lpf_type);
BLACKBOX_PRINT_HEADER_LINE("deadband", "%d", rcControlsConfig()->deadband);
BLACKBOX_PRINT_HEADER_LINE("yaw_deadband", "%d", rcControlsConfig()->yaw_deadband);
BLACKBOX_PRINT_HEADER_LINE("gyro_lpf", "%d", gyroConfig()->gyro_lpf);
BLACKBOX_PRINT_HEADER_LINE("gyro_lpf", "%d", GYRO_LPF_256HZ);
BLACKBOX_PRINT_HEADER_LINE("gyro_lpf_hz", "%d", gyroConfig()->gyro_main_lpf_hz);
BLACKBOX_PRINT_HEADER_LINE("gyro_lpf_type", "%d", gyroConfig()->gyro_main_lpf_type);
#ifdef USE_DYNAMIC_FILTERS
BLACKBOX_PRINT_HEADER_LINE("dynamicGyroNotchQ", "%d", gyroConfig()->dynamicGyroNotchQ);
BLACKBOX_PRINT_HEADER_LINE("dynamicGyroNotchMinHz", "%d", gyroConfig()->dynamicGyroNotchMinHz);
@ -1946,8 +1948,6 @@ static bool blackboxWriteSysinfo(void)
BLACKBOX_PRINT_HEADER_LINE("waypoints", "%d,%d", getWaypointCount(),isWaypointListValid());
BLACKBOX_PRINT_HEADER_LINE("acc_notch_hz", "%d", accelerometerConfig()->acc_notch_hz);
BLACKBOX_PRINT_HEADER_LINE("acc_notch_cutoff", "%d", accelerometerConfig()->acc_notch_cutoff);
BLACKBOX_PRINT_HEADER_LINE("pidSumLimit", "%d", pidProfile()->pidSumLimit);
BLACKBOX_PRINT_HEADER_LINE("pidSumLimitYaw", "%d", pidProfile()->pidSumLimitYaw);
BLACKBOX_PRINT_HEADER_LINE("axisAccelerationLimitYaw", "%d", pidProfile()->axisAccelerationLimitYaw);
BLACKBOX_PRINT_HEADER_LINE("axisAccelerationLimitRollPitch", "%d", pidProfile()->axisAccelerationLimitRollPitch);
#ifdef USE_RPM_FILTER
@ -2026,10 +2026,10 @@ static void blackboxCheckAndLogArmingBeep(void)
static void blackboxCheckAndLogFlightMode(void)
{
// Use != so that we can still detect a change if the counter wraps
if (memcmp(&rcModeActivationMask, &blackboxLastFlightModeFlags, sizeof(blackboxLastFlightModeFlags))) {
if (memcmp(&rcModeActivationMask, &blackboxLastRcModeFlags, sizeof(blackboxLastRcModeFlags))) {
flightLogEvent_flightMode_t eventData; // Add new data for current flight mode flags
eventData.lastFlags = blackboxLastFlightModeFlags;
memcpy(&blackboxLastFlightModeFlags, &rcModeActivationMask, sizeof(blackboxLastFlightModeFlags));
eventData.lastFlags = blackboxLastRcModeFlags;
memcpy(&blackboxLastRcModeFlags, &rcModeActivationMask, sizeof(blackboxLastRcModeFlags));
memcpy(&eventData.flags, &rcModeActivationMask, sizeof(eventData.flags));
blackboxLogEvent(FLIGHT_LOG_EVENT_FLIGHTMODE, (flightLogEventData_t *)&eventData);
}

View file

@ -35,6 +35,10 @@
#include "config/parameter_group.h"
#include "config/parameter_group_ids.h"
#ifdef USE_SDCARD
#include "drivers/sdcard/sdcard.h"
#endif
#include "io/asyncfatfs/asyncfatfs.h"
#include "io/flashfs.h"
#include "io/serial.h"
@ -507,6 +511,36 @@ bool isBlackboxDeviceFull(void)
}
}
bool isBlackboxDeviceWorking(void)
{
switch (blackboxConfig()->device) {
case BLACKBOX_DEVICE_SERIAL:
return blackboxPort != NULL;
#ifdef USE_SDCARD
case BLACKBOX_DEVICE_SDCARD:
return sdcard_isInserted() && sdcard_isFunctional() && (afatfs_getFilesystemState() == AFATFS_FILESYSTEM_STATE_READY);
#endif
#ifdef USE_FLASHFS
case BLACKBOX_DEVICE_FLASH:
return flashfsIsReady();
#endif
default:
return false;
}
}
int32_t blackboxGetLogNumber(void)
{
switch (blackboxConfig()->device) {
#ifdef USE_SDCARD
case BLACKBOX_DEVICE_SDCARD:
return blackboxSDCard.largestLogFileNumber;
#endif
default:
return -1;
}
}
/**
* Call once every loop iteration in order to maintain the global blackboxHeaderBudget with the number of bytes we can
* transmit this iteration.

View file

@ -67,6 +67,8 @@ bool blackboxDeviceBeginLog(void);
bool blackboxDeviceEndLog(bool retainLog);
bool isBlackboxDeviceFull(void);
bool isBlackboxDeviceWorking(void);
int32_t blackboxGetLogNumber(void);
void blackboxReplenishHeaderBudget(void);
blackboxBufferReserveStatus_e blackboxDeviceReserveBufferSpace(int32_t bytes);

View file

@ -40,7 +40,7 @@
#endif
#ifdef __APPLE__
#define FASTRAM __attribute__ ((section("__DATA,__.fastram_bss"), aligned(4)))
#define FASTRAM __attribute__ ((section("__DATA,__.fastram_bss"), aligned(8)))
#else
#define FASTRAM __attribute__ ((section(".fastram_bss"), aligned(4)))
#endif

View file

@ -137,6 +137,30 @@ static long cmsx_PidWriteback(const OSD_Entry *self)
return 0;
}
static const OSD_Entry cmsx_menuEzTuneEntries[] =
{
OSD_LABEL_DATA_ENTRY("-- EZTUNE --", profileIndexString),
OSD_SETTING_ENTRY("ENABLED", SETTING_EZ_ENABLED),
OSD_SETTING_ENTRY("FILTER HZ", SETTING_EZ_FILTER_HZ),
OSD_SETTING_ENTRY("RATIO", SETTING_EZ_AXIS_RATIO),
OSD_SETTING_ENTRY("RESP.", SETTING_EZ_RESPONSE),
OSD_SETTING_ENTRY("DAMP.", SETTING_EZ_DAMPING),
OSD_SETTING_ENTRY("STAB.", SETTING_EZ_STABILITY),
OSD_SETTING_ENTRY("AGGR.", SETTING_EZ_AGGRESSIVENESS),
OSD_SETTING_ENTRY("RATE", SETTING_EZ_RATE),
OSD_SETTING_ENTRY("EXPO", SETTING_EZ_EXPO),
OSD_BACK_AND_END_ENTRY,
};
static const CMS_Menu cmsx_menuEzTune = {
.onEnter = NULL,
.onExit = NULL,
.onGlobalExit = NULL,
.entries = cmsx_menuEzTuneEntries
};
static const OSD_Entry cmsx_menuPidEntries[] =
{
OSD_LABEL_DATA_ENTRY("-- PID --", profileIndexString),
@ -198,6 +222,8 @@ static const OSD_Entry cmsx_menuPidAltMagEntries[] =
{
OSD_LABEL_DATA_ENTRY("-- ALT&MAG --", profileIndexString),
OSD_SETTING_ENTRY("FW ALT RESPONSE", SETTING_NAV_FW_ALT_CONTROL_RESPONSE),
OTHER_PIDFF_ENTRY("ALT P", &cmsx_pidPosZ.P),
OTHER_PIDFF_ENTRY("ALT I", &cmsx_pidPosZ.I),
OTHER_PIDFF_ENTRY("ALT D", &cmsx_pidPosZ.D),
@ -398,7 +424,6 @@ static const CMS_Menu cmsx_menuProfileOther = {
static const OSD_Entry cmsx_menuFilterPerProfileEntries[] =
{
OSD_LABEL_DATA_ENTRY("-- FILTERING --", profileIndexString),
OSD_SETTING_ENTRY("HARDWARE LPF", SETTING_GYRO_HARDWARE_LPF),
OSD_SETTING_ENTRY("GYRO MAIN", SETTING_GYRO_MAIN_LPF_HZ),
OSD_SETTING_ENTRY("DTERM LPF", SETTING_DTERM_LPF_HZ),
#ifdef USE_DYNAMIC_FILTERS
@ -458,6 +483,7 @@ static const OSD_Entry cmsx_menuImuEntries[] =
// Profile dependent
OSD_UINT8_CALLBACK_ENTRY("PID PROF", cmsx_profileIndexOnChange, (&(const OSD_UINT8_t){ &tmpProfileIndex, 1, MAX_PROFILE_COUNT, 1})),
OSD_SUBMENU_ENTRY("EZTUNE", &cmsx_menuEzTune),
OSD_SUBMENU_ENTRY("PID", &cmsx_menuPid),
OSD_SUBMENU_ENTRY("PID ALTMAG", &cmsx_menuPidAltMag),
OSD_SUBMENU_ENTRY("PID GPSNAV", &cmsx_menuPidGpsnav),

View file

@ -45,8 +45,9 @@ static const OSD_Entry cmsx_menuNavSettingsEntries[] =
OSD_SETTING_ENTRY("MC NAV SPEED", SETTING_NAV_AUTO_SPEED),
OSD_SETTING_ENTRY("MC MAX NAV SPEED", SETTING_NAV_MAX_AUTO_SPEED),
OSD_SETTING_ENTRY("MAX CRUISE SPEED", SETTING_NAV_MANUAL_SPEED),
OSD_SETTING_ENTRY("MAX NAV CLIMB RATE", SETTING_NAV_AUTO_CLIMB_RATE),
OSD_SETTING_ENTRY("MAX AH CLIMB RATE", SETTING_NAV_MANUAL_CLIMB_RATE),
OSD_SETTING_ENTRY("MAX NAV CLIMB RATE", SETTING_NAV_MC_AUTO_CLIMB_RATE),
OSD_SETTING_ENTRY("MAX MC AH CLIMB RATE", SETTING_NAV_MC_MANUAL_CLIMB_RATE),
OSD_SETTING_ENTRY("MAX FW AH CLIMB RATE", SETTING_NAV_FW_MANUAL_CLIMB_RATE),
OSD_SETTING_ENTRY("MC MAX BANK ANGLE", SETTING_NAV_MC_BANK_ANGLE),
OSD_SETTING_ENTRY("MC ALTHOLD THROT", SETTING_NAV_MC_ALTHOLD_THROTTLE),
OSD_SETTING_ENTRY("MC HOVER THR", SETTING_NAV_MC_HOVER_THR),

View file

@ -26,6 +26,12 @@
//type of elements
#ifndef __APPLE__
#define OSD_ENTRY_ATTR __attribute__((packed))
#else
#define OSD_ENTRY_ATTR
#endif
typedef enum
{
OME_Label,
@ -71,7 +77,7 @@ typedef struct
const void * const data;
const uint8_t type; // from OSD_MenuElement
uint8_t flags;
} __attribute__((packed)) OSD_Entry;
} OSD_ENTRY_ATTR OSD_Entry;
// Bits in flags
#define PRINT_VALUE (1 << 0) // Value has been changed, need to redraw

View file

@ -516,9 +516,25 @@ bool sensorCalibrationSolveForScale(sensorCalibrationState_t * state, float resu
return sensorCalibrationValidateResult(result);
}
float gaussian(const float x, const float mu, const float sigma) {
return exp(-pow((double)(x - mu), 2) / (2 * pow((double)sigma, 2)));
}
float bellCurve(const float x, const float curveWidth)
{
return powf(M_Ef, -sq(x) / (2.0f * sq(curveWidth)));
return gaussian(x, 0.0f, curveWidth);
}
/**
* @brief Calculate the attenuation of a value using a Gaussian function.
* Retuns 1 for input 0 and ~0 for input width.
* @param input The input value.
* @param width The width of the Gaussian function.
* @return The attenuation of the input value.
*/
float attenuation(const float input, const float width) {
const float sigma = width / 2.35482f; // Approximately width / sqrt(2 * ln(2))
return gaussian(input, 0.0f, sigma);
}
float fast_fsqrtf(const float value) {

View file

@ -36,7 +36,7 @@
#define RAD (M_PIf / 180.0f)
#define DEGREES_TO_CENTIDEGREES(angle) ((angle) * 100)
#define CENTIDEGREES_TO_DEGREES(angle) ((angle) / 100.0f)
#define CENTIDEGREES_TO_DEGREES(angle) ((angle) * 0.01f)
#define CENTIDEGREES_TO_DECIDEGREES(angle) ((angle) / 10.0f)
#define DECIDEGREES_TO_CENTIDEGREES(angle) ((angle) * 10)
@ -54,17 +54,21 @@
#define RADIANS_TO_DECIDEGREES(angle) (((angle) * 10.0f) / RAD)
#define RADIANS_TO_CENTIDEGREES(angle) (((angle) * 100.0f) / RAD)
#define CENTIDEGREES_TO_RADIANS(angle) (((angle) / 100.0f) * RAD)
#define CENTIDEGREES_TO_RADIANS(angle) (((angle) * 0.01f) * RAD)
#define MILLIMETERS_TO_CENTIMETERS(mm) (mm / 10.0f)
#define CENTIMETERS_TO_CENTIFEET(cm) (cm / 0.3048f)
#define CENTIMETERS_TO_FEET(cm) (cm / 30.48f)
#define CENTIMETERS_TO_METERS(cm) (cm / 100.0f)
#define CENTIMETERS_TO_METERS(cm) (cm * 0.01f)
#define METERS_TO_CENTIMETERS(m) (m * 100)
#define METERS_TO_KILOMETERS(m) (m / 1000.0f)
#define METERS_TO_MILES(m) (m / 1609.344f)
#define METERS_TO_NAUTICALMILES(m) (m / 1852.00f)
#define MWH_TO_WH(mWh) (mWh / 1000.0f)
#define CMSEC_TO_CENTIMPH(cms) (cms * 2.2369363f)
#define CMSEC_TO_CENTIKPH(cms) (cms * 3.6f)
#define CMSEC_TO_CENTIKNOTS(cms) (cms * 1.943845f)
@ -191,6 +195,8 @@ float acos_approx(float x);
void arraySubInt32(int32_t *dest, int32_t *array1, int32_t *array2, int count);
float bellCurve(const float x, const float curveWidth);
float attenuation(const float input, const float width);
float gaussian(const float x, const float mu, const float sigma);
float fast_fsqrtf(const float value);
float calc_length_pythagorean_2D(const float firstElement, const float secondElement);
float calc_length_pythagorean_3D(const float firstElement, const float secondElement, const float thirdElement);

View file

@ -64,7 +64,7 @@ static inline uint16_t pgIsProfile(const pgRegistry_t* reg) {return (reg->size &
#ifdef __APPLE__
extern const pgRegistry_t __pg_registry_start[] __asm("section$start$__DATA$__pg_registry");
extern const pgRegistry_t __pg_registry_end[] __asm("section$end$__DATA$__pg_registry");
#define PG_REGISTER_ATTRIBUTES __attribute__ ((section("__DATA,__pg_registry"), used, aligned(4)))
#define PG_REGISTER_ATTRIBUTES __attribute__ ((section("__DATA,__pg_registry"), used, aligned(8)))
extern const uint8_t __pg_resetdata_start[] __asm("section$start$__DATA$__pg_resetdata");
extern const uint8_t __pg_resetdata_end[] __asm("section$end$__DATA$__pg_resetdata");

View file

@ -108,15 +108,6 @@ static const gyroFilterAndRateConfig_t gyroConfigs[] = {
{ GYRO_LPF_256HZ, 3200, { BMI160_BWP_OSR4 | BMI160_ODR_3200_Hz} },
{ GYRO_LPF_256HZ, 1600, { BMI160_BWP_OSR2 | BMI160_ODR_1600_Hz} },
{ GYRO_LPF_256HZ, 800, { BMI160_BWP_NORMAL | BMI160_ODR_800_Hz } },
{ GYRO_LPF_188HZ, 800, { BMI160_BWP_OSR2 | BMI160_ODR_800_Hz } }, // ODR = 800 Hz, LPF = 128 Hz
{ GYRO_LPF_188HZ, 400, { BMI160_BWP_NORMAL | BMI160_ODR_400_Hz } }, // ODR = 400 Hz, LPF = 137 Hz
{ GYRO_LPF_98HZ, 800, { BMI160_BWP_OSR4 | BMI160_ODR_800_Hz } }, // ODR = 800 Hz, LPF = 63 Hz
{ GYRO_LPF_98HZ, 400, { BMI160_BWP_OSR2 | BMI160_ODR_400_Hz } }, // ODR = 400 Hz, LPF = 68 Hz
{ GYRO_LPF_42HZ, 800, { BMI160_BWP_OSR4 | BMI160_ODR_800_Hz } }, // ODR = 800 Hz, LPF = 63 Hz
{ GYRO_LPF_42HZ, 400, { BMI160_BWP_OSR4 | BMI160_ODR_400_Hz } }, // ODR = 400 Hz, LPF = 34 Hz
};
static void bmi160AccAndGyroInit(gyroDev_t *gyro)

View file

@ -134,15 +134,6 @@ static const gyroFilterAndRateConfig_t gyroConfigs[] = {
{ GYRO_LPF_256HZ, 3200, { BMI270_BWP_OSR4 | BMI270_ODR_3200} },
{ GYRO_LPF_256HZ, 1600, { BMI270_BWP_OSR2 | BMI270_ODR_1600} },
{ GYRO_LPF_256HZ, 800, { BMI270_BWP_NORM | BMI270_ODR_800 } },
{ GYRO_LPF_188HZ, 800, { BMI270_BWP_OSR2 | BMI270_ODR_800 } },
{ GYRO_LPF_188HZ, 400, { BMI270_BWP_NORM | BMI270_ODR_400 } },
{ GYRO_LPF_98HZ, 800, { BMI270_BWP_OSR4 | BMI270_ODR_800 } },
{ GYRO_LPF_98HZ, 400, { BMI270_BWP_OSR2 | BMI270_ODR_400 } },
{ GYRO_LPF_42HZ, 800, { BMI270_BWP_OSR4 | BMI270_ODR_800 } },
{ GYRO_LPF_42HZ, 400, { BMI270_BWP_OSR4 | BMI270_ODR_400 } },
};
// Toggle the CS to switch the device into SPI mode.

View file

@ -198,21 +198,6 @@ static const gyroFilterAndRateConfig_t icm42605GyroConfigs[] = {
{ GYRO_LPF_256HZ, 2000, { 3, 5 } }, /* 250 Hz LPF */
{ GYRO_LPF_256HZ, 1000, { 1, 6 } }, /* 250 Hz LPF */
{ GYRO_LPF_256HZ, 500, { 0, 15 } }, /* 250 Hz LPF */
{ GYRO_LPF_188HZ, 1000, { 3, 6 } }, /* 125 HZ */
{ GYRO_LPF_188HZ, 500, { 1, 15 } }, /* 125 HZ */
{ GYRO_LPF_98HZ, 1000, { 4, 6 } }, /* 100 HZ*/
{ GYRO_LPF_98HZ, 500, { 2, 15 } }, /* 100 HZ*/
{ GYRO_LPF_42HZ, 1000, { 6, 6 } }, /* 50 HZ */
{ GYRO_LPF_42HZ, 500, { 4, 15 } },
{ GYRO_LPF_20HZ, 1000, { 7, 6 } }, /* 25 HZ */
{ GYRO_LPF_20HZ, 500, { 6, 15 } },
{ GYRO_LPF_10HZ, 1000, { 7, 6 } }, /* 25 HZ */
{ GYRO_LPF_10HZ, 500, { 7, 15 } } /* 12.5 HZ */
};
static void icm42605AccAndGyroInit(gyroDev_t *gyro)

View file

@ -50,21 +50,6 @@ static const gyroFilterAndRateConfig_t mpuGyroConfigs[] = {
{ GYRO_LPF_256HZ, 1000, { MPU_DLPF_256HZ, 7 } },
{ GYRO_LPF_256HZ, 666, { MPU_DLPF_256HZ, 11 } },
{ GYRO_LPF_256HZ, 500, { MPU_DLPF_256HZ, 15 } },
{ GYRO_LPF_188HZ, 1000, { MPU_DLPF_188HZ, 0 } },
{ GYRO_LPF_188HZ, 500, { MPU_DLPF_188HZ, 1 } },
{ GYRO_LPF_98HZ, 1000, { MPU_DLPF_98HZ, 0 } },
{ GYRO_LPF_98HZ, 500, { MPU_DLPF_98HZ, 1 } },
{ GYRO_LPF_42HZ, 1000, { MPU_DLPF_42HZ, 0 } },
{ GYRO_LPF_42HZ, 500, { MPU_DLPF_42HZ, 1 } },
{ GYRO_LPF_20HZ, 1000, { MPU_DLPF_20HZ, 0 } },
{ GYRO_LPF_20HZ, 500, { MPU_DLPF_20HZ, 1 } },
{ GYRO_LPF_10HZ, 1000, { MPU_DLPF_10HZ, 0 } },
{ GYRO_LPF_10HZ, 500, { MPU_DLPF_10HZ, 1 } }
};
const gyroFilterAndRateConfig_t * mpuChooseGyroConfig(uint8_t desiredLpf, uint16_t desiredRateHz)

View file

@ -135,6 +135,7 @@ typedef enum {
DEVHW_VL53L1X,
DEVHW_US42,
DEVHW_TOF10120_I2C,
DEVHW_TERARANGER_EVO_I2C,
/* Other hardware */
DEVHW_MS4525, // Pitot meter

View file

@ -121,8 +121,9 @@ static bool ist8308Read(magDev_t * mag)
return false;
}
// Invert Y axis to co convert from left to right coordinate system
mag->magADCRaw[X] = (int16_t)(buf[1] << 8 | buf[0]) * LSB2FSV;
mag->magADCRaw[Y] = (int16_t)(buf[3] << 8 | buf[2]) * LSB2FSV;
mag->magADCRaw[Y] = -(int16_t)(buf[3] << 8 | buf[2]) * LSB2FSV;
mag->magADCRaw[Z] = (int16_t)(buf[5] << 8 | buf[4]) * LSB2FSV;
return true;

View file

@ -139,7 +139,7 @@ static bool ist8310Read(magDev_t * mag)
return false;
}
// Looks like datasheet is incorrect and we need to invert Y axis to conform to right hand rule
// Invert Y axis to co convert from left to right coordinate system
mag->magADCRaw[X] = (int16_t)(buf[1] << 8 | buf[0]) * LSB2FSV;
mag->magADCRaw[Y] = -(int16_t)(buf[3] << 8 | buf[2]) * LSB2FSV;
mag->magADCRaw[Z] = (int16_t)(buf[5] << 8 | buf[4]) * LSB2FSV;

View file

@ -178,13 +178,13 @@ int displayWriteChar(displayPort_t *instance, uint8_t x, uint8_t y, uint16_t c)
#ifdef USE_SIMULATOR
if (ARMING_FLAG(SIMULATOR_MODE_HITL)) {
//some FCs do not power max7456 from USB power
//driver can not read font metadata
//chip assumed to not support second bank of font
//artifical horizon, variometer and home direction are not drawn ( display.c: displayUpdateMaxChar())
//return dummy metadata to let all OSD elements to work in simulator mode
instance->maxChar = 512;
}
//some FCs do not power max7456 from USB power
//driver can not read font metadata
//chip assumed to not support second bank of font
//artifical horizon, variometer and home direction are not drawn ( display.c: displayUpdateMaxChar())
//return dummy metadata to let all OSD elements to work in simulator mode
instance->maxChar = 512;
}
#endif
if (c > instance->maxChar) {

View file

@ -124,6 +124,10 @@ void ws2811LedStripInit(void)
{
const timerHardware_t * timHw = timerGetByTag(IO_TAG(WS2811_PIN), TIM_USE_ANY);
if (!(timHw->usageFlags & TIM_USE_LED)) { // Check if it has not been reassigned
timHw = timerGetByUsageFlag(TIM_USE_LED); // Get first pin marked as LED
}
if (timHw == NULL) {
return;
}
@ -133,14 +137,14 @@ void ws2811LedStripInit(void)
return;
}
ws2811IO = IOGetByTag(IO_TAG(WS2811_PIN));
ws2811IO = IOGetByTag(timHw->tag); //IOGetByTag(IO_TAG(WS2811_PIN));
IOInit(ws2811IO, OWNER_LED_STRIP, RESOURCE_OUTPUT, 0);
IOConfigGPIOAF(ws2811IO, IOCFG_AF_PP_FAST, timHw->alternateFunction);
if ( ledPinConfig()->led_pin_pwm_mode == LED_PIN_PWM_MODE_LOW ) {
if (ledPinConfig()->led_pin_pwm_mode == LED_PIN_PWM_MODE_LOW) {
ledConfigurePWM();
*timerCCR(ws2811TCH) = 0;
} else if ( ledPinConfig()->led_pin_pwm_mode == LED_PIN_PWM_MODE_HIGH ) {
} else if (ledPinConfig()->led_pin_pwm_mode == LED_PIN_PWM_MODE_HIGH) {
ledConfigurePWM();
*timerCCR(ws2811TCH) = 100;
} else {

View file

@ -26,4 +26,4 @@
#else
#define NVIC_PRIORITY_GROUPING NVIC_PriorityGroup_4
#endif
#endif
#endif

View file

@ -49,8 +49,8 @@ typedef enum {
VIDEO_SYSTEM_HDZERO,
VIDEO_SYSTEM_DJIWTF,
VIDEO_SYSTEM_AVATAR,
VIDEO_SYSTEM_BFCOMPAT,
VIDEO_SYSTEM_BFCOMPAT_HD
VIDEO_SYSTEM_DJICOMPAT,
VIDEO_SYSTEM_DJICOMPAT_HD
} videoSystem_e;
typedef enum {

View file

@ -44,9 +44,9 @@
#define SYM_DBM 0x13 // 019 dBm
#define SYM_SNR 0x14 // 020 SNR
#define SYM_AH_DIRECTION_UP 0x15 // 021 Arrow up AHI
#define SYM_AH_DIRECTION_DOWN 0x16 // 022 Arrow down AHI
#define SYM_DIRECTION 0x17 // 023 to 030, directional little arrows
#define SYM_AH_DECORATION_UP 0x15 // 021 Arrow up AHI
#define SYM_AH_DECORATION_DOWN 0x16 // 022 Arrow down AHI
#define SYM_DECORATION 0x17 // 023 to 030, directional little arrows
#define SYM_VOLT 0x1F // 031 VOLTS
#define SYM_MAH 0x99 // 153 mAh
@ -178,8 +178,12 @@
#define SYM_ALERT 0xDD // 221 General alert symbol
#define SYM_TERRAIN_FOLLOWING 0xFB // 251 Terrain following (also Alt adjust)
#define SYM_CROSS_TRACK_ERROR 0xFC // 252 Cross track error
#define SYM_ADSB 0xFD // 253 ADBS
#define SYM_BLACKBOX 0xFE // 254 Blackbox
#define SYM_ADSB 0xFD // 253 ADSB
#define SYM_LOGO_START 0x101 // 257 to 297, INAV logo
#define SYM_LOGO_WIDTH 10
#define SYM_LOGO_HEIGHT 4

View file

@ -100,16 +100,14 @@ void pinioInit(void)
}
}
void pinioSet(int index, bool on)
void pinioSet(int index, bool newState)
{
const bool newState = on ^ pinioRuntime[index].inverted;
if (!pinioRuntime[index].io) {
return;
}
if (newState != pinioRuntime[index].state) {
IOWrite(pinioRuntime[index].io, newState);
IOWrite(pinioRuntime[index].io, newState ^ pinioRuntime[index].inverted);
pinioRuntime[index].state = newState;
}
}

View file

@ -38,4 +38,4 @@ extern const pinioHardware_t pinioHardware[];
extern const int pinioHardwareCount;
void pinioInit(void);
void pinioSet(int index, bool on);
void pinioSet(int index, bool newState);

View file

@ -47,6 +47,7 @@ enum {
MAP_TO_NONE,
MAP_TO_MOTOR_OUTPUT,
MAP_TO_SERVO_OUTPUT,
MAP_TO_LED_OUTPUT
};
typedef struct {
@ -167,10 +168,16 @@ static bool checkPwmTimerConflicts(const timerHardware_t *timHw)
#if defined(USE_LED_STRIP)
if (feature(FEATURE_LED_STRIP)) {
const timerHardware_t * ledTimHw = timerGetByTag(IO_TAG(WS2811_PIN), TIM_USE_ANY);
if (ledTimHw != NULL && timHw->tim == ledTimHw->tim) {
return true;
for (int i = 0; i < timerHardwareCount; i++) {
if (timHw->tim == timerHardware[i].tim && timerHardware[i].usageFlags & TIM_USE_LED) {
return true;
}
}
//const timerHardware_t * ledTimHw = timerGetByTag(IO_TAG(WS2811_PIN), TIM_USE_ANY);
//if (ledTimHw != NULL && timHw->tim == ledTimHw->tim) {
// return true;
//}
}
#endif
@ -213,16 +220,16 @@ static bool checkPwmTimerConflicts(const timerHardware_t *timHw)
static void timerHardwareOverride(timerHardware_t * timer) {
switch (timerOverrides(timer2id(timer->tim))->outputMode) {
case OUTPUT_MODE_MOTORS:
if (TIM_IS_SERVO(timer->usageFlags)) {
timer->usageFlags &= ~TIM_USE_SERVO;
timer->usageFlags |= TIM_USE_MOTOR;
}
timer->usageFlags &= ~(TIM_USE_SERVO|TIM_USE_LED);
timer->usageFlags |= TIM_USE_MOTOR;
break;
case OUTPUT_MODE_SERVOS:
if (TIM_IS_MOTOR(timer->usageFlags)) {
timer->usageFlags &= ~TIM_USE_MOTOR;
timer->usageFlags |= TIM_USE_SERVO;
}
timer->usageFlags &= ~(TIM_USE_MOTOR|TIM_USE_LED);
timer->usageFlags |= TIM_USE_SERVO;
break;
case OUTPUT_MODE_LED:
timer->usageFlags &= ~(TIM_USE_MOTOR|TIM_USE_SERVO);
timer->usageFlags |= TIM_USE_LED;
break;
}
}
@ -335,6 +342,8 @@ void pwmBuildTimerOutputList(timMotorServoHardware_t * timOutputs, bool isMixerU
type = MAP_TO_SERVO_OUTPUT;
} else if (TIM_IS_MOTOR(timHw->usageFlags) && !pwmHasServoOnTimer(timOutputs, timHw->tim)) {
type = MAP_TO_MOTOR_OUTPUT;
} else if (TIM_IS_LED(timHw->usageFlags) && !pwmHasMotorOnTimer(timOutputs, timHw->tim) && !pwmHasServoOnTimer(timOutputs, timHw->tim)) {
type = MAP_TO_LED_OUTPUT;
}
switch(type) {
@ -348,6 +357,10 @@ void pwmBuildTimerOutputList(timMotorServoHardware_t * timOutputs, bool isMixerU
timOutputs->timServos[timOutputs->maxTimServoCount++] = timHw;
pwmClaimTimer(timHw->tim, timHw->usageFlags);
break;
case MAP_TO_LED_OUTPUT:
timHw->usageFlags &= TIM_USE_LED;
pwmClaimTimer(timHw->tim, timHw->usageFlags);
break;
default:
break;
}

View file

@ -53,6 +53,11 @@ typedef enum {
SERVO_TYPE_SBUS_PWM
} servoProtocolType_e;
typedef enum {
PIN_LABEL_NONE = 0,
PIN_LABEL_LED
} pinLabel_e;
typedef enum {
PWM_INIT_ERROR_NONE = 0,
PWM_INIT_ERROR_TOO_MANY_MOTORS,

View file

@ -172,6 +172,8 @@ static pwmOutputPort_t *pwmOutConfig(const timerHardware_t *timHw, resourceOwner
const IO_t io = IOGetByTag(timHw->tag);
IOInit(io, owner, RESOURCE_OUTPUT, allocatedOutputPortCount);
pwmOutConfigTimer(p, tch, hz, period, value);
if (enableOutput) {
IOConfigGPIOAF(io, IOCFG_AF_PP, timHw->alternateFunction);
}
@ -181,7 +183,6 @@ static pwmOutputPort_t *pwmOutConfig(const timerHardware_t *timHw, resourceOwner
IOLo(io);
}
pwmOutConfigTimer(p, tch, hz, period, value);
return p;
}

View file

@ -0,0 +1,128 @@
/*
* This file is part of Cleanflight.
*
* Cleanflight is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Cleanflight is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdbool.h>
#include <stdint.h>
#include "platform.h"
#include "common/maths.h"
#if defined(USE_RANGEFINDER) && defined(USE_RANGEFINDER_TERARANGER_EVO_I2C)
#include "build/build_config.h"
#include "common/crc.h"
#include "drivers/time.h"
#include "drivers/bus_i2c.h"
#include "drivers/rangefinder/rangefinder.h"
#include "drivers/rangefinder/rangefinder_teraranger_evo.h"
#include "build/debug.h"
#define TERARANGER_EVO_DETECTION_CONE_DECIDEGREES 900
#define TERARANGER_EVO_DETECTION_CONE_EXTENDED_DECIDEGREES 900
#define TERARANGER_EVO_I2C_ADDRESS 0x31
#define TERARANGER_EVO_I2C_REGISTRY_TRIGGER_READING 0x00 // Write this command to the TeraRanger Evo and after a wait of approximately 500us read the 3 byte distance response
#define TERARANGER_EVO_I2C_REGISTRY_WHO_AM_I 0x01 // Write this value to TeraRanger Evo via I2C and the device responds with 0xA
#define TERARANGER_EVO_I2C_REGISTRY_CHANGE_BASE_ADDR 0xA2 // This command assigns a base address that will be memorised by the TerRanger Evo ie. power cycling the Evo will not restore the default I2C address.
#define TERARANGER_EVO_I2C_ANSWER_WHO_AM_I 0xA1
#define TERARANGER_EVO_VALUE_TOO_CLOSE 0x0000
#define TERARANGER_EVO_VALUE_OUT_OF_RANGE 0xffff
static int16_t minimumReadingIntervalMs = 50;
uint8_t triggerValue[0];
volatile int32_t teraRangerMeasurementCm;
static uint32_t timeOfLastMeasurementMs;
static uint8_t dataBuff[3];
static void teraRangerInit(rangefinderDev_t *rangefinder){
busWriteBuf(rangefinder->busDev, TERARANGER_EVO_I2C_REGISTRY_TRIGGER_READING, triggerValue, 1);
}
void teraRangerUpdate(rangefinderDev_t *rangefinder){
if (busReadBuf(rangefinder->busDev, TERARANGER_EVO_I2C_REGISTRY_TRIGGER_READING, dataBuff, 3)) {
teraRangerMeasurementCm = MILLIMETERS_TO_CENTIMETERS(((int32_t)dataBuff[0] << 8 | (int32_t)dataBuff[1]));
if(dataBuff[2] == crc8_update(0, &dataBuff, 2)){
if (teraRangerMeasurementCm == TERARANGER_EVO_VALUE_TOO_CLOSE || teraRangerMeasurementCm == TERARANGER_EVO_VALUE_OUT_OF_RANGE) {
teraRangerMeasurementCm = RANGEFINDER_OUT_OF_RANGE;
}
}
} else {
teraRangerMeasurementCm = RANGEFINDER_HARDWARE_FAILURE;
}
const timeMs_t timeNowMs = millis();
if (timeNowMs > timeOfLastMeasurementMs + minimumReadingIntervalMs) {
// measurement repeat interval should be greater than minimumReadingIntervalMs
// to avoid interference between connective measurements.
timeOfLastMeasurementMs = timeNowMs;
busWriteBuf(rangefinder->busDev, TERARANGER_EVO_I2C_ADDRESS, triggerValue, 1);
}
}
int32_t teraRangerGetDistance(rangefinderDev_t *rangefinder){
UNUSED(rangefinder);
return teraRangerMeasurementCm;
}
static bool deviceDetect(busDevice_t * busDev){
for (int retry = 0; retry < 5; retry++) {
uint8_t whoIamResult;
delay(150);
bool ack = busRead(busDev, TERARANGER_EVO_I2C_REGISTRY_WHO_AM_I, &whoIamResult);
if (ack && whoIamResult == TERARANGER_EVO_I2C_ANSWER_WHO_AM_I) {
return true;
}
};
return false;
}
bool teraRangerDetect(rangefinderDev_t *rangefinder){
rangefinder->busDev = busDeviceInit(BUSTYPE_I2C, DEVHW_TERARANGER_EVO_I2C, 0, OWNER_RANGEFINDER);
if (rangefinder->busDev == NULL) {
return false;
}
if (!deviceDetect(rangefinder->busDev)) {
busDeviceDeInit(rangefinder->busDev);
return false;
}
rangefinder->delayMs = RANGEFINDER_TERA_EVO_TASK_PERIOD_MS;
rangefinder->maxRangeCm = RANGEFINDER_TERA_EVO_MAX_RANGE_CM;
rangefinder->detectionConeDeciDegrees = TERARANGER_EVO_DETECTION_CONE_DECIDEGREES;
rangefinder->detectionConeExtendedDeciDegrees = TERARANGER_EVO_DETECTION_CONE_EXTENDED_DECIDEGREES;
rangefinder->init = &teraRangerInit;
rangefinder->update = &teraRangerUpdate;
rangefinder->read = &teraRangerGetDistance;
return true;
}
#endif

View file

@ -0,0 +1,29 @@
/*
* This file is part of INAV.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Alternatively, the contents of this file may be used under the terms
* of the GNU General Public License Version 3, as described below:
*
* This file is free software: you may copy, redistribute and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This file is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://www.gnu.org/licenses/.
*/
#pragma once
#define RANGEFINDER_TERA_EVO_TASK_PERIOD_MS 70
#define RANGEFINDER_TERA_EVO_MAX_RANGE_CM 600 // max distance depends on model https://www.terabee.com/sensors-modules/lidar-tof-range-finders/#individual-distance-measurement-sensors
bool teraRangerDetect(rangefinderDev_t *dev);

View file

@ -43,6 +43,7 @@
#include "drivers/serial.h"
#include "drivers/serial_tcp.h"
#include "target/SITL/serial_proxy.h"
static const struct serialPortVTable tcpVTable[];
static tcpPort_t tcpPorts[SERIAL_PORT_COUNT];
@ -118,6 +119,23 @@ static tcpPort_t *tcpReConfigure(tcpPort_t *port, uint32_t id)
return port;
}
void tcpReceiveBytes( tcpPort_t *port, const uint8_t* buffer, ssize_t recvSize ) {
for (ssize_t i = 0; i < recvSize; i++) {
if (port->serialPort.rxCallback) {
port->serialPort.rxCallback((uint16_t)buffer[i], port->serialPort.rxCallbackData);
} else {
pthread_mutex_lock(&port->receiveMutex);
port->serialPort.rxBuffer[port->serialPort.rxBufferHead] = buffer[i];
port->serialPort.rxBufferHead = (port->serialPort.rxBufferHead + 1) % port->serialPort.rxBufferSize;
pthread_mutex_unlock(&port->receiveMutex);
}
}
}
void tcpReceiveBytesEx( int portIndex, const uint8_t* buffer, ssize_t recvSize ) {
tcpReceiveBytes( &tcpPorts[portIndex], buffer, recvSize );
}
int tcpReceive(tcpPort_t *port)
{
char addrbuf[IPADDRESS_PRINT_BUFLEN];
@ -162,22 +180,12 @@ int tcpReceive(tcpPort_t *port)
return 0;
}
for (ssize_t i = 0; i < recvSize; i++) {
if (port->serialPort.rxCallback) {
port->serialPort.rxCallback((uint16_t)buffer[i], port->serialPort.rxCallbackData);
} else {
pthread_mutex_lock(&port->receiveMutex);
port->serialPort.rxBuffer[port->serialPort.rxBufferHead] = buffer[i];
port->serialPort.rxBufferHead = (port->serialPort.rxBufferHead + 1) % port->serialPort.rxBufferSize;
pthread_mutex_unlock(&port->receiveMutex);
}
}
if (recvSize < 0) {
recvSize = 0;
}
tcpReceiveBytes( port, buffer, recvSize );
return (int)recvSize;
}
@ -240,9 +248,21 @@ void tcpWritBuf(serialPort_t *instance, const void *data, int count)
send(port->clientSocketFd, data, count, 0);
}
int getTcpPortIndex(const serialPort_t *instance) {
for (int i = 0; i < SERIAL_PORT_COUNT; i++) {
if ( &(tcpPorts[i].serialPort) == instance) return i;
}
return -1;
}
void tcpWrite(serialPort_t *instance, uint8_t ch)
{
tcpWritBuf(instance, (void*)&ch, 1);
int index = getTcpPortIndex(instance);
if ( !serialFCProxy && serialProxyIsConnected() && (index == (serialUartIndex-1)) ) {
serialProxyWriteData( (unsigned char *)&ch, 1);
}
}
uint32_t tcpTotalRxBytesWaiting(const serialPort_t *instance)
@ -263,6 +283,10 @@ uint32_t tcpTotalRxBytesWaiting(const serialPort_t *instance)
return count;
}
uint32_t tcpRXBytesFree(int portIndex) {
return tcpPorts[portIndex].serialPort.rxBufferSize - tcpTotalRxBytesWaiting( &tcpPorts[portIndex].serialPort);
}
uint32_t tcpTotalTxBytesFree(const serialPort_t *instance)
{
UNUSED(instance);
@ -272,7 +296,6 @@ uint32_t tcpTotalTxBytesFree(const serialPort_t *instance)
bool isTcpTransmitBufferEmpty(const serialPort_t *instance)
{
UNUSED(instance);
return true;
}

View file

@ -26,6 +26,8 @@
#include <netinet/in.h>
#include <netdb.h>
#include "drivers/serial.h"
#define BASE_IP_ADDRESS 5760
#define TCP_BUFFER_SIZE 2048
#define TCP_MAX_PACKET_SIZE 65535
@ -50,5 +52,7 @@ typedef struct
serialPort_t *tcpOpen(USART_TypeDef *USARTx, serialReceiveCallbackPtr callback, void *rxCallbackData, uint32_t baudRate, portMode_t mode, portOptions_t options);
void tcpSend(tcpPort_t *port);
int tcpReceive(tcpPort_t *port);
extern void tcpSend(tcpPort_t *port);
extern int tcpReceive(tcpPort_t *port);
extern void tcpReceiveBytesEx( int portIndex, const uint8_t* buffer, ssize_t recvSize );
extern uint32_t tcpRXBytesFree(int portIndex);

View file

@ -48,10 +48,10 @@ void systemBeep(bool onoff)
#ifdef USE_SIMULATOR
if (ARMING_FLAG(SIMULATOR_MODE_HITL)) {
if (SIMULATOR_HAS_OPTION(HITL_MUTE_BEEPER)) {
onoff = false;
}
}
if (SIMULATOR_HAS_OPTION(HITL_MUTE_BEEPER)) {
onoff = false;
}
}
#endif
if (beeperConfig()->pwmMode) {

View file

@ -21,7 +21,6 @@
#include <stdbool.h>
void systemInit(void);
void systemClockSetup(uint8_t cpuUnderclock);
typedef enum {
FAILURE_DEVELOPER = 0,

View file

@ -114,12 +114,6 @@ uint32_t systemBootloaderAddress(void)
//return system_isr_vector_table_base;
}
void systemClockSetup(uint8_t cpuUnderclock)
{
(void)cpuUnderclock;
// This is a stub
}
void systemInit(void)
{
//config system clock to 288mhz usb 48mhz

View file

@ -143,12 +143,6 @@ uint32_t systemBootloaderAddress(void)
return 0x1FFF0000;
}
void systemClockSetup(uint8_t cpuUnderclock)
{
(void)cpuUnderclock;
// This is a stub
}
void systemInit(void)
{
SetSysClock();

View file

@ -66,12 +66,6 @@ uint32_t systemBootloaderAddress(void)
return 0x1FF00000;
}
void systemClockSetup(uint8_t cpuUnderclock)
{
(void)cpuUnderclock;
// This is a stub
}
void systemInit(void)
{
checkForBootLoaderRequest();

View file

@ -60,12 +60,6 @@ uint32_t systemBootloaderAddress(void)
#endif
}
void systemClockSetup(uint8_t cpuUnderclock)
{
(void)cpuUnderclock;
// This is a stub
}
void systemInit(void)
{
checkForBootLoaderRequest();

View file

@ -113,9 +113,9 @@ typedef enum {
TIM_USE_MOTOR = (1 << 2), // Motor output
TIM_USE_SERVO = (1 << 3), // Servo output
TIM_USE_MC_CHNFW = (1 << 4), // Deprecated and not used after removal of CHANNEL_FORWARDING feature
//TIM_USE_FW_MOTOR = (1 << 5), // We no longer differentiate mc from fw on pwm allocation
//TIM_USE_FW_SERVO = (1 << 6),
TIM_USE_LED = (1 << 24),
//TIM_USE_FW_MOTOR = (1 << 5), // We no longer differentiate mc from fw on pwm allocation
//TIM_USE_FW_SERVO = (1 << 6),
TIM_USE_LED = (1 << 24), // Remapping needs to be in the lower 8 bits.
TIM_USE_BEEPER = (1 << 25),
} timerUsageFlag_e;
@ -123,6 +123,7 @@ typedef enum {
#define TIM_IS_MOTOR(flags) ((flags) & TIM_USE_MOTOR)
#define TIM_IS_SERVO(flags) ((flags) & TIM_USE_SERVO)
#define TIM_IS_LED(flags) ((flags) & TIM_USE_LED)
#define TIM_IS_MOTOR_ONLY(flags) (TIM_IS_MOTOR(flags) && !TIM_IS_SERVO(flags))
#define TIM_IS_SERVO_ONLY(flags) (!TIM_IS_MOTOR(flags) && TIM_IS_SERVO(flags))

View file

@ -143,8 +143,9 @@ static void cliAssert(char *cmdline);
#endif
#ifdef USE_CLI_BATCH
static bool commandBatchActive = false;
static bool commandBatchError = false;
static bool commandBatchActive = false;
static bool commandBatchError = false;
static uint8_t commandBatchErrorCount = 0;
#endif
// sync this with features_e
@ -162,6 +163,7 @@ static const char * outputModeNames[] = {
"AUTO",
"MOTORS",
"SERVOS",
"LED",
NULL
};
@ -257,6 +259,7 @@ static void cliPrintError(const char *str)
#ifdef USE_CLI_BATCH
if (commandBatchActive) {
commandBatchError = true;
commandBatchErrorCount++;
}
#endif
}
@ -268,6 +271,7 @@ static void cliPrintErrorLine(const char *str)
#ifdef USE_CLI_BATCH
if (commandBatchActive) {
commandBatchError = true;
commandBatchErrorCount++;
}
#endif
}
@ -370,6 +374,7 @@ static void cliPrintErrorVa(const char *format, va_list va)
#ifdef USE_CLI_BATCH
if (commandBatchActive) {
commandBatchError = true;
commandBatchErrorCount++;
}
#endif
}
@ -661,6 +666,7 @@ static void cliAssert(char *cmdline)
#ifdef USE_CLI_BATCH
if (commandBatchActive) {
commandBatchError = true;
commandBatchErrorCount++;
}
#endif
}
@ -1166,7 +1172,7 @@ static void cliRxRange(char *cmdline)
ptr = cmdline;
i = fastA2I(ptr);
if (i >= 0 && i < NON_AUX_CHANNEL_COUNT) {
int rangeMin, rangeMax;
int rangeMin = 0, rangeMax = 0;
ptr = nextArg(ptr);
if (ptr) {
@ -2816,6 +2822,8 @@ static void cliTimerOutputMode(char *cmdline)
mode = OUTPUT_MODE_MOTORS;
} else if(!sl_strcasecmp("SERVOS", tok)) {
mode = OUTPUT_MODE_SERVOS;
} else if(!sl_strcasecmp("LED", tok)) {
mode = OUTPUT_MODE_LED;
} else {
cliShowParseError();
return;
@ -3420,7 +3428,10 @@ static void cliDumpMixerProfile(uint8_t profileIndex, uint8_t dumpMask)
#ifdef USE_CLI_BATCH
static void cliPrintCommandBatchWarning(const char *warning)
{
cliPrintErrorLinef("ERRORS WERE DETECTED - PLEASE REVIEW BEFORE CONTINUING");
char errorBuf[59];
tfp_sprintf(errorBuf, "%d ERRORS WERE DETECTED - Please review and fix before continuing!", commandBatchErrorCount);
cliPrintErrorLinef(errorBuf);
if (warning) {
cliPrintErrorLinef(warning);
}
@ -3430,6 +3441,7 @@ static void resetCommandBatch(void)
{
commandBatchActive = false;
commandBatchError = false;
commandBatchErrorCount = 0;
}
static void cliBatch(char *cmdline)
@ -3438,6 +3450,7 @@ static void cliBatch(char *cmdline)
if (!commandBatchActive) {
commandBatchActive = true;
commandBatchError = false;
commandBatchErrorCount = 0;
}
cliPrintLine("Command batch started");
} else if (strncasecmp(cmdline, "end", 3) == 0) {

View file

@ -115,9 +115,6 @@ PG_RESET_TEMPLATE(systemConfig_t, systemConfig,
#endif
#ifdef USE_I2C
.i2c_speed = SETTING_I2C_SPEED_DEFAULT,
#endif
#ifdef USE_UNDERCLOCK
.cpuUnderclock = SETTING_CPU_UNDERCLOCK_DEFAULT,
#endif
.throttle_tilt_compensation_strength = SETTING_THROTTLE_TILT_COMP_STR_DEFAULT, // 0-100, 0 - disabled
.craftName = SETTING_NAME_DEFAULT,
@ -287,6 +284,14 @@ void createDefaultConfig(void)
featureSet(FEATURE_AIRMODE);
targetConfiguration();
#ifdef MSP_UART
int port = findSerialPortIndexByIdentifier(MSP_UART);
if (port) {
serialConfigMutable()->portConfigs[port].functionMask = FUNCTION_MSP;
serialConfigMutable()->portConfigs[port].msp_baudrateIndex = BAUD_115200;
}
#endif
}
void resetConfigs(void)

View file

@ -76,9 +76,6 @@ typedef struct systemConfig_s {
#endif
#ifdef USE_I2C
uint8_t i2c_speed;
#endif
#ifdef USE_UNDERCLOCK
uint8_t cpuUnderclock;
#endif
uint8_t throttle_tilt_compensation_strength; // the correction that will be applied at throttle_correction_angle.
char craftName[MAX_NAME_LENGTH + 1];

View file

@ -237,7 +237,7 @@ static void updateArmingStatus(void)
/* CHECK: pitch / roll sticks centered when NAV_LAUNCH_MODE enabled */
if (isNavLaunchEnabled()) {
if (isRollPitchStickDeflected(rcControlsConfig()->control_deadband)) {
if (isRollPitchStickDeflected(CONTROL_DEADBAND)) {
ENABLE_ARMING_FLAG(ARMING_DISABLED_ROLLPITCH_NOT_CENTERED);
} else {
DISABLE_ARMING_FLAG(ARMING_DISABLED_ROLLPITCH_NOT_CENTERED);
@ -307,14 +307,6 @@ static void updateArmingStatus(void)
DISABLE_ARMING_FLAG(ARMING_DISABLED_BOXFAILSAFE);
}
/* CHECK: BOXKILLSWITCH */
if (IS_RC_MODE_ACTIVE(BOXKILLSWITCH)) {
ENABLE_ARMING_FLAG(ARMING_DISABLED_BOXKILLSWITCH);
}
else {
DISABLE_ARMING_FLAG(ARMING_DISABLED_BOXKILLSWITCH);
}
/* CHECK: Do not allow arming if Servo AutoTrim is enabled */
if (IS_RC_MODE_ACTIVE(BOXAUTOTRIM)) {
ENABLE_ARMING_FLAG(ARMING_DISABLED_SERVO_AUTOTRIM);
@ -350,6 +342,10 @@ static void updateArmingStatus(void)
DISABLE_ARMING_FLAG(ARMING_DISABLED_NO_PREARM);
}
if (ARMING_FLAG(ARMING_DISABLED_LANDING_DETECTED) && !IS_RC_MODE_ACTIVE(BOXARM)) {
DISABLE_ARMING_FLAG(ARMING_DISABLED_LANDING_DETECTED);
}
/* CHECK: Arming switch */
// If arming is disabled and the ARM switch is on
// Note that this should be last check so all other blockers could be cleared correctly
@ -513,7 +509,7 @@ bool emergInflightRearmEnabled(void)
timeMs_t currentTimeMs = millis();
emergRearmStabiliseTimeout = 0;
if ((lastDisarmReason != DISARM_SWITCH && lastDisarmReason != DISARM_KILLSWITCH) ||
if ((lastDisarmReason != DISARM_SWITCH) ||
(currentTimeMs > US2MS(lastDisarmTimeUs) + EMERGENCY_INFLIGHT_REARM_TIME_WINDOW_MS)) {
return false;
}
@ -708,7 +704,7 @@ void processRx(timeUs_t currentTimeUs)
}
/* Turn assistant mode */
if (IS_RC_MODE_ACTIVE(BOXTURNASSIST)) {
if (IS_RC_MODE_ACTIVE(BOXTURNASSIST) || navigationRequiresTurnAssistance()) {
ENABLE_FLIGHT_MODE(TURN_ASSISTANT);
} else {
DISABLE_FLIGHT_MODE(TURN_ASSISTANT);
@ -904,7 +900,7 @@ void taskMainPidLoop(timeUs_t currentTimeUs)
}
#if defined(SITL_BUILD)
if (lockMainPID()) {
if (ARMING_FLAG(SIMULATOR_MODE_HITL) || lockMainPID()) {
#endif
gyroFilter();
@ -1020,6 +1016,10 @@ float getFlightTime(void)
return US2S(flightTime);
}
void resetFlightTime(void) {
flightTime = 0;
}
float getArmTime(void)
{
return US2S(armTime);

View file

@ -27,7 +27,6 @@ typedef enum disarmReason_e {
DISARM_STICKS = 2,
DISARM_SWITCH_3D = 3,
DISARM_SWITCH = 4,
DISARM_KILLSWITCH = 5,
DISARM_FAILSAFE = 6,
DISARM_NAVIGATION = 7,
DISARM_LANDING = 8,
@ -46,6 +45,7 @@ bool emergencyArmingUpdate(bool armingSwitchIsOn, bool forceArm);
bool areSensorsCalibrating(void);
float getFlightTime(void);
void resetFlightTime(void);
float getArmTime(void);
void fcReboot(bool bootLoader);

View file

@ -60,7 +60,6 @@
#include "drivers/pwm_esc_detect.h"
#include "drivers/pwm_mapping.h"
#include "drivers/pwm_output.h"
#include "drivers/pwm_output.h"
#include "drivers/sensor.h"
#include "drivers/serial.h"
#include "drivers/serial_softserial.h"
@ -147,6 +146,10 @@
#include "telemetry/telemetry.h"
#if defined(SITL_BUILD)
#include "target/SITL/serial_proxy.h"
#endif
#ifdef USE_HARDWARE_REVISION_DETECTION
#include "hardware_revision.h"
#endif
@ -223,19 +226,16 @@ void init(void)
flashDeviceInitialized = flashInit();
#endif
#if defined(SITL_BUILD)
serialProxyInit();
#endif
initEEPROM();
ensureEEPROMContainsValidData();
suspendRxSignal();
readEEPROM();
resumeRxSignal();
#ifdef USE_UNDERCLOCK
// Re-initialize system clock to their final values (if necessary)
systemClockSetup(systemConfig()->cpuUnderclock);
#else
systemClockSetup(false);
#endif
#ifdef USE_I2C
i2cSetSpeed(systemConfig()->i2c_speed);
#endif
@ -256,7 +256,7 @@ void init(void)
EXTIInit();
#endif
#ifdef USE_SPEKTRUM_BIND
#if defined(USE_SPEKTRUM_BIND) && defined(USE_SERIALRX_SPEKTRUM)
if (rxConfig()->receiverType == RX_TYPE_SERIAL) {
switch (rxConfig()->serialrx_provider) {
case SERIALRX_SPEKTRUM1024:

View file

@ -83,6 +83,7 @@
#include "config/config_eeprom.h"
#include "config/feature.h"
#include "io/adsb.h"
#include "io/asyncfatfs/asyncfatfs.h"
#include "io/flashfs.h"
#include "io/gps.h"
@ -503,6 +504,14 @@ static bool mspFcProcessOutCommand(uint16_t cmdMSP, sbuf_t *dst, mspPostProcessF
sbufWriteU32(dst, 0); //Input reversing is not required since it can be done on mixer level
}
break;
case MSP2_INAV_SERVO_CONFIG:
for (int i = 0; i < MAX_SUPPORTED_SERVOS; i++) {
sbufWriteU16(dst, servoParams(i)->min);
sbufWriteU16(dst, servoParams(i)->max);
sbufWriteU16(dst, servoParams(i)->middle);
sbufWriteU8(dst, servoParams(i)->rate);
}
break;
case MSP_SERVO_MIX_RULES:
for (int i = 0; i < MAX_SERVO_RULES; i++) {
sbufWriteU8(dst, customServoMixers(i)->targetChannel);
@ -669,11 +678,6 @@ static bool mspFcProcessOutCommand(uint16_t cmdMSP, sbuf_t *dst, mspPostProcessF
sbufWriteU16(dst, getRSSI());
break;
case MSP_ARMING_CONFIG:
sbufWriteU8(dst, 0);
sbufWriteU8(dst, armingConfig()->disarm_kill_switch);
break;
case MSP_LOOP_TIME:
sbufWriteU16(dst, gyroConfig()->looptime);
break;
@ -768,7 +772,7 @@ static bool mspFcProcessOutCommand(uint16_t cmdMSP, sbuf_t *dst, mspPostProcessF
sbufWriteU16(dst, PWM_RANGE_MIDDLE);
sbufWriteU16(dst, 0); // Was min_throttle
sbufWriteU16(dst, motorConfig()->maxthrottle);
sbufWriteU16(dst, getMaxThrottle());
sbufWriteU16(dst, motorConfig()->mincommand);
sbufWriteU16(dst, currentBatteryProfile->failsafe_throttle);
@ -809,7 +813,7 @@ static bool mspFcProcessOutCommand(uint16_t cmdMSP, sbuf_t *dst, mspPostProcessF
sbufWriteU16(dst, PWM_RANGE_MIDDLE);
sbufWriteU16(dst, 0); //Was min_throttle
sbufWriteU16(dst, motorConfig()->maxthrottle);
sbufWriteU16(dst, getMaxThrottle());
sbufWriteU16(dst, motorConfig()->mincommand);
sbufWriteU16(dst, currentBatteryProfile->failsafe_throttle);
@ -852,7 +856,7 @@ static bool mspFcProcessOutCommand(uint16_t cmdMSP, sbuf_t *dst, mspPostProcessF
sbufWriteU32(dst, currentBatteryProfile->capacity.value);
sbufWriteU32(dst, currentBatteryProfile->capacity.warning);
sbufWriteU32(dst, currentBatteryProfile->capacity.critical);
sbufWriteU8(dst, currentBatteryProfile->capacity.unit);
sbufWriteU8(dst, batteryMetersConfig()->capacity_unit);
break;
case MSP2_INAV_MISC2:
@ -891,14 +895,7 @@ static bool mspFcProcessOutCommand(uint16_t cmdMSP, sbuf_t *dst, mspPostProcessF
sbufWriteU32(dst, currentBatteryProfile->capacity.value);
sbufWriteU32(dst, currentBatteryProfile->capacity.warning);
sbufWriteU32(dst, currentBatteryProfile->capacity.critical);
sbufWriteU8(dst, currentBatteryProfile->capacity.unit);
break;
case MSP_MOTOR_PINS:
// FIXME This is hardcoded and should not be.
for (int i = 0; i < 8; i++) {
sbufWriteU8(dst, i + 1);
}
sbufWriteU8(dst, batteryMetersConfig()->capacity_unit);
break;
#ifdef USE_GPS
@ -950,6 +947,33 @@ static bool mspFcProcessOutCommand(uint16_t cmdMSP, sbuf_t *dst, mspPostProcessF
sbufWriteU16(dst, gpsSol.epv);
break;
#endif
case MSP2_ADSB_VEHICLE_LIST:
#ifdef USE_ADSB
sbufWriteU8(dst, MAX_ADSB_VEHICLES);
sbufWriteU8(dst, ADSB_CALL_SIGN_MAX_LENGTH);
for(uint8_t i = 0; i < MAX_ADSB_VEHICLES; i++){
adsbVehicle_t *adsbVehicle = findVehicle(i);
for(uint8_t ii = 0; ii < ADSB_CALL_SIGN_MAX_LENGTH; ii++){
sbufWriteU8(dst, adsbVehicle->vehicleValues.callsign[ii]);
}
sbufWriteU32(dst, adsbVehicle->vehicleValues.icao);
sbufWriteU32(dst, adsbVehicle->vehicleValues.lat);
sbufWriteU32(dst, adsbVehicle->vehicleValues.lon);
sbufWriteU32(dst, adsbVehicle->vehicleValues.alt);
sbufWriteU16(dst, (uint16_t)CENTIDEGREES_TO_DEGREES(adsbVehicle->vehicleValues.heading));
sbufWriteU8(dst, adsbVehicle->vehicleValues.tslc);
sbufWriteU8(dst, adsbVehicle->vehicleValues.emitterType);
sbufWriteU8(dst, adsbVehicle->ttl);
}
#else
sbufWriteU8(dst, 0);
sbufWriteU8(dst, 0);
#endif
break;
case MSP_DEBUG:
// output some useful QA statistics
// debug[x] = ((hse_value / 1000000) * 1000) + (SystemCoreClock / 1000000); // XX0YY [crystal clock : core clock]
@ -1244,7 +1268,7 @@ static bool mspFcProcessOutCommand(uint16_t cmdMSP, sbuf_t *dst, mspPostProcessF
sbufWriteU16(dst, accelerometerConfig()->acc_notch_cutoff);
sbufWriteU16(dst, 0); //Was gyroConfig()->gyro_stage2_lowpass_hz
break;
break;
case MSP_PID_ADVANCED:
sbufWriteU16(dst, 0); // pidProfile()->rollPitchItermIgnoreRate
@ -1254,7 +1278,7 @@ static bool mspFcProcessOutCommand(uint16_t cmdMSP, sbuf_t *dst, mspPostProcessF
sbufWriteU8(dst, 0); //BF: pidProfile()->vbatPidCompensation
sbufWriteU8(dst, 0); //BF: pidProfile()->setpointRelaxRatio
sbufWriteU8(dst, 0);
sbufWriteU16(dst, pidProfile()->pidSumLimit);
sbufWriteU16(dst, 0); //Was pidsum limit
sbufWriteU8(dst, 0); //BF: pidProfile()->itermThrottleGain
/*
@ -1272,7 +1296,7 @@ static bool mspFcProcessOutCommand(uint16_t cmdMSP, sbuf_t *dst, mspPostProcessF
sbufWriteU8(dst, pidProfile()->heading_hold_rate_limit);
sbufWriteU8(dst, HEADING_HOLD_ERROR_LPF_FREQ);
sbufWriteU16(dst, 0);
sbufWriteU8(dst, gyroConfig()->gyro_lpf);
sbufWriteU8(dst, GYRO_LPF_256HZ);
sbufWriteU8(dst, accelerometerConfig()->acc_lpf_hz);
sbufWriteU8(dst, 0); //reserved
sbufWriteU8(dst, 0); //reserved
@ -1312,9 +1336,9 @@ static bool mspFcProcessOutCommand(uint16_t cmdMSP, sbuf_t *dst, mspPostProcessF
case MSP_NAV_POSHOLD:
sbufWriteU8(dst, navConfig()->general.flags.user_control_mode);
sbufWriteU16(dst, navConfig()->general.max_auto_speed);
sbufWriteU16(dst, navConfig()->general.max_auto_climb_rate);
sbufWriteU16(dst, mixerConfig()->platformType == PLATFORM_AIRPLANE ? navConfig()->fw.max_auto_climb_rate : navConfig()->mc.max_auto_climb_rate);
sbufWriteU16(dst, navConfig()->general.max_manual_speed);
sbufWriteU16(dst, navConfig()->general.max_manual_climb_rate);
sbufWriteU16(dst, mixerConfig()->platformType == PLATFORM_AIRPLANE ? navConfig()->fw.max_manual_climb_rate : navConfig()->mc.max_manual_climb_rate);
sbufWriteU8(dst, navConfig()->mc.max_bank_angle);
sbufWriteU8(dst, navConfig()->mc.althold_throttle_type);
sbufWriteU16(dst, currentBatteryProfile->nav.mc.hover_throttle);
@ -1392,7 +1416,7 @@ static bool mspFcProcessOutCommand(uint16_t cmdMSP, sbuf_t *dst, mspPostProcessF
sbufWriteU16(dst, positionEstimationConfig()->w_xy_gps_p * 100); // 2 inav_w_xy_gps_p float as value * 100
sbufWriteU16(dst, positionEstimationConfig()->w_xy_gps_v * 100); // 2 inav_w_xy_gps_v float as value * 100
sbufWriteU8(dst, gpsConfigMutable()->gpsMinSats); // 1
sbufWriteU8(dst, positionEstimationConfig()->use_gps_velned); // 1 inav_use_gps_velned ON/OFF
sbufWriteU8(dst, 1); // 1 inav_use_gps_velned ON/OFF
break;
@ -1520,6 +1544,13 @@ static bool mspFcProcessOutCommand(uint16_t cmdMSP, sbuf_t *dst, mspPostProcessF
#else
sbufWriteU16(dst, 0);
sbufWriteU16(dst, 0);
#endif
#ifdef USE_ADSB
sbufWriteU16(dst, osdConfig()->adsb_distance_warning);
sbufWriteU16(dst, osdConfig()->adsb_distance_alert);
#else
sbufWriteU16(dst, 0);
sbufWriteU16(dst, 0);
#endif
break;
@ -1544,6 +1575,7 @@ static bool mspFcProcessOutCommand(uint16_t cmdMSP, sbuf_t *dst, mspPostProcessF
}
break;
// Obsolete, replaced by MSP2_INAV_OUTPUT_MAPPING_EXT2
case MSP2_INAV_OUTPUT_MAPPING_EXT:
for (uint8_t i = 0; i < timerHardwareCount; ++i)
if (!(timerHardware[i].usageFlags & (TIM_USE_PPM | TIM_USE_PWM))) {
@ -1552,10 +1584,36 @@ static bool mspFcProcessOutCommand(uint16_t cmdMSP, sbuf_t *dst, mspPostProcessF
#else
sbufWriteU8(dst, timer2id(timerHardware[i].tim));
#endif
// usageFlags is u32, cuts out the higher 24bits
sbufWriteU8(dst, timerHardware[i].usageFlags);
}
break;
case MSP2_INAV_OUTPUT_MAPPING_EXT2:
{
#if !defined(SITL_BUILD) && defined(WS2811_PIN)
ioTag_t led_tag = IO_TAG(WS2811_PIN);
#endif
for (uint8_t i = 0; i < timerHardwareCount; ++i)
if (!(timerHardware[i].usageFlags & (TIM_USE_PPM | TIM_USE_PWM))) {
#if defined(SITL_BUILD)
sbufWriteU8(dst, i);
#else
sbufWriteU8(dst, timer2id(timerHardware[i].tim));
#endif
sbufWriteU32(dst, timerHardware[i].usageFlags);
#if defined(SITL_BUILD) || !defined(WS2811_PIN)
sbufWriteU8(dst, 0);
#else
// Extra label to help identify repurposed PINs.
// Eventually, we can try to add more labels for PPM pins, etc.
sbufWriteU8(dst, timerHardware[i].tag == led_tag ? PIN_LABEL_LED : PIN_LABEL_NONE);
#endif
}
}
break;
case MSP2_INAV_MC_BRAKING:
#ifdef USE_MR_BRAKING_MODE
sbufWriteU16(dst, navConfig()->mc.braking_speed_threshold);
@ -1621,6 +1679,7 @@ static bool mspFcProcessOutCommand(uint16_t cmdMSP, sbuf_t *dst, mspPostProcessF
sbufWriteU8(dst, ezTune()->aggressiveness);
sbufWriteU8(dst, ezTune()->rate);
sbufWriteU8(dst, ezTune()->expo);
sbufWriteU8(dst, ezTune()->snappiness);
}
break;
#endif
@ -1793,14 +1852,6 @@ static mspResult_e mspFcProcessInCommand(uint16_t cmdMSP, sbuf_t *src)
break;
#endif
case MSP_SET_ARMING_CONFIG:
if (dataSize == 2) {
sbufReadU8(src); //Swallow the first byte, used to be auto_disarm_delay
armingConfigMutable()->disarm_kill_switch = !!sbufReadU8(src);
} else
return MSP_RESULT_ERROR;
break;
case MSP_SET_LOOP_TIME:
if (sbufReadU16Safe(&tmp_u16, src))
gyroConfigMutable()->looptime = tmp_u16;
@ -1936,7 +1987,7 @@ static mspResult_e mspFcProcessInCommand(uint16_t cmdMSP, sbuf_t *src)
sbufReadU16(src); // midrc
sbufReadU16(src); //Was min_throttle
motorConfigMutable()->maxthrottle = constrain(sbufReadU16(src), PWM_RANGE_MIN, PWM_RANGE_MAX);
sbufReadU16(src); //Was maxThrottle
motorConfigMutable()->mincommand = constrain(sbufReadU16(src), 0, PWM_RANGE_MAX);
currentBatteryProfileMutable->failsafe_throttle = constrain(sbufReadU16(src), PWM_RANGE_MIN, PWM_RANGE_MAX);
@ -1984,7 +2035,7 @@ static mspResult_e mspFcProcessInCommand(uint16_t cmdMSP, sbuf_t *src)
sbufReadU16(src); // midrc
sbufReadU16(src); // was min_throttle
motorConfigMutable()->maxthrottle = constrain(sbufReadU16(src), PWM_RANGE_MIN, PWM_RANGE_MAX);
sbufReadU16(src); // was maxThrottle
motorConfigMutable()->mincommand = constrain(sbufReadU16(src), 0, PWM_RANGE_MAX);
currentBatteryProfileMutable->failsafe_throttle = constrain(sbufReadU16(src), PWM_RANGE_MIN, PWM_RANGE_MAX);
@ -2030,13 +2081,13 @@ static mspResult_e mspFcProcessInCommand(uint16_t cmdMSP, sbuf_t *src)
currentBatteryProfileMutable->capacity.value = sbufReadU32(src);
currentBatteryProfileMutable->capacity.warning = sbufReadU32(src);
currentBatteryProfileMutable->capacity.critical = sbufReadU32(src);
currentBatteryProfileMutable->capacity.unit = sbufReadU8(src);
batteryMetersConfigMutable()->capacity_unit = sbufReadU8(src);
if ((batteryMetersConfig()->voltageSource != BAT_VOLTAGE_RAW) && (batteryMetersConfig()->voltageSource != BAT_VOLTAGE_SAG_COMP)) {
batteryMetersConfigMutable()->voltageSource = BAT_VOLTAGE_RAW;
return MSP_RESULT_ERROR;
}
if ((currentBatteryProfile->capacity.unit != BAT_CAPACITY_UNIT_MAH) && (currentBatteryProfile->capacity.unit != BAT_CAPACITY_UNIT_MWH)) {
currentBatteryProfileMutable->capacity.unit = BAT_CAPACITY_UNIT_MAH;
if ((batteryMetersConfig()->capacity_unit != BAT_CAPACITY_UNIT_MAH) && (batteryMetersConfig()->capacity_unit != BAT_CAPACITY_UNIT_MWH)) {
batteryMetersConfigMutable()->capacity_unit = BAT_CAPACITY_UNIT_MAH;
return MSP_RESULT_ERROR;
}
} else
@ -2069,13 +2120,13 @@ static mspResult_e mspFcProcessInCommand(uint16_t cmdMSP, sbuf_t *src)
currentBatteryProfileMutable->capacity.value = sbufReadU32(src);
currentBatteryProfileMutable->capacity.warning = sbufReadU32(src);
currentBatteryProfileMutable->capacity.critical = sbufReadU32(src);
currentBatteryProfileMutable->capacity.unit = sbufReadU8(src);
batteryMetersConfigMutable()->capacity_unit = sbufReadU8(src);
if ((batteryMetersConfig()->voltageSource != BAT_VOLTAGE_RAW) && (batteryMetersConfig()->voltageSource != BAT_VOLTAGE_SAG_COMP)) {
batteryMetersConfigMutable()->voltageSource = BAT_VOLTAGE_RAW;
return MSP_RESULT_ERROR;
}
if ((currentBatteryProfile->capacity.unit != BAT_CAPACITY_UNIT_MAH) && (currentBatteryProfile->capacity.unit != BAT_CAPACITY_UNIT_MWH)) {
currentBatteryProfileMutable->capacity.unit = BAT_CAPACITY_UNIT_MAH;
if ((batteryMetersConfig()->capacity_unit != BAT_CAPACITY_UNIT_MAH) && (batteryMetersConfig()->capacity_unit != BAT_CAPACITY_UNIT_MWH)) {
batteryMetersConfigMutable()->capacity_unit = BAT_CAPACITY_UNIT_MAH;
return MSP_RESULT_ERROR;
}
} else
@ -2114,6 +2165,22 @@ static mspResult_e mspFcProcessInCommand(uint16_t cmdMSP, sbuf_t *src)
}
break;
case MSP2_INAV_SET_SERVO_CONFIG:
if (dataSize != 8) {
return MSP_RESULT_ERROR;
}
tmp_u8 = sbufReadU8(src);
if (tmp_u8 >= MAX_SUPPORTED_SERVOS) {
return MSP_RESULT_ERROR;
} else {
servoParamsMutable(tmp_u8)->min = sbufReadU16(src);
servoParamsMutable(tmp_u8)->max = sbufReadU16(src);
servoParamsMutable(tmp_u8)->middle = sbufReadU16(src);
servoParamsMutable(tmp_u8)->rate = sbufReadU8(src);
servoComputeScalingFactors(tmp_u8);
}
break;
case MSP_SET_SERVO_MIX_RULE:
sbufReadU8Safe(&tmp_u8, src);
if ((dataSize == 9) && (tmp_u8 < MAX_SERVO_RULES)) {
@ -2292,7 +2359,7 @@ static mspResult_e mspFcProcessInCommand(uint16_t cmdMSP, sbuf_t *src)
sbufReadU8(src); //BF: pidProfileMutable()->vbatPidCompensation
sbufReadU8(src); //BF: pidProfileMutable()->setpointRelaxRatio
sbufReadU8(src);
pidProfileMutable()->pidSumLimit = sbufReadU16(src);
sbufReadU16(src); // Was pidsumLimit
sbufReadU8(src); //BF: pidProfileMutable()->itermThrottleGain
/*
@ -2313,7 +2380,7 @@ static mspResult_e mspFcProcessInCommand(uint16_t cmdMSP, sbuf_t *src)
pidProfileMutable()->heading_hold_rate_limit = sbufReadU8(src);
sbufReadU8(src); //HEADING_HOLD_ERROR_LPF_FREQ
sbufReadU16(src); //Legacy yaw_jump_prevention_limit
gyroConfigMutable()->gyro_lpf = sbufReadU8(src);
sbufReadU8(src); // was gyro lpf
accelerometerConfigMutable()->acc_lpf_hz = sbufReadU8(src);
sbufReadU8(src); //reserved
sbufReadU8(src); //reserved
@ -2359,9 +2426,17 @@ static mspResult_e mspFcProcessInCommand(uint16_t cmdMSP, sbuf_t *src)
if (dataSize == 13) {
navConfigMutable()->general.flags.user_control_mode = sbufReadU8(src);
navConfigMutable()->general.max_auto_speed = sbufReadU16(src);
navConfigMutable()->general.max_auto_climb_rate = sbufReadU16(src);
if (mixerConfig()->platformType == PLATFORM_AIRPLANE) {
navConfigMutable()->fw.max_auto_climb_rate = sbufReadU16(src);
} else {
navConfigMutable()->mc.max_auto_climb_rate = sbufReadU16(src);
}
navConfigMutable()->general.max_manual_speed = sbufReadU16(src);
navConfigMutable()->general.max_manual_climb_rate = sbufReadU16(src);
if (mixerConfig()->platformType == PLATFORM_AIRPLANE) {
navConfigMutable()->fw.max_manual_climb_rate = sbufReadU16(src);
} else {
navConfigMutable()->mc.max_manual_climb_rate = sbufReadU16(src);
}
navConfigMutable()->mc.max_bank_angle = sbufReadU8(src);
navConfigMutable()->mc.althold_throttle_type = sbufReadU8(src);
currentBatteryProfileMutable->nav.mc.hover_throttle = sbufReadU16(src);
@ -2450,7 +2525,7 @@ static mspResult_e mspFcProcessInCommand(uint16_t cmdMSP, sbuf_t *src)
positionEstimationConfigMutable()->w_xy_gps_p = constrainf(sbufReadU16(src) / 100.0f, 0.0f, 10.0f);
positionEstimationConfigMutable()->w_xy_gps_v = constrainf(sbufReadU16(src) / 100.0f, 0.0f, 10.0f);
gpsConfigMutable()->gpsMinSats = constrain(sbufReadU8(src), 5, 10);
positionEstimationConfigMutable()->use_gps_velned = constrain(sbufReadU8(src), 0, 1);
sbufReadU8(src); // was positionEstimationConfigMutable()->use_gps_velned
} else
return MSP_RESULT_ERROR;
break;
@ -2690,7 +2765,7 @@ static mspResult_e mspFcProcessInCommand(uint16_t cmdMSP, sbuf_t *src)
case MSP_SET_WP:
if (dataSize == 21) {
const uint8_t msp_wp_no = sbufReadU8(src); // get the waypoint number
navWaypoint_t msp_wp;
msp_wp.action = sbufReadU8(src); // action
@ -3194,7 +3269,7 @@ static mspResult_e mspFcProcessInCommand(uint16_t cmdMSP, sbuf_t *src)
fwAutolandApproachConfigMutable(i)->approachAlt = sbufReadU32(src);
fwAutolandApproachConfigMutable(i)->landAlt = sbufReadU32(src);
fwAutolandApproachConfigMutable(i)->approachDirection = sbufReadU8(src);
int16_t head1 = 0, head2 = 0;
if (sbufReadI16Safe(&head1, src)) {
fwAutolandApproachConfigMutable(i)->landApproachHeading1 = head1;
@ -3213,21 +3288,25 @@ static mspResult_e mspFcProcessInCommand(uint16_t cmdMSP, sbuf_t *src)
case MSP2_INAV_EZ_TUNE_SET:
{
if (dataSize == 10) {
ezTuneMutable()->enabled = sbufReadU8(src);
ezTuneMutable()->filterHz = sbufReadU16(src);
ezTuneMutable()->axisRatio = sbufReadU8(src);
ezTuneMutable()->response = sbufReadU8(src);
ezTuneMutable()->damping = sbufReadU8(src);
ezTuneMutable()->stability = sbufReadU8(src);
ezTuneMutable()->aggressiveness = sbufReadU8(src);
ezTuneMutable()->rate = sbufReadU8(src);
ezTuneMutable()->expo = sbufReadU8(src);
ezTuneUpdate();
} else {
if (dataSize < 10 || dataSize > 11) {
return MSP_RESULT_ERROR;
}
ezTuneMutable()->enabled = sbufReadU8(src);
ezTuneMutable()->filterHz = sbufReadU16(src);
ezTuneMutable()->axisRatio = sbufReadU8(src);
ezTuneMutable()->response = sbufReadU8(src);
ezTuneMutable()->damping = sbufReadU8(src);
ezTuneMutable()->stability = sbufReadU8(src);
ezTuneMutable()->aggressiveness = sbufReadU8(src);
ezTuneMutable()->rate = sbufReadU8(src);
ezTuneMutable()->expo = sbufReadU8(src);
if (dataSize == 11) {
ezTuneMutable()->snappiness = sbufReadU8(src);
}
ezTuneUpdate();
}
break;
@ -3244,12 +3323,12 @@ static mspResult_e mspFcProcessInCommand(uint16_t cmdMSP, sbuf_t *src)
((controlRateConfig_t*)currentControlRateProfile)->rateDynamics.correctionEnd = sbufReadU8(src);
((controlRateConfig_t*)currentControlRateProfile)->rateDynamics.weightCenter = sbufReadU8(src);
((controlRateConfig_t*)currentControlRateProfile)->rateDynamics.weightEnd = sbufReadU8(src);
} else {
return MSP_RESULT_ERROR;
}
break;
break;
#endif
#ifdef USE_PROGRAMMING_FRAMEWORK
@ -3521,7 +3600,7 @@ static bool mspParameterGroupsCommand(sbuf_t *dst, sbuf_t *src)
bool isOSDTypeSupportedBySimulator(void)
{
#ifdef USE_OSD
displayPort_t *osdDisplayPort = osdGetDisplayPort();
displayPort_t *osdDisplayPort = osdGetDisplayPort();
return (!!osdDisplayPort && !!osdDisplayPort->vTable->readChar);
#else
return false;
@ -3543,7 +3622,7 @@ void mspWriteSimulatorOSD(sbuf_t *dst)
static uint8_t osdPos_x = 0;
//indicate new format hitl 1.4.0
sbufWriteU8(dst, 255);
sbufWriteU8(dst, 255);
if (isOSDTypeSupportedBySimulator())
{
@ -3748,132 +3827,130 @@ bool mspFCProcessInOutCommand(uint16_t cmdMSP, sbuf_t *dst, sbuf_t *src, mspResu
#endif
#ifdef USE_SIMULATOR
case MSP_SIMULATOR:
tmp_u8 = sbufReadU8(src); // Get the Simulator MSP version
tmp_u8 = sbufReadU8(src); // Get the Simulator MSP version
// Check the MSP version of simulator
if (tmp_u8 != SIMULATOR_MSP_VERSION) {
if (tmp_u8 != SIMULATOR_MSP_VERSION) {
break;
}
simulatorData.flags = sbufReadU8(src);
simulatorData.flags = sbufReadU8(src);
if (!SIMULATOR_HAS_OPTION(HITL_ENABLE)) {
if (ARMING_FLAG(SIMULATOR_MODE_HITL)) { // Just once
DISABLE_ARMING_FLAG(SIMULATOR_MODE_HITL);
if (ARMING_FLAG(SIMULATOR_MODE_HITL)) { // Just once
DISABLE_ARMING_FLAG(SIMULATOR_MODE_HITL);
#ifdef USE_BARO
if ( requestedSensors[SENSOR_INDEX_BARO] != BARO_NONE ) {
baroStartCalibration();
baroStartCalibration();
}
#endif
#ifdef USE_MAG
DISABLE_STATE(COMPASS_CALIBRATED);
compassInit();
DISABLE_STATE(COMPASS_CALIBRATED);
compassInit();
#endif
simulatorData.flags = HITL_RESET_FLAGS;
simulatorData.flags = HITL_RESET_FLAGS;
// Review: Many states were affected. Reboot?
disarm(DISARM_SWITCH); // Disarm to prevent motor output!!!
disarm(DISARM_SWITCH); // Disarm to prevent motor output!!!
}
} else {
if (!ARMING_FLAG(SIMULATOR_MODE_HITL)) { // Just once
if (!ARMING_FLAG(SIMULATOR_MODE_HITL)) { // Just once
#ifdef USE_BARO
if ( requestedSensors[SENSOR_INDEX_BARO] != BARO_NONE ) {
sensorsSet(SENSOR_BARO);
setTaskEnabled(TASK_BARO, true);
DISABLE_ARMING_FLAG(ARMING_DISABLED_HARDWARE_FAILURE);
baroStartCalibration();
baroStartCalibration();
}
#endif
#ifdef USE_MAG
if (compassConfig()->mag_hardware != MAG_NONE) {
sensorsSet(SENSOR_MAG);
ENABLE_STATE(COMPASS_CALIBRATED);
DISABLE_ARMING_FLAG(ARMING_DISABLED_HARDWARE_FAILURE);
mag.magADC[X] = 800;
mag.magADC[Y] = 0;
mag.magADC[Z] = 0;
}
if (compassConfig()->mag_hardware != MAG_NONE) {
sensorsSet(SENSOR_MAG);
ENABLE_STATE(COMPASS_CALIBRATED);
DISABLE_ARMING_FLAG(ARMING_DISABLED_HARDWARE_FAILURE);
mag.magADC[X] = 800;
mag.magADC[Y] = 0;
mag.magADC[Z] = 0;
}
#endif
ENABLE_ARMING_FLAG(SIMULATOR_MODE_HITL);
ENABLE_ARMING_FLAG(SIMULATOR_MODE_HITL);
ENABLE_STATE(ACCELEROMETER_CALIBRATED);
LOG_DEBUG(SYSTEM, "Simulator enabled");
}
LOG_DEBUG(SYSTEM, "Simulator enabled");
}
if (dataSize >= 14) {
if (dataSize >= 14) {
if (feature(FEATURE_GPS) && SIMULATOR_HAS_OPTION(HITL_HAS_NEW_GPS_DATA)) {
gpsSol.fixType = sbufReadU8(src);
gpsSol.hdop = gpsSol.fixType == GPS_NO_FIX ? 9999 : 100;
gpsSol.flags.hasNewData = true;
gpsSol.numSat = sbufReadU8(src);
if (feature(FEATURE_GPS) && SIMULATOR_HAS_OPTION(HITL_HAS_NEW_GPS_DATA)) {
gpsSolDRV.fixType = sbufReadU8(src);
gpsSolDRV.hdop = gpsSolDRV.fixType == GPS_NO_FIX ? 9999 : 100;
gpsSolDRV.numSat = sbufReadU8(src);
if (gpsSol.fixType != GPS_NO_FIX) {
gpsSol.flags.validVelNE = true;
gpsSol.flags.validVelD = true;
gpsSol.flags.validEPE = true;
gpsSol.flags.validTime = false;
if (gpsSolDRV.fixType != GPS_NO_FIX) {
gpsSolDRV.flags.validVelNE = true;
gpsSolDRV.flags.validVelD = true;
gpsSolDRV.flags.validEPE = true;
gpsSolDRV.flags.validTime = false;
gpsSol.llh.lat = sbufReadU32(src);
gpsSol.llh.lon = sbufReadU32(src);
gpsSol.llh.alt = sbufReadU32(src);
gpsSol.groundSpeed = (int16_t)sbufReadU16(src);
gpsSol.groundCourse = (int16_t)sbufReadU16(src);
gpsSolDRV.llh.lat = sbufReadU32(src);
gpsSolDRV.llh.lon = sbufReadU32(src);
gpsSolDRV.llh.alt = sbufReadU32(src);
gpsSolDRV.groundSpeed = (int16_t)sbufReadU16(src);
gpsSolDRV.groundCourse = (int16_t)sbufReadU16(src);
gpsSol.velNED[X] = (int16_t)sbufReadU16(src);
gpsSol.velNED[Y] = (int16_t)sbufReadU16(src);
gpsSol.velNED[Z] = (int16_t)sbufReadU16(src);
gpsSolDRV.velNED[X] = (int16_t)sbufReadU16(src);
gpsSolDRV.velNED[Y] = (int16_t)sbufReadU16(src);
gpsSolDRV.velNED[Z] = (int16_t)sbufReadU16(src);
gpsSol.eph = 100;
gpsSol.epv = 100;
ENABLE_STATE(GPS_FIX);
} else {
sbufAdvance(src, sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint16_t) * 3);
}
gpsSolDRV.eph = 100;
gpsSolDRV.epv = 100;
} else {
sbufAdvance(src, sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint16_t) * 3);
}
// Feed data to navigation
gpsProcessNewSolutionData();
} else {
sbufAdvance(src, sizeof(uint8_t) + sizeof(uint8_t) + sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint16_t) * 3);
}
gpsProcessNewDriverData();
gpsProcessNewSolutionData(false);
} else {
sbufAdvance(src, sizeof(uint8_t) + sizeof(uint8_t) + sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint16_t) * 3);
}
if (!SIMULATOR_HAS_OPTION(HITL_USE_IMU)) {
attitude.values.roll = (int16_t)sbufReadU16(src);
attitude.values.pitch = (int16_t)sbufReadU16(src);
attitude.values.yaw = (int16_t)sbufReadU16(src);
} else {
sbufAdvance(src, sizeof(uint16_t) * XYZ_AXIS_COUNT);
}
if (!SIMULATOR_HAS_OPTION(HITL_USE_IMU)) {
attitude.values.roll = (int16_t)sbufReadU16(src);
attitude.values.pitch = (int16_t)sbufReadU16(src);
attitude.values.yaw = (int16_t)sbufReadU16(src);
} else {
sbufAdvance(src, sizeof(uint16_t) * XYZ_AXIS_COUNT);
}
// Get the acceleration in 1G units
acc.accADCf[X] = ((int16_t)sbufReadU16(src)) / 1000.0f;
acc.accADCf[Y] = ((int16_t)sbufReadU16(src)) / 1000.0f;
acc.accADCf[Z] = ((int16_t)sbufReadU16(src)) / 1000.0f;
acc.accVibeSq[X] = 0.0f;
acc.accVibeSq[Y] = 0.0f;
acc.accVibeSq[Z] = 0.0f;
acc.accADCf[X] = ((int16_t)sbufReadU16(src)) / 1000.0f;
acc.accADCf[Y] = ((int16_t)sbufReadU16(src)) / 1000.0f;
acc.accADCf[Z] = ((int16_t)sbufReadU16(src)) / 1000.0f;
acc.accVibeSq[X] = 0.0f;
acc.accVibeSq[Y] = 0.0f;
acc.accVibeSq[Z] = 0.0f;
// Get the angular velocity in DPS
gyro.gyroADCf[X] = ((int16_t)sbufReadU16(src)) / 16.0f;
gyro.gyroADCf[Y] = ((int16_t)sbufReadU16(src)) / 16.0f;
gyro.gyroADCf[Z] = ((int16_t)sbufReadU16(src)) / 16.0f;
gyro.gyroADCf[X] = ((int16_t)sbufReadU16(src)) / 16.0f;
gyro.gyroADCf[Y] = ((int16_t)sbufReadU16(src)) / 16.0f;
gyro.gyroADCf[Z] = ((int16_t)sbufReadU16(src)) / 16.0f;
if (sensors(SENSOR_BARO)) {
baro.baroPressure = (int32_t)sbufReadU32(src);
baro.baroTemperature = DEGREES_TO_CENTIDEGREES(SIMULATOR_BARO_TEMP);
} else {
sbufAdvance(src, sizeof(uint32_t));
}
if (sensors(SENSOR_BARO)) {
baro.baroPressure = (int32_t)sbufReadU32(src);
baro.baroTemperature = DEGREES_TO_CENTIDEGREES(SIMULATOR_BARO_TEMP);
} else {
sbufAdvance(src, sizeof(uint32_t));
}
if (sensors(SENSOR_MAG)) {
mag.magADC[X] = ((int16_t)sbufReadU16(src)) / 20; // 16000 / 20 = 800uT
mag.magADC[Y] = ((int16_t)sbufReadU16(src)) / 20; //note that mag failure is simulated by setting all readings to zero
mag.magADC[Z] = ((int16_t)sbufReadU16(src)) / 20;
} else {
sbufAdvance(src, sizeof(uint16_t) * XYZ_AXIS_COUNT);
}
if (sensors(SENSOR_MAG)) {
mag.magADC[X] = ((int16_t)sbufReadU16(src)) / 20; // 16000 / 20 = 800uT
mag.magADC[Y] = ((int16_t)sbufReadU16(src)) / 20; //note that mag failure is simulated by setting all readings to zero
mag.magADC[Z] = ((int16_t)sbufReadU16(src)) / 20;
} else {
sbufAdvance(src, sizeof(uint16_t) * XYZ_AXIS_COUNT);
}
if (SIMULATOR_HAS_OPTION(HITL_EXT_BATTERY_VOLTAGE)) {
simulatorData.vbat = sbufReadU8(src);
@ -3883,7 +3960,7 @@ bool mspFCProcessInOutCommand(uint16_t cmdMSP, sbuf_t *dst, sbuf_t *src, mspResu
if (SIMULATOR_HAS_OPTION(HITL_AIRSPEED)) {
simulatorData.airSpeed = sbufReadU16(src);
} else {
} else {
if (SIMULATOR_HAS_OPTION(HITL_EXTENDED_FLAGS)) {
sbufReadU16(src);
}
@ -3892,35 +3969,35 @@ bool mspFCProcessInOutCommand(uint16_t cmdMSP, sbuf_t *dst, sbuf_t *src, mspResu
if (SIMULATOR_HAS_OPTION(HITL_EXTENDED_FLAGS)) {
simulatorData.flags |= ((uint16_t)sbufReadU8(src)) << 8;
}
} else {
DISABLE_STATE(GPS_FIX);
}
}
} else {
DISABLE_STATE(GPS_FIX);
}
}
sbufWriteU16(dst, (uint16_t)simulatorData.input[INPUT_STABILIZED_ROLL]);
sbufWriteU16(dst, (uint16_t)simulatorData.input[INPUT_STABILIZED_PITCH]);
sbufWriteU16(dst, (uint16_t)simulatorData.input[INPUT_STABILIZED_YAW]);
sbufWriteU16(dst, (uint16_t)(ARMING_FLAG(ARMED) ? simulatorData.input[INPUT_STABILIZED_THROTTLE] : -500));
sbufWriteU16(dst, (uint16_t)simulatorData.input[INPUT_STABILIZED_ROLL]);
sbufWriteU16(dst, (uint16_t)simulatorData.input[INPUT_STABILIZED_PITCH]);
sbufWriteU16(dst, (uint16_t)simulatorData.input[INPUT_STABILIZED_YAW]);
sbufWriteU16(dst, (uint16_t)(ARMING_FLAG(ARMED) ? simulatorData.input[INPUT_STABILIZED_THROTTLE] : -500));
simulatorData.debugIndex++;
if (simulatorData.debugIndex == 8) {
simulatorData.debugIndex = 0;
}
simulatorData.debugIndex++;
if (simulatorData.debugIndex == 8) {
simulatorData.debugIndex = 0;
}
tmp_u8 = simulatorData.debugIndex |
((mixerConfig()->platformType == PLATFORM_AIRPLANE) ? 128 : 0) |
(ARMING_FLAG(ARMED) ? 64 : 0) |
(!feature(FEATURE_OSD) ? 32: 0) |
(!isOSDTypeSupportedBySimulator() ? 16 : 0);
tmp_u8 = simulatorData.debugIndex |
((mixerConfig()->platformType == PLATFORM_AIRPLANE) ? 128 : 0) |
(ARMING_FLAG(ARMED) ? 64 : 0) |
(!feature(FEATURE_OSD) ? 32: 0) |
(!isOSDTypeSupportedBySimulator() ? 16 : 0);
sbufWriteU8(dst, tmp_u8);
sbufWriteU32(dst, debug[simulatorData.debugIndex]);
sbufWriteU8(dst, tmp_u8);
sbufWriteU32(dst, debug[simulatorData.debugIndex]);
sbufWriteU16(dst, attitude.values.roll);
sbufWriteU16(dst, attitude.values.pitch);
sbufWriteU16(dst, attitude.values.yaw);
sbufWriteU16(dst, attitude.values.roll);
sbufWriteU16(dst, attitude.values.pitch);
sbufWriteU16(dst, attitude.values.yaw);
mspWriteSimulatorOSD(dst);
mspWriteSimulatorOSD(dst);
*ret = MSP_RESULT_ACK;
break;
@ -3960,8 +4037,8 @@ bool mspFCProcessInOutCommand(uint16_t cmdMSP, sbuf_t *dst, sbuf_t *src, mspResu
*ret = MSP_RESULT_ERROR;
}
break;
#endif
#endif
default:
// Not handled
return false;

View file

@ -76,7 +76,6 @@ static const box_t boxes[CHECKBOX_ITEM_COUNT + 1] = {
{ .boxId = BOXTURNASSIST, .boxName = "TURN ASSIST", .permanentId = 35 },
{ .boxId = BOXNAVLAUNCH, .boxName = "NAV LAUNCH", .permanentId = 36 },
{ .boxId = BOXAUTOTRIM, .boxName = "SERVO AUTOTRIM", .permanentId = 37 },
{ .boxId = BOXKILLSWITCH, .boxName = "KILLSWITCH", .permanentId = 38 },
{ .boxId = BOXCAMERA1, .boxName = "CAMERA CONTROL 1", .permanentId = 39 },
{ .boxId = BOXCAMERA2, .boxName = "CAMERA CONTROL 2", .permanentId = 40 },
{ .boxId = BOXCAMERA3, .boxName = "CAMERA CONTROL 3", .permanentId = 41 },
@ -214,9 +213,9 @@ void initActiveBoxIds(void)
ADD_ACTIVE_BOX(BOXFPVANGLEMIX);
}
bool navReadyAltControl = sensors(SENSOR_BARO);
bool navReadyAltControl = getHwBarometerStatus() != HW_SENSOR_NONE;
#ifdef USE_GPS
navReadyAltControl = navReadyAltControl || (feature(FEATURE_GPS) && (STATE(AIRPLANE) || positionEstimationConfig()->use_gps_no_baro));
navReadyAltControl = navReadyAltControl || feature(FEATURE_GPS);
const bool navFlowDeadReckoning = sensors(SENSOR_OPFLOW) && sensors(SENSOR_ACC) && positionEstimationConfig()->allow_dead_reckoning;
bool navReadyPosControl = sensors(SENSOR_ACC) && feature(FEATURE_GPS);
@ -317,7 +316,6 @@ void initActiveBoxIds(void)
}
#endif
ADD_ACTIVE_BOX(BOXKILLSWITCH);
ADD_ACTIVE_BOX(BOXFAILSAFE);
#if defined(USE_RCDEVICE) || defined(USE_MSP_DISPLAYPORT)
@ -402,7 +400,6 @@ void packBoxModeFlags(boxBitmask_t * mspBoxModeFlags)
CHECK_ACTIVE_BOX(IS_ENABLED(FLIGHT_MODE(NAV_LAUNCH_MODE)), BOXNAVLAUNCH);
CHECK_ACTIVE_BOX(IS_ENABLED(FLIGHT_MODE(AUTO_TUNE)), BOXAUTOTUNE);
CHECK_ACTIVE_BOX(IS_ENABLED(IS_RC_MODE_ACTIVE(BOXAUTOTRIM)), BOXAUTOTRIM);
CHECK_ACTIVE_BOX(IS_ENABLED(IS_RC_MODE_ACTIVE(BOXKILLSWITCH)), BOXKILLSWITCH);
CHECK_ACTIVE_BOX(IS_ENABLED(IS_RC_MODE_ACTIVE(BOXHOMERESET)), BOXHOMERESET);
CHECK_ACTIVE_BOX(IS_ENABLED(IS_RC_MODE_ACTIVE(BOXCAMERA1)), BOXCAMERA1);
CHECK_ACTIVE_BOX(IS_ENABLED(IS_RC_MODE_ACTIVE(BOXCAMERA2)), BOXCAMERA2);

View file

@ -69,6 +69,7 @@
#include "io/osd_dji_hd.h"
#include "io/displayport_msp_osd.h"
#include "io/servo_sbus.h"
#include "io/adsb.h"
#include "msp/msp_serial.h"
@ -92,6 +93,10 @@
#include "config/feature.h"
#if defined(SITL_BUILD)
#include "target/SITL/serial_proxy.h"
#endif
void taskHandleSerial(timeUs_t currentTimeUs)
{
UNUSED(currentTimeUs);
@ -181,6 +186,14 @@ void taskUpdateCompass(timeUs_t currentTimeUs)
}
#endif
#ifdef USE_ADSB
void taskAdsb(timeUs_t currentTimeUs)
{
UNUSED(currentTimeUs);
adsbTtlClean(currentTimeUs);
}
#endif
#ifdef USE_BARO
void taskUpdateBaro(timeUs_t currentTimeUs)
{
@ -360,6 +373,9 @@ void fcTasksInit(void)
#ifdef USE_PITOT
setTaskEnabled(TASK_PITOT, sensors(SENSOR_PITOT));
#endif
#ifdef USE_ADSB
setTaskEnabled(TASK_ADSB, true);
#endif
#ifdef USE_RANGEFINDER
setTaskEnabled(TASK_RANGEFINDER, sensors(SENSOR_RANGEFINDER));
#endif
@ -409,6 +425,10 @@ void fcTasksInit(void)
#if defined(USE_SMARTPORT_MASTER)
setTaskEnabled(TASK_SMARTPORT_MASTER, true);
#endif
#if defined(SITL_BUILD)
serialProxyStart();
#endif
}
cfTask_t cfTasks[TASK_COUNT] = {
@ -495,6 +515,15 @@ cfTask_t cfTasks[TASK_COUNT] = {
},
#endif
#ifdef USE_ADSB
[TASK_ADSB] = {
.taskName = "ADSB",
.taskFunc = taskAdsb,
.desiredPeriod = TASK_PERIOD_HZ(1), // ADSB is updated at 1 Hz
.staticPriority = TASK_PRIORITY_IDLE,
},
#endif
#ifdef USE_BARO
[TASK_BARO] = {
.taskName = "BARO",

View file

@ -24,6 +24,8 @@
#pragma once
#include <stdbool.h>
#ifdef USE_MULTI_FUNCTIONS
extern uint8_t multiFunctionFlags;

View file

@ -75,24 +75,23 @@ stickPositions_e rcStickPositions;
FASTRAM int16_t rcCommand[4]; // interval [1000;2000] for THROTTLE and [-500;+500] for ROLL/PITCH/YAW
PG_REGISTER_WITH_RESET_TEMPLATE(rcControlsConfig_t, rcControlsConfig, PG_RC_CONTROLS_CONFIG, 3);
PG_REGISTER_WITH_RESET_TEMPLATE(rcControlsConfig_t, rcControlsConfig, PG_RC_CONTROLS_CONFIG, 4);
PG_RESET_TEMPLATE(rcControlsConfig_t, rcControlsConfig,
.deadband = SETTING_DEADBAND_DEFAULT,
.yaw_deadband = SETTING_YAW_DEADBAND_DEFAULT,
.pos_hold_deadband = SETTING_POS_HOLD_DEADBAND_DEFAULT,
.control_deadband = SETTING_CONTROL_DEADBAND_DEFAULT,
.alt_hold_deadband = SETTING_ALT_HOLD_DEADBAND_DEFAULT,
.mid_throttle_deadband = SETTING_3D_DEADBAND_THROTTLE_DEFAULT,
.airmodeHandlingType = SETTING_AIRMODE_TYPE_DEFAULT,
.airmodeThrottleThreshold = SETTING_AIRMODE_THROTTLE_THRESHOLD_DEFAULT,
);
PG_REGISTER_WITH_RESET_TEMPLATE(armingConfig_t, armingConfig, PG_ARMING_CONFIG, 2);
PG_REGISTER_WITH_RESET_TEMPLATE(armingConfig_t, armingConfig, PG_ARMING_CONFIG, 3);
PG_RESET_TEMPLATE(armingConfig_t, armingConfig,
.fixed_wing_auto_arm = SETTING_FIXED_WING_AUTO_ARM_DEFAULT,
.disarm_kill_switch = SETTING_DISARM_KILL_SWITCH_DEFAULT,
.disarm_always = SETTING_DISARM_ALWAYS_DEFAULT,
.switchDisarmDelayMs = SETTING_SWITCH_DISARM_DELAY_DEFAULT,
.prearmTimeoutMs = SETTING_PREARM_TIMEOUT_DEFAULT,
);
@ -104,7 +103,7 @@ bool areSticksInApModePosition(uint16_t ap_mode)
bool areSticksDeflected(void)
{
return (ABS(rcCommand[ROLL]) > rcControlsConfig()->control_deadband) || (ABS(rcCommand[PITCH]) > rcControlsConfig()->control_deadband) || (ABS(rcCommand[YAW]) > rcControlsConfig()->control_deadband);
return (ABS(rcCommand[ROLL]) > CONTROL_DEADBAND) || (ABS(rcCommand[PITCH]) > CONTROL_DEADBAND) || (ABS(rcCommand[YAW]) > CONTROL_DEADBAND);
}
bool isRollPitchStickDeflected(uint8_t deadband)
@ -232,7 +231,7 @@ void processRcStickPositions(bool isThrottleLow)
if (ARMING_FLAG(ARMED) && !IS_RC_MODE_ACTIVE(BOXFAILSAFE) && rxIsReceivingSignal() && !failsafeIsActive()) {
const timeMs_t disarmDelay = currentTimeMs - rcDisarmTimeMs;
if (disarmDelay > armingConfig()->switchDisarmDelayMs) {
if (armingConfig()->disarm_kill_switch || isThrottleLow) {
if (armingConfig()->disarm_always || isThrottleLow) {
disarm(DISARM_SWITCH);
}
}
@ -241,11 +240,6 @@ void processRcStickPositions(bool isThrottleLow)
rcDisarmTimeMs = currentTimeMs;
}
}
// KILLSWITCH disarms instantly
if (IS_RC_MODE_ACTIVE(BOXKILLSWITCH)) {
disarm(DISARM_KILLSWITCH);
}
}
if (rcDelayCommand != 20) {

View file

@ -19,7 +19,7 @@
#include "config/parameter_group.h"
#define AIRMODE_THROTTLE_THRESHOLD 1300
#define CONTROL_DEADBAND 10 // Used to check if sticks are centered
typedef enum rc_alias {
ROLL = 0,
@ -85,7 +85,6 @@ typedef struct rcControlsConfig_s {
uint8_t deadband; // introduce a deadband around the stick center for pitch and roll axis. Must be greater than zero.
uint8_t yaw_deadband; // introduce a deadband around the stick center for yaw axis. Must be greater than zero.
uint8_t pos_hold_deadband; // Deadband for position hold
uint8_t control_deadband; // General deadband to check if sticks are deflected, us PWM.
uint8_t alt_hold_deadband; // Defines the neutral zone of throttle stick during altitude hold
uint16_t mid_throttle_deadband; // default throttle deadband from MIDRC
uint8_t airmodeHandlingType; // Defaults to ANTI_WINDUP triggered at sticks centered
@ -96,7 +95,7 @@ PG_DECLARE(rcControlsConfig_t, rcControlsConfig);
typedef struct armingConfig_s {
bool fixed_wing_auto_arm; // Auto-arm fixed wing aircraft on throttle up and never disarm
bool disarm_kill_switch; // allow disarm via AUX switch regardless of throttle value
bool disarm_always; // Disarm motors regardless of throttle value
uint16_t switchDisarmDelayMs; // additional delay between ARM box going off and actual disarm
uint16_t prearmTimeoutMs; // duration for which Prearm being activated is valid. after this, Prearm needs to be reset. 0 means Prearm does not timeout.
} armingConfig_t;

View file

@ -39,7 +39,7 @@ int16_t lookupThrottleRCMid; // THROTTLE curve mid point
void generateThrottleCurve(const controlRateConfig_t *controlRateConfig)
{
const int minThrottle = getThrottleIdleValue();
lookupThrottleRCMid = minThrottle + (int32_t)(motorConfig()->maxthrottle - minThrottle) * controlRateConfig->throttle.rcMid8 / 100; // [MINTHROTTLE;MAXTHROTTLE]
lookupThrottleRCMid = minThrottle + (int32_t)(getMaxThrottle() - minThrottle) * controlRateConfig->throttle.rcMid8 / 100; // [MINTHROTTLE;MAXTHROTTLE]
for (int i = 0; i < THROTTLE_LOOKUP_LENGTH; i++) {
const int16_t tmp = 10 * i - controlRateConfig->throttle.rcMid8;
@ -49,7 +49,7 @@ void generateThrottleCurve(const controlRateConfig_t *controlRateConfig)
if (tmp < 0)
y = controlRateConfig->throttle.rcMid8;
lookupThrottleRC[i] = 10 * controlRateConfig->throttle.rcMid8 + tmp * (100 - controlRateConfig->throttle.rcExpo8 + (int32_t) controlRateConfig->throttle.rcExpo8 * (tmp * tmp) / (y * y)) / 10;
lookupThrottleRC[i] = minThrottle + (int32_t) (motorConfig()->maxthrottle - minThrottle) * lookupThrottleRC[i] / 1000; // [MINTHROTTLE;MAXTHROTTLE]
lookupThrottleRC[i] = minThrottle + (int32_t) (getMaxThrottle() - minThrottle) * lookupThrottleRC[i] / 1000; // [MINTHROTTLE;MAXTHROTTLE]
}
}
@ -62,7 +62,7 @@ int16_t rcLookup(int32_t stickDeflection, uint8_t expo)
uint16_t rcLookupThrottle(uint16_t absoluteDeflection)
{
if (absoluteDeflection > 999)
return motorConfig()->maxthrottle;
return getMaxThrottle();
const uint8_t lookupStep = absoluteDeflection / 100;
return lookupThrottleRC[lookupStep] + (absoluteDeflection - lookupStep * 100) * (lookupThrottleRC[lookupStep + 1] - lookupThrottleRC[lookupStep]) / 100;

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