mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-06-17 15:50:05 +08:00
Compare commits
29 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 18a5bb32bc | |||
| ad0482155e | |||
| d300a879f1 | |||
| e77b4418a5 | |||
| 05a2d4d5a9 | |||
| d9e31d67aa | |||
| b7e563bdbe | |||
| 596da5b7d3 | |||
| 2f73115b54 | |||
| bf311ed77d | |||
| 63a53d48e7 | |||
| c8ec6b3d08 | |||
| 3b27864e53 | |||
| 3ac8c23dd0 | |||
| 6215e6c7ec | |||
| e87a6c755d | |||
| 69e0c2fc10 | |||
| e4ee7c7d98 | |||
| 541697d193 | |||
| c49c8932de | |||
| 0c926250a2 | |||
| dfb4ec56b1 | |||
| f15eefcc95 | |||
| 29730e30fa | |||
| ac97b5520c | |||
| 648a21f11d | |||
| d3fd03a014 | |||
| b1e0702657 | |||
| 8d82560308 |
@@ -468,26 +468,27 @@ validate_module_configs:
|
|||||||
.PHONY: clean submodulesclean submodulesupdate gazeboclean distclean
|
.PHONY: clean submodulesclean submodulesupdate gazeboclean distclean
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
@rm -rf "$(SRC_DIR)"/build
|
@find "$(SRC_DIR)/build" -mindepth 1 -maxdepth 1 -type d -exec sh -c "echo {}; cmake --build {} -- clean || rm -rf {}" \; # use generated build system to clean, wipe build directory if it fails
|
||||||
@git submodule foreach git clean -df
|
@git submodule foreach git clean -dX --force # some submodules generate build artifacts in source
|
||||||
|
|
||||||
submodulesclean:
|
submodulesclean:
|
||||||
@git submodule foreach --quiet --recursive git clean -ff -x -d
|
@git submodule foreach --quiet --recursive git clean -ff -x -d
|
||||||
@git submodule update --quiet --init --recursive --force || true
|
@git submodule update --quiet --init --recursive --force || true
|
||||||
@git submodule sync --recursive
|
@git submodule sync --recursive
|
||||||
@git submodule update --init --recursive --force
|
@git submodule update --init --recursive --force --jobs 4
|
||||||
|
|
||||||
submodulesupdate:
|
submodulesupdate:
|
||||||
@git submodule update --quiet --init --recursive || true
|
@git submodule update --quiet --init --recursive --jobs 4 || true
|
||||||
@git submodule sync --recursive
|
@git submodule sync --recursive
|
||||||
@git submodule update --init --recursive
|
@git submodule update --init --recursive --jobs 4
|
||||||
|
|
||||||
gazeboclean:
|
gazeboclean:
|
||||||
@rm -rf ~/.gazebo/*
|
@rm -rf ~/.gazebo/*
|
||||||
|
|
||||||
distclean: gazeboclean
|
distclean: gazeboclean
|
||||||
@git submodule deinit -f .
|
@git submodule deinit --force $(SRC_DIR)
|
||||||
@git clean -ff -x -d -e ".cproject" -e ".idea" -e ".project" -e ".settings" -e ".vscode"
|
@rm -rf "$(SRC_DIR)/build"
|
||||||
|
@git clean --force -X "$(SRC_DIR)/msg/" "$(SRC_DIR)/platforms/" "$(SRC_DIR)/posix-configs/" "$(SRC_DIR)/ROMFS/" "$(SRC_DIR)/src/" "$(SRC_DIR)/test/" "$(SRC_DIR)/Tools/"
|
||||||
|
|
||||||
# Help / Error
|
# Help / Error
|
||||||
# --------------------------------------------------------------------
|
# --------------------------------------------------------------------
|
||||||
|
|||||||
@@ -115,6 +115,7 @@ add_custom_command(
|
|||||||
set(romfs_extract_stamp ${CMAKE_CURRENT_BINARY_DIR}/romfs_extract.stamp)
|
set(romfs_extract_stamp ${CMAKE_CURRENT_BINARY_DIR}/romfs_extract.stamp)
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
OUTPUT ${romfs_extract_stamp}
|
OUTPUT ${romfs_extract_stamp}
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E remove_directory ${romfs_gen_root_dir}/*
|
||||||
COMMAND ${CMAKE_COMMAND} -E tar xf ${romfs_tar_file}
|
COMMAND ${CMAKE_COMMAND} -E tar xf ${romfs_tar_file}
|
||||||
COMMAND ${CMAKE_COMMAND} -E touch ${romfs_extract_stamp}
|
COMMAND ${CMAKE_COMMAND} -E touch ${romfs_extract_stamp}
|
||||||
WORKING_DIRECTORY ${romfs_gen_root_dir}
|
WORKING_DIRECTORY ${romfs_gen_root_dir}
|
||||||
|
|||||||
@@ -14,7 +14,8 @@
|
|||||||
|
|
||||||
param set-default EKF2_ARSP_THR 8
|
param set-default EKF2_ARSP_THR 8
|
||||||
param set-default EKF2_FUSE_BETA 1
|
param set-default EKF2_FUSE_BETA 1
|
||||||
param set-default ASPD_STALL 10.0
|
|
||||||
|
param set-default FW_AIRSPD_STALL 8
|
||||||
|
|
||||||
param set-default FW_P_RMAX_NEG 20.0
|
param set-default FW_P_RMAX_NEG 20.0
|
||||||
param set-default FW_P_RMAX_POS 60.0
|
param set-default FW_P_RMAX_POS 60.0
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ set FRC /fs/microsd/etc/rc.txt
|
|||||||
set IOFW "/etc/extras/px4_io-v2_default.bin"
|
set IOFW "/etc/extras/px4_io-v2_default.bin"
|
||||||
set IO_PRESENT no
|
set IO_PRESENT no
|
||||||
set LOGGER_ARGS ""
|
set LOGGER_ARGS ""
|
||||||
set LOGGER_BUF 14
|
set LOGGER_BUF 8
|
||||||
set MAV_TYPE none
|
set MAV_TYPE none
|
||||||
set MIXER none
|
set MIXER none
|
||||||
set MIXER_AUX none
|
set MIXER_AUX none
|
||||||
|
|||||||
+1
-1
Submodule Tools/sitl_gazebo updated: 4c27fc7dd6...2496b85dd2
@@ -63,7 +63,7 @@ CONFIG_HAVE_CXXINITIALIZE=y
|
|||||||
CONFIG_I2C_RESET=y
|
CONFIG_I2C_RESET=y
|
||||||
CONFIG_IDLETHREAD_STACKSIZE=750
|
CONFIG_IDLETHREAD_STACKSIZE=750
|
||||||
CONFIG_IOB_NBUFFERS=48
|
CONFIG_IOB_NBUFFERS=48
|
||||||
CONFIG_IOB_NCHAINS=16
|
CONFIG_IOB_NCHAINS=18
|
||||||
CONFIG_KINETIS_ADC0=y
|
CONFIG_KINETIS_ADC0=y
|
||||||
CONFIG_KINETIS_ADC1=y
|
CONFIG_KINETIS_ADC1=y
|
||||||
CONFIG_KINETIS_CRC=y
|
CONFIG_KINETIS_CRC=y
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ CONFIG_I2C_RESET=y
|
|||||||
CONFIG_IDLETHREAD_STACKSIZE=750
|
CONFIG_IDLETHREAD_STACKSIZE=750
|
||||||
CONFIG_LIBC_FLOATINGPOINT=y
|
CONFIG_LIBC_FLOATINGPOINT=y
|
||||||
CONFIG_LIBC_LONG_LONG=y
|
CONFIG_LIBC_LONG_LONG=y
|
||||||
CONFIG_LIBC_STRERROR=y
|
CONFIG_LIBC_STRERROR=n
|
||||||
CONFIG_LIBC_STRERROR_SHORT=y
|
CONFIG_LIBC_STRERROR_SHORT=y
|
||||||
CONFIG_MEMSET_64BIT=y
|
CONFIG_MEMSET_64BIT=y
|
||||||
CONFIG_MEMSET_OPTSPEED=y
|
CONFIG_MEMSET_OPTSPEED=y
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ px4_add_board(
|
|||||||
imu/bosch/bmi088
|
imu/bosch/bmi088
|
||||||
imu/invensense/icm20602
|
imu/invensense/icm20602
|
||||||
imu/invensense/icm20948 # required for ak09916 mag
|
imu/invensense/icm20948 # required for ak09916 mag
|
||||||
|
imu/invensense/icm20649
|
||||||
imu/invensense/icm42688p
|
imu/invensense/icm42688p
|
||||||
irlock
|
irlock
|
||||||
lights # all available light drivers
|
lights # all available light drivers
|
||||||
|
|||||||
@@ -8,13 +8,19 @@ board_adc start
|
|||||||
ina226 -X -b 1 -t 1 -k start
|
ina226 -X -b 1 -t 1 -k start
|
||||||
ina226 -X -b 2 -t 2 -k start
|
ina226 -X -b 2 -t 2 -k start
|
||||||
|
|
||||||
if ver hwtypecmp V5X90 V5X91 V5Xa0 V5Xa1
|
if ver hwtypecmp V5X90 V5X91 V5X92 V5Xa0 V5Xa1 V5Xa2
|
||||||
then
|
then
|
||||||
#SKYNODE base fmu board orientation
|
#SKYNODE base fmu board orientation
|
||||||
|
|
||||||
# Internal SPI BMI088
|
if ver hwtypecmp V5X90 V5X91 V5Xa0 V5Xa1
|
||||||
bmi088 -A -R 2 -s start
|
then
|
||||||
bmi088 -G -R 2 -s start
|
# Internal SPI BMI088
|
||||||
|
bmi088 -A -R 2 -s start
|
||||||
|
bmi088 -G -R 2 -s start
|
||||||
|
else
|
||||||
|
# Internal SPI bus ICM20649
|
||||||
|
icm20649 -s -R 4 start
|
||||||
|
fi
|
||||||
|
|
||||||
# Internal SPI bus ICM42688p
|
# Internal SPI bus ICM42688p
|
||||||
icm42688p -R 4 -s start
|
icm42688p -R 4 -s start
|
||||||
@@ -28,9 +34,15 @@ then
|
|||||||
else
|
else
|
||||||
#FMUv5Xbase board orientation
|
#FMUv5Xbase board orientation
|
||||||
|
|
||||||
# Internal SPI BMI088
|
if ver hwtypecmp V5X00 V5X01
|
||||||
bmi088 -A -R 4 -s start
|
then
|
||||||
bmi088 -G -R 4 -s start
|
# Internal SPI BMI088
|
||||||
|
bmi088 -A -R 4 -s start
|
||||||
|
bmi088 -G -R 4 -s start
|
||||||
|
else
|
||||||
|
# Internal SPI bus ICM20649
|
||||||
|
icm20649 -s -R 6 start
|
||||||
|
fi
|
||||||
|
|
||||||
# Internal SPI bus ICM42688p
|
# Internal SPI bus ICM42688p
|
||||||
icm42688p -R 6 -s start
|
icm42688p -R 6 -s start
|
||||||
|
|||||||
@@ -185,6 +185,18 @@
|
|||||||
#define HW_INFO_INIT {'V','5','X','x', 'x',0}
|
#define HW_INFO_INIT {'V','5','X','x', 'x',0}
|
||||||
#define HW_INFO_INIT_VER 3 /* Offset in above string of the VER */
|
#define HW_INFO_INIT_VER 3 /* Offset in above string of the VER */
|
||||||
#define HW_INFO_INIT_REV 4 /* Offset in above string of the REV */
|
#define HW_INFO_INIT_REV 4 /* Offset in above string of the REV */
|
||||||
|
#define BOARD_NUM_SPI_CFG_HW_VERSIONS 3
|
||||||
|
// Base FMUM
|
||||||
|
#define V5X00 HW_VER_REV(0x0,0x0) // FMUV5X, Rev 0
|
||||||
|
#define V5X10 HW_VER_REV(0x1,0x0) // NO PX4IO, Rev 0
|
||||||
|
#define V5X01 HW_VER_REV(0x0,0x1) // FMUV5X I2C2 BMP388, Rev 1
|
||||||
|
#define V5X02 HW_VER_REV(0x0,0x2) // FMUV5X, Rev 2
|
||||||
|
#define V5X90 HW_VER_REV(0x9,0x0) // NO USB, Rev 0
|
||||||
|
#define V5X91 HW_VER_REV(0x9,0x1) // NO USB I2C2 BMP388, Rev 1
|
||||||
|
#define V5X92 HW_VER_REV(0x9,0x2) // NO USB I2C2 BMP388, Rev 2
|
||||||
|
#define V5Xa0 HW_VER_REV(0xa,0x0) // NO USB (Q), Rev 0
|
||||||
|
#define V5Xa1 HW_VER_REV(0xa,0x1) // NO USB (Q) I2C2 BMP388, Rev 1
|
||||||
|
#define V5Xa2 HW_VER_REV(0xa,0x2) // NO USB (Q) I2C2 BMP388, Rev 2
|
||||||
|
|
||||||
/* HEATER
|
/* HEATER
|
||||||
* PWM in future
|
* PWM in future
|
||||||
|
|||||||
@@ -175,12 +175,6 @@ stm32_boardinitialize(void)
|
|||||||
const uint32_t gpio[] = PX4_GPIO_INIT_LIST;
|
const uint32_t gpio[] = PX4_GPIO_INIT_LIST;
|
||||||
px4_gpio_init(gpio, arraySize(gpio));
|
px4_gpio_init(gpio, arraySize(gpio));
|
||||||
|
|
||||||
/* configure SPI interfaces (we can do this here as long as we only have a single SPI hw config version -
|
|
||||||
* otherwise we need to move this after board_determine_hw_info()) */
|
|
||||||
static_assert(BOARD_NUM_SPI_CFG_HW_VERSIONS == 1, "Need to move the SPI initialization for multi-version support");
|
|
||||||
|
|
||||||
stm32_spiinitialize();
|
|
||||||
|
|
||||||
/* configure USB interfaces */
|
/* configure USB interfaces */
|
||||||
|
|
||||||
stm32_usbinitialize();
|
stm32_usbinitialize();
|
||||||
@@ -220,7 +214,6 @@ __EXPORT int board_app_initialize(uintptr_t arg)
|
|||||||
VDD_3V3_SD_CARD_EN(true);
|
VDD_3V3_SD_CARD_EN(true);
|
||||||
VDD_5V_PERIPH_EN(true);
|
VDD_5V_PERIPH_EN(true);
|
||||||
VDD_5V_HIPOWER_EN(true);
|
VDD_5V_HIPOWER_EN(true);
|
||||||
board_spi_reset(10, 0xffff);
|
|
||||||
VDD_3V3_SENSORS4_EN(true);
|
VDD_3V3_SENSORS4_EN(true);
|
||||||
VDD_3V3_SPEKTRUM_POWER_EN(true);
|
VDD_3V3_SPEKTRUM_POWER_EN(true);
|
||||||
|
|
||||||
@@ -237,6 +230,9 @@ __EXPORT int board_app_initialize(uintptr_t arg)
|
|||||||
syslog(LOG_ERR, "[boot] Failed to read HW revision and version\n");
|
syslog(LOG_ERR, "[boot] Failed to read HW revision and version\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stm32_spiinitialize();
|
||||||
|
|
||||||
|
board_spi_reset(10, 0xffff);
|
||||||
|
|
||||||
/* configure the DMA allocator */
|
/* configure the DMA allocator */
|
||||||
|
|
||||||
|
|||||||
@@ -111,16 +111,19 @@ static const px4_hw_mft_item_t hw_mft_list_v0509[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static px4_hw_mft_list_entry_t mft_lists[] = {
|
static px4_hw_mft_list_entry_t mft_lists[] = {
|
||||||
{0x0000, hw_mft_list_v0500, arraySize(hw_mft_list_v0500)},
|
// ver_rev
|
||||||
{0x0001, hw_mft_list_v0500, arraySize(hw_mft_list_v0500)},
|
{V5X00, hw_mft_list_v0500, arraySize(hw_mft_list_v0500)}, // FMUV5X, Rev 0
|
||||||
{0x0100, hw_mft_list_v0510, arraySize(hw_mft_list_v0510)},
|
{V5X01, hw_mft_list_v0500, arraySize(hw_mft_list_v0500)}, // FMUV5X, Rev 1
|
||||||
{0x0900, hw_mft_list_v0509, arraySize(hw_mft_list_v0509)},
|
{V5X02, hw_mft_list_v0500, arraySize(hw_mft_list_v0500)}, // FMUV5X, Rev 2
|
||||||
{0x0901, hw_mft_list_v0509, arraySize(hw_mft_list_v0509)},
|
{V5X10, hw_mft_list_v0510, arraySize(hw_mft_list_v0510)}, // NO PX4IO, Rev 0
|
||||||
{0x0a00, hw_mft_list_v0509, arraySize(hw_mft_list_v0509)},
|
{V5X90, hw_mft_list_v0509, arraySize(hw_mft_list_v0509)}, // NO USB, Rev 0
|
||||||
{0x0a01, hw_mft_list_v0509, arraySize(hw_mft_list_v0509)},
|
{V5X91, hw_mft_list_v0509, arraySize(hw_mft_list_v0509)}, // NO USB I2C2 BMP388, Rev 1
|
||||||
|
{V5X92, hw_mft_list_v0509, arraySize(hw_mft_list_v0509)}, // NO USB I2C2 BMP388, Rev 2
|
||||||
|
{V5Xa0, hw_mft_list_v0509, arraySize(hw_mft_list_v0509)}, // NO USB (Q), Rev 0
|
||||||
|
{V5Xa1, hw_mft_list_v0509, arraySize(hw_mft_list_v0509)}, // NO USB (Q) I2C2 BMP388, Rev 1
|
||||||
|
{V5Xa2, hw_mft_list_v0509, arraySize(hw_mft_list_v0509)}, // NO USB (Q) I2C2 BMP388, Rev 2
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/************************************************************************************
|
/************************************************************************************
|
||||||
* Name: board_query_manifest
|
* Name: board_query_manifest
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -35,28 +35,77 @@
|
|||||||
#include <drivers/drv_sensor.h>
|
#include <drivers/drv_sensor.h>
|
||||||
#include <nuttx/spi/spi.h>
|
#include <nuttx/spi/spi.h>
|
||||||
|
|
||||||
constexpr px4_spi_bus_t px4_spi_buses[SPI_BUS_MAX_BUS_ITEMS] = {
|
constexpr px4_spi_bus_all_hw_t px4_spi_buses_all_hw[BOARD_NUM_SPI_CFG_HW_VERSIONS] = {
|
||||||
initSPIBus(SPI::Bus::SPI1, {
|
initSPIHWVersion(HW_VER_REV(0, 0), {
|
||||||
initSPIDevice(DRV_IMU_DEVTYPE_ICM20602, SPI::CS{GPIO::PortI, GPIO::Pin9}, SPI::DRDY{GPIO::PortF, GPIO::Pin2}),
|
initSPIBus(SPI::Bus::SPI1, {
|
||||||
}, {GPIO::PortI, GPIO::Pin11}),
|
initSPIDevice(DRV_IMU_DEVTYPE_ICM20602, SPI::CS{GPIO::PortI, GPIO::Pin9}, SPI::DRDY{GPIO::PortF, GPIO::Pin2}),
|
||||||
initSPIBus(SPI::Bus::SPI2, {
|
}, {GPIO::PortI, GPIO::Pin11}),
|
||||||
initSPIDevice(DRV_IMU_DEVTYPE_ICM42688P, SPI::CS{GPIO::PortH, GPIO::Pin5}, SPI::DRDY{GPIO::PortH, GPIO::Pin12}),
|
initSPIBus(SPI::Bus::SPI2, {
|
||||||
}, {GPIO::PortD, GPIO::Pin15}),
|
initSPIDevice(DRV_IMU_DEVTYPE_ICM42688P, SPI::CS{GPIO::PortH, GPIO::Pin5}, SPI::DRDY{GPIO::PortH, GPIO::Pin12}),
|
||||||
initSPIBus(SPI::Bus::SPI3, {
|
}, {GPIO::PortD, GPIO::Pin15}),
|
||||||
initSPIDevice(DRV_GYR_DEVTYPE_BMI088, SPI::CS{GPIO::PortI, GPIO::Pin8}, SPI::DRDY{GPIO::PortI, GPIO::Pin7}),
|
initSPIBus(SPI::Bus::SPI3, {
|
||||||
initSPIDevice(DRV_ACC_DEVTYPE_BMI088, SPI::CS{GPIO::PortI, GPIO::Pin4}),
|
initSPIDevice(DRV_GYR_DEVTYPE_BMI088, SPI::CS{GPIO::PortI, GPIO::Pin8}, SPI::DRDY{GPIO::PortI, GPIO::Pin7}),
|
||||||
}, {GPIO::PortE, GPIO::Pin7}),
|
initSPIDevice(DRV_ACC_DEVTYPE_BMI088, SPI::CS{GPIO::PortI, GPIO::Pin4}),
|
||||||
// initSPIBus(SPI::Bus::SPI4, {
|
}, {GPIO::PortE, GPIO::Pin7}),
|
||||||
// // no devices
|
// initSPIBus(SPI::Bus::SPI4, {
|
||||||
// TODO: if enabled, remove GPIO_VDD_3V3_SENSORS4_EN from board_config.h
|
// // no devices
|
||||||
// }, {GPIO::PortG, GPIO::Pin8}),
|
// TODO: if enabled, remove GPIO_VDD_3V3_SENSORS4_EN from board_config.h
|
||||||
initSPIBus(SPI::Bus::SPI5, {
|
// }, {GPIO::PortG, GPIO::Pin8}),
|
||||||
initSPIDevice(SPIDEV_FLASH(0), SPI::CS{GPIO::PortG, GPIO::Pin7})
|
initSPIBus(SPI::Bus::SPI5, {
|
||||||
|
initSPIDevice(SPIDEV_FLASH(0), SPI::CS{GPIO::PortG, GPIO::Pin7})
|
||||||
|
}),
|
||||||
|
initSPIBusExternal(SPI::Bus::SPI6, {
|
||||||
|
initSPIConfigExternal(SPI::CS{GPIO::PortI, GPIO::Pin10}, SPI::DRDY{GPIO::PortD, GPIO::Pin11}),
|
||||||
|
initSPIConfigExternal(SPI::CS{GPIO::PortA, GPIO::Pin15}, SPI::DRDY{GPIO::PortD, GPIO::Pin12}),
|
||||||
|
}),
|
||||||
}),
|
}),
|
||||||
initSPIBusExternal(SPI::Bus::SPI6, {
|
|
||||||
initSPIConfigExternal(SPI::CS{GPIO::PortI, GPIO::Pin10}, SPI::DRDY{GPIO::PortD, GPIO::Pin11}),
|
initSPIHWVersion(HW_VER_REV(0, 1), {
|
||||||
initSPIConfigExternal(SPI::CS{GPIO::PortA, GPIO::Pin15}, SPI::DRDY{GPIO::PortD, GPIO::Pin12}),
|
initSPIBus(SPI::Bus::SPI1, {
|
||||||
|
initSPIDevice(DRV_IMU_DEVTYPE_ICM20602, SPI::CS{GPIO::PortI, GPIO::Pin9}, SPI::DRDY{GPIO::PortF, GPIO::Pin2}),
|
||||||
|
}, {GPIO::PortI, GPIO::Pin11}),
|
||||||
|
initSPIBus(SPI::Bus::SPI2, {
|
||||||
|
initSPIDevice(DRV_IMU_DEVTYPE_ICM42688P, SPI::CS{GPIO::PortH, GPIO::Pin5}, SPI::DRDY{GPIO::PortH, GPIO::Pin12}),
|
||||||
|
}, {GPIO::PortD, GPIO::Pin15}),
|
||||||
|
initSPIBus(SPI::Bus::SPI3, {
|
||||||
|
initSPIDevice(DRV_GYR_DEVTYPE_BMI088, SPI::CS{GPIO::PortI, GPIO::Pin8}, SPI::DRDY{GPIO::PortI, GPIO::Pin7}),
|
||||||
|
initSPIDevice(DRV_ACC_DEVTYPE_BMI088, SPI::CS{GPIO::PortI, GPIO::Pin4}),
|
||||||
|
}, {GPIO::PortE, GPIO::Pin7}),
|
||||||
|
// initSPIBus(SPI::Bus::SPI4, {
|
||||||
|
// // no devices
|
||||||
|
// TODO: if enabled, remove GPIO_VDD_3V3_SENSORS4_EN from board_config.h
|
||||||
|
// }, {GPIO::PortG, GPIO::Pin8}),
|
||||||
|
initSPIBus(SPI::Bus::SPI5, {
|
||||||
|
initSPIDevice(SPIDEV_FLASH(0), SPI::CS{GPIO::PortG, GPIO::Pin7})
|
||||||
|
}),
|
||||||
|
initSPIBusExternal(SPI::Bus::SPI6, {
|
||||||
|
initSPIConfigExternal(SPI::CS{GPIO::PortI, GPIO::Pin10}, SPI::DRDY{GPIO::PortD, GPIO::Pin11}),
|
||||||
|
initSPIConfigExternal(SPI::CS{GPIO::PortA, GPIO::Pin15}, SPI::DRDY{GPIO::PortD, GPIO::Pin12}),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
|
||||||
|
initSPIHWVersion(HW_VER_REV(0, 2), {
|
||||||
|
initSPIBus(SPI::Bus::SPI1, {
|
||||||
|
initSPIDevice(DRV_IMU_DEVTYPE_ICM20602, SPI::CS{GPIO::PortI, GPIO::Pin9}, SPI::DRDY{GPIO::PortF, GPIO::Pin2}),
|
||||||
|
}, {GPIO::PortI, GPIO::Pin11}),
|
||||||
|
initSPIBus(SPI::Bus::SPI2, {
|
||||||
|
initSPIDevice(DRV_IMU_DEVTYPE_ICM42688P, SPI::CS{GPIO::PortH, GPIO::Pin5}, SPI::DRDY{GPIO::PortH, GPIO::Pin12}),
|
||||||
|
}, {GPIO::PortD, GPIO::Pin15}),
|
||||||
|
initSPIBus(SPI::Bus::SPI3, {
|
||||||
|
initSPIDevice(DRV_IMU_DEVTYPE_ICM20649, SPI::CS{GPIO::PortI, GPIO::Pin4}, SPI::DRDY{GPIO::PortI, GPIO::Pin7}),
|
||||||
|
}, {GPIO::PortE, GPIO::Pin7}),
|
||||||
|
// initSPIBus(SPI::Bus::SPI4, {
|
||||||
|
// // no devices
|
||||||
|
// TODO: if enabled, remove GPIO_VDD_3V3_SENSORS4_EN from board_config.h
|
||||||
|
// }, {GPIO::PortG, GPIO::Pin8}),
|
||||||
|
initSPIBus(SPI::Bus::SPI5, {
|
||||||
|
initSPIDevice(SPIDEV_FLASH(0), SPI::CS{GPIO::PortG, GPIO::Pin7})
|
||||||
|
}),
|
||||||
|
initSPIBusExternal(SPI::Bus::SPI6, {
|
||||||
|
initSPIConfigExternal(SPI::CS{GPIO::PortI, GPIO::Pin10}, SPI::DRDY{GPIO::PortD, GPIO::Pin11}),
|
||||||
|
initSPIConfigExternal(SPI::CS{GPIO::PortA, GPIO::Pin15}, SPI::DRDY{GPIO::PortD, GPIO::Pin12}),
|
||||||
|
}),
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
|
|
||||||
static constexpr bool unused = validateSPIConfig(px4_spi_buses);
|
static constexpr bool unused = validateSPIConfig(px4_spi_buses_all_hw);
|
||||||
|
|||||||
@@ -89,6 +89,7 @@ bool high_latency_data_link_lost # Set to true if the high latency data link
|
|||||||
|
|
||||||
bool engine_failure # Set to true if an engine failure is detected
|
bool engine_failure # Set to true if an engine failure is detected
|
||||||
bool mission_failure # Set to true if mission could not continue/finish
|
bool mission_failure # Set to true if mission could not continue/finish
|
||||||
|
bool geofence_violated
|
||||||
|
|
||||||
uint8 failure_detector_status # Bitmask containing FailureDetector status [0, 0, 0, 0, 0, FAILURE_ALT, FAILURE_PITCH, FAILURE_ROLL]
|
uint8 failure_detector_status # Bitmask containing FailureDetector status [0, 0, 0, 0, 0, FAILURE_ALT, FAILURE_PITCH, FAILURE_ROLL]
|
||||||
|
|
||||||
|
|||||||
@@ -262,6 +262,7 @@
|
|||||||
|
|
||||||
#if defined(BOARD_HAS_HW_VERSIONING)
|
#if defined(BOARD_HAS_HW_VERSIONING)
|
||||||
# define BOARD_HAS_VERSIONING 1
|
# define BOARD_HAS_VERSIONING 1
|
||||||
|
# define HW_VER_REV(v,r) ((uint32_t)((v) & 0xff) << 8) | ((uint32_t)(r) & 0xff)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Default LED logical to color mapping */
|
/* Default LED logical to color mapping */
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ struct px4_spi_bus_t {
|
|||||||
|
|
||||||
struct px4_spi_bus_all_hw_t {
|
struct px4_spi_bus_all_hw_t {
|
||||||
px4_spi_bus_t buses[SPI_BUS_MAX_BUS_ITEMS];
|
px4_spi_bus_t buses[SPI_BUS_MAX_BUS_ITEMS];
|
||||||
int board_hw_version{-1}; ///< 0=default, >0 for a specific revision (see board_get_hw_version), -1=unused
|
int board_hw_version_revision{-1}; ///< 0=default, >0 for a specific revision (see board_get_hw_version & board_get_hw_revision), -1=unused
|
||||||
};
|
};
|
||||||
|
|
||||||
#if BOARD_NUM_SPI_CFG_HW_VERSIONS > 1
|
#if BOARD_NUM_SPI_CFG_HW_VERSIONS > 1
|
||||||
|
|||||||
@@ -39,14 +39,19 @@
|
|||||||
#if BOARD_NUM_SPI_CFG_HW_VERSIONS > 1
|
#if BOARD_NUM_SPI_CFG_HW_VERSIONS > 1
|
||||||
void px4_set_spi_buses_from_hw_version()
|
void px4_set_spi_buses_from_hw_version()
|
||||||
{
|
{
|
||||||
int hw_version = board_get_hw_version();
|
#if defined(BOARD_HAS_SIMPLE_HW_VERSIONING)
|
||||||
|
int hw_version_revision = board_get_hw_version();
|
||||||
|
#else
|
||||||
|
int hw_version_revision = board_get_hw_revision();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
for (int i = 0; i < BOARD_NUM_SPI_CFG_HW_VERSIONS; ++i) {
|
for (int i = 0; i < BOARD_NUM_SPI_CFG_HW_VERSIONS; ++i) {
|
||||||
if (!px4_spi_buses && px4_spi_buses_all_hw[i].board_hw_version == 0) {
|
if (!px4_spi_buses && px4_spi_buses_all_hw[i].board_hw_version_revision == 0) {
|
||||||
px4_spi_buses = px4_spi_buses_all_hw[i].buses;
|
px4_spi_buses = px4_spi_buses_all_hw[i].buses;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (px4_spi_buses_all_hw[i].board_hw_version == hw_version) {
|
if (px4_spi_buses_all_hw[i].board_hw_version_revision == hw_version_revision) {
|
||||||
px4_spi_buses = px4_spi_buses_all_hw[i].buses;
|
px4_spi_buses = px4_spi_buses_all_hw[i].buses;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Submodule platforms/nuttx/NuttX/nuttx updated: bf06434168...20376b65d1
@@ -9,7 +9,7 @@ param set-default SENS_IMU_MODE 1
|
|||||||
param set-default EKF2_MULTI_MAG 0
|
param set-default EKF2_MULTI_MAG 0
|
||||||
param set-default SENS_MAG_MODE 1
|
param set-default SENS_MAG_MODE 1
|
||||||
|
|
||||||
set LOGGER_BUF 12
|
set LOGGER_BUF 8
|
||||||
|
|
||||||
if param greater -s UAVCAN_ENABLE 1
|
if param greater -s UAVCAN_ENABLE 1
|
||||||
then
|
then
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
# S32K1XX specific defaults
|
# S32K1XX specific defaults
|
||||||
#------------------------------------------------------------------------------
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
set LOGGER_BUF 12
|
set LOGGER_BUF 8
|
||||||
|
|
||||||
if param greater -s UAVCAN_ENABLE 1
|
if param greater -s UAVCAN_ENABLE 1
|
||||||
then
|
then
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ param set-default SENS_IMU_MODE 1
|
|||||||
param set-default EKF2_MULTI_MAG 0
|
param set-default EKF2_MULTI_MAG 0
|
||||||
param set-default SENS_MAG_MODE 1
|
param set-default SENS_MAG_MODE 1
|
||||||
|
|
||||||
set LOGGER_BUF 12
|
set LOGGER_BUF 8
|
||||||
|
|
||||||
if param greater -s UAVCAN_ENABLE 1
|
if param greater -s UAVCAN_ENABLE 1
|
||||||
then
|
then
|
||||||
|
|||||||
@@ -129,7 +129,8 @@ static inline constexpr SPI::bus_device_external_cfg_t initSPIConfigExternal(SPI
|
|||||||
struct px4_spi_bus_array_t {
|
struct px4_spi_bus_array_t {
|
||||||
px4_spi_bus_t item[SPI_BUS_MAX_BUS_ITEMS];
|
px4_spi_bus_t item[SPI_BUS_MAX_BUS_ITEMS];
|
||||||
};
|
};
|
||||||
static inline constexpr px4_spi_bus_all_hw_t initSPIHWVersion(int hw_version, const px4_spi_bus_array_t &bus_items)
|
static inline constexpr px4_spi_bus_all_hw_t initSPIHWVersion(int hw_version_revision,
|
||||||
|
const px4_spi_bus_array_t &bus_items)
|
||||||
{
|
{
|
||||||
px4_spi_bus_all_hw_t ret{};
|
px4_spi_bus_all_hw_t ret{};
|
||||||
|
|
||||||
@@ -137,7 +138,7 @@ static inline constexpr px4_spi_bus_all_hw_t initSPIHWVersion(int hw_version, co
|
|||||||
ret.buses[i] = bus_items.item[i];
|
ret.buses[i] = bus_items.item[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
ret.board_hw_version = hw_version;
|
ret.board_hw_version_revision = hw_version_revision;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
constexpr bool validateSPIConfig(const px4_spi_bus_t spi_buses_conf[SPI_BUS_MAX_BUS_ITEMS]);
|
constexpr bool validateSPIConfig(const px4_spi_bus_t spi_buses_conf[SPI_BUS_MAX_BUS_ITEMS]);
|
||||||
|
|||||||
+1
-1
Submodule src/drivers/gps/devices updated: f82313f082...f3c4c97bc8
+10
-2
@@ -75,7 +75,8 @@
|
|||||||
#include <linux/spi/spidev.h>
|
#include <linux/spi/spidev.h>
|
||||||
#endif /* __PX4_LINUX */
|
#endif /* __PX4_LINUX */
|
||||||
|
|
||||||
#define TIMEOUT_5HZ 500
|
#define TIMEOUT_1HZ 1300 //!< Timeout time in mS, 1000 mS (1Hz) + 300 mS delta for error
|
||||||
|
#define TIMEOUT_5HZ 500 //!< Timeout time in mS, 200 mS (5Hz) + 300 mS delta for error
|
||||||
#define RATE_MEASUREMENT_PERIOD 5000000
|
#define RATE_MEASUREMENT_PERIOD 5000000
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@@ -837,8 +838,15 @@ GPS::run()
|
|||||||
}
|
}
|
||||||
|
|
||||||
int helper_ret;
|
int helper_ret;
|
||||||
|
unsigned receive_timeout = TIMEOUT_5HZ;
|
||||||
|
|
||||||
while ((helper_ret = _helper->receive(TIMEOUT_5HZ)) > 0 && !should_exit()) {
|
if (ubx_mode == GPSDriverUBX::UBXMode::RoverWithMovingBase) {
|
||||||
|
/* The MB rover will wait as long as possible to compute a navigation solution,
|
||||||
|
* possibly lowering the navigation rate all the way to 1 Hz while doing so. */
|
||||||
|
receive_timeout = TIMEOUT_1HZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((helper_ret = _helper->receive(receive_timeout)) > 0 && !should_exit()) {
|
||||||
|
|
||||||
if (helper_ret & 1) {
|
if (helper_ret & 1) {
|
||||||
publish();
|
publish();
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ int16_t CanardNuttXCDev::receive(CanardFrame *received_frame)
|
|||||||
// Any recieved CAN messages will cause the poll statement to unblock and run
|
// Any recieved CAN messages will cause the poll statement to unblock and run
|
||||||
// This way CAN read runs with minimal latency.
|
// This way CAN read runs with minimal latency.
|
||||||
// Note that multiple messages may be received in a short time, so this will try to read any availible in a loop
|
// Note that multiple messages may be received in a short time, so this will try to read any availible in a loop
|
||||||
::poll(&fds, 1, 10);
|
::poll(&fds, 1, 0);
|
||||||
|
|
||||||
// Only execute this part if can0 is changed.
|
// Only execute this part if can0 is changed.
|
||||||
if (fds.revents & POLLIN) {
|
if (fds.revents & POLLIN) {
|
||||||
|
|||||||
@@ -162,12 +162,12 @@ int16_t CanardSocketCAN::transmit(const CanardFrame &txf, int timeout_ms)
|
|||||||
_send_tv->tv_usec = txf.timestamp_usec % 1000000ULL;
|
_send_tv->tv_usec = txf.timestamp_usec % 1000000ULL;
|
||||||
_send_tv->tv_sec = (txf.timestamp_usec - _send_tv->tv_usec) / 1000000ULL;
|
_send_tv->tv_sec = (txf.timestamp_usec - _send_tv->tv_usec) / 1000000ULL;
|
||||||
|
|
||||||
return sendmsg(_fd, &_send_msg, 1000);
|
return sendmsg(_fd, &_send_msg, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t CanardSocketCAN::receive(CanardFrame *rxf)
|
int16_t CanardSocketCAN::receive(CanardFrame *rxf)
|
||||||
{
|
{
|
||||||
int32_t result = recvmsg(_fd, &_recv_msg, 1000);
|
int32_t result = recvmsg(_fd, &_recv_msg, MSG_DONTWAIT);
|
||||||
|
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@@ -39,16 +39,20 @@
|
|||||||
* @author Peter van der Perk <peter.vanderperk@nxp.com>
|
* @author Peter van der Perk <peter.vanderperk@nxp.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define RETRY_COUNT 10
|
||||||
|
|
||||||
#include "NodeManager.hpp"
|
#include "NodeManager.hpp"
|
||||||
|
|
||||||
bool NodeManager::HandleNodeIDRequest(uavcan_pnp_NodeIDAllocationData_1_0 &msg)
|
bool NodeManager::HandleNodeIDRequest(uavcan_pnp_NodeIDAllocationData_1_0 &msg)
|
||||||
{
|
{
|
||||||
if (msg.allocated_node_id.count == 0) {
|
if (msg.allocated_node_id.count == 0) {
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
msg.allocated_node_id.count = 1;
|
msg.allocated_node_id.count = 1;
|
||||||
msg.allocated_node_id.elements[0].value = CANARD_NODE_ID_UNSET;
|
msg.allocated_node_id.elements[0].value = CANARD_NODE_ID_UNSET;
|
||||||
|
|
||||||
/* Search for an available NodeID to assign */
|
/* Search for an available NodeID to assign */
|
||||||
for (uint32_t i = 1; i < sizeof(nodeid_registry) / sizeof(nodeid_registry[0]); i++) {
|
for (i = 1; i < sizeof(nodeid_registry) / sizeof(nodeid_registry[0]); i++) {
|
||||||
if (i == _canard_instance.node_id) {
|
if (i == _canard_instance.node_id) {
|
||||||
continue; // Don't give our NodeID to a node
|
continue; // Don't give our NodeID to a node
|
||||||
|
|
||||||
@@ -63,6 +67,10 @@ bool NodeManager::HandleNodeIDRequest(uavcan_pnp_NodeIDAllocationData_1_0 &msg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nodeid_registry[i].register_setup = false; // Re-instantiate register setup
|
||||||
|
nodeid_registry[i].register_index = 0;
|
||||||
|
nodeid_registry[i].retry_count = 0;
|
||||||
|
|
||||||
if (msg.allocated_node_id.elements[0].value != CANARD_NODE_ID_UNSET) {
|
if (msg.allocated_node_id.elements[0].value != CANARD_NODE_ID_UNSET) {
|
||||||
|
|
||||||
PX4_INFO("Received NodeID allocation request assigning %i", msg.allocated_node_id.elements[0].value);
|
PX4_INFO("Received NodeID allocation request assigning %i", msg.allocated_node_id.elements[0].value);
|
||||||
@@ -120,17 +128,15 @@ void NodeManager::HandleListResponse(CanardNodeID node_id, uavcan_register_List_
|
|||||||
if (nodeid_registry[i].node_id == node_id) {
|
if (nodeid_registry[i].node_id == node_id) {
|
||||||
nodeid_registry[i].register_index++; // Increment index counter for next update()
|
nodeid_registry[i].register_index++; // Increment index counter for next update()
|
||||||
nodeid_registry[i].register_setup = false;
|
nodeid_registry[i].register_setup = false;
|
||||||
|
nodeid_registry[i].retry_count = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_access_request.setPortId(node_id, msg.name)) {
|
||||||
|
PX4_INFO("Set portID succesfull");
|
||||||
|
|
||||||
if (strncmp((char *)msg.name.name.elements, gps_uorb_register_name,
|
} else {
|
||||||
msg.name.name.count) == 0) {
|
PX4_INFO("Register not found %.*s", msg.name.name.count, msg.name.name.elements);
|
||||||
_access_request.setPortId(node_id, gps_uorb_register_name, 1235); //TODO configurable and combine with ParamManager.
|
|
||||||
|
|
||||||
} else if (strncmp((char *)msg.name.name.elements, bms_status_register_name,
|
|
||||||
msg.name.name.count) == 0) { //Battery status publisher
|
|
||||||
_access_request.setPortId(node_id, bms_status_register_name, 1234); //TODO configurable and combine with ParamManager.
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -142,7 +148,11 @@ void NodeManager::update()
|
|||||||
if (nodeid_registry[i].node_id != 0 && nodeid_registry[i].register_setup == false) {
|
if (nodeid_registry[i].node_id != 0 && nodeid_registry[i].register_setup == false) {
|
||||||
//Setting up registers
|
//Setting up registers
|
||||||
_list_request.request(nodeid_registry[i].node_id, nodeid_registry[i].register_index);
|
_list_request.request(nodeid_registry[i].node_id, nodeid_registry[i].register_index);
|
||||||
nodeid_registry[i].register_setup = true;
|
nodeid_registry[i].retry_count++;
|
||||||
|
|
||||||
|
if (nodeid_registry[i].retry_count > RETRY_COUNT) {
|
||||||
|
nodeid_registry[i].register_setup = true; // Don't update anymore
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -63,12 +63,14 @@ typedef struct {
|
|||||||
uint8_t unique_id[16];
|
uint8_t unique_id[16];
|
||||||
bool register_setup;
|
bool register_setup;
|
||||||
uint16_t register_index;
|
uint16_t register_index;
|
||||||
|
uint16_t retry_count;
|
||||||
} UavcanNodeEntry;
|
} UavcanNodeEntry;
|
||||||
|
|
||||||
class NodeManager
|
class NodeManager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NodeManager(CanardInstance &ins) : _canard_instance(ins), _access_request(ins), _list_request(ins) { };
|
NodeManager(CanardInstance &ins, UavcanParamManager &pmgr) : _canard_instance(ins), _access_request(ins, pmgr),
|
||||||
|
_list_request(ins) { };
|
||||||
|
|
||||||
bool HandleNodeIDRequest(uavcan_pnp_NodeIDAllocationData_1_0 &msg);
|
bool HandleNodeIDRequest(uavcan_pnp_NodeIDAllocationData_1_0 &msg);
|
||||||
bool HandleNodeIDRequest(uavcan_pnp_NodeIDAllocationData_2_0 &msg);
|
bool HandleNodeIDRequest(uavcan_pnp_NodeIDAllocationData_2_0 &msg);
|
||||||
@@ -89,8 +91,4 @@ private:
|
|||||||
bool nodeRegisterSetup = 0;
|
bool nodeRegisterSetup = 0;
|
||||||
|
|
||||||
hrt_abstime _register_request_last{0};
|
hrt_abstime _register_request_last{0};
|
||||||
|
|
||||||
//TODO work this out
|
|
||||||
const char *gps_uorb_register_name = "uavcan.pub.gnss_uorb.id";
|
|
||||||
const char *bms_status_register_name = "uavcan.pub.battery_status.id";
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -40,6 +40,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "ParamManager.hpp"
|
#include "ParamManager.hpp"
|
||||||
|
#include <px4_platform_common/defines.h>
|
||||||
|
|
||||||
bool UavcanParamManager::GetParamByName(const char *param_name, uavcan_register_Value_1_0 &value)
|
bool UavcanParamManager::GetParamByName(const char *param_name, uavcan_register_Value_1_0 &value)
|
||||||
{
|
{
|
||||||
@@ -56,8 +57,16 @@ bool UavcanParamManager::GetParamByName(const char *param_name, uavcan_register_
|
|||||||
case PARAM_TYPE_INT32: {
|
case PARAM_TYPE_INT32: {
|
||||||
int32_t out_val {};
|
int32_t out_val {};
|
||||||
param_get(param_handle, &out_val);
|
param_get(param_handle, &out_val);
|
||||||
value.integer32.value.elements[0] = out_val;
|
|
||||||
uavcan_register_Value_1_0_select_integer32_(&value);
|
if (uavcan_register_Value_1_0_is_natural16_(&value)) { //FIXME param rewrite
|
||||||
|
value.natural16.value.elements[0] = (uint16_t)out_val;
|
||||||
|
uavcan_register_Value_1_0_select_natural16_(&value);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
value.integer32.value.elements[0] = out_val;
|
||||||
|
uavcan_register_Value_1_0_select_integer32_(&value);
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,15 +100,23 @@ bool UavcanParamManager::GetParamByName(const uavcan_register_Name_1_0 &name, ua
|
|||||||
switch (param_type(param_handle)) {
|
switch (param_type(param_handle)) {
|
||||||
case PARAM_TYPE_INT32: {
|
case PARAM_TYPE_INT32: {
|
||||||
int32_t out_val {};
|
int32_t out_val {};
|
||||||
param_set(param_handle, &out_val);
|
param_get(param_handle, &out_val);
|
||||||
value.integer32.value.elements[0] = out_val;
|
|
||||||
uavcan_register_Value_1_0_select_integer32_(&value);
|
if (uavcan_register_Value_1_0_is_natural16_(&value)) { //FIXME param rewrite
|
||||||
|
value.natural16.value.elements[0] = (uint16_t)out_val;
|
||||||
|
uavcan_register_Value_1_0_select_natural16_(&value);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
value.integer32.value.elements[0] = out_val;
|
||||||
|
uavcan_register_Value_1_0_select_integer32_(&value);
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case PARAM_TYPE_FLOAT: {
|
case PARAM_TYPE_FLOAT: {
|
||||||
float out_val {};
|
float out_val {};
|
||||||
param_set(param_handle, &out_val);
|
param_get(param_handle, &out_val);
|
||||||
value.real32.value.elements[0] = out_val;
|
value.real32.value.elements[0] = out_val;
|
||||||
uavcan_register_Value_1_0_select_real32_(&value);
|
uavcan_register_Value_1_0_select_real32_(&value);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
const UavcanParamBinder _uavcan_params[10] {
|
const UavcanParamBinder _uavcan_params[11] {
|
||||||
{"uavcan.pub.esc.0.id", "UCAN1_ESC_PUB"},
|
{"uavcan.pub.esc.0.id", "UCAN1_ESC_PUB"},
|
||||||
{"uavcan.pub.servo.0.id", "UCAN1_SERVO_PUB"},
|
{"uavcan.pub.servo.0.id", "UCAN1_SERVO_PUB"},
|
||||||
{"uavcan.pub.gps.0.id", "UCAN1_GPS_PUB"},
|
{"uavcan.pub.gps.0.id", "UCAN1_GPS_PUB"},
|
||||||
@@ -74,6 +74,7 @@ private:
|
|||||||
{"uavcan.sub.battery_status.0.id", "UCAN1_BMS_BS_PID"},
|
{"uavcan.sub.battery_status.0.id", "UCAN1_BMS_BS_PID"},
|
||||||
{"uavcan.sub.battery_parameters.0.id", "UCAN1_BMS_BP_PID"},
|
{"uavcan.sub.battery_parameters.0.id", "UCAN1_BMS_BP_PID"},
|
||||||
{"uavcan.sub.legacy_bms.0.id", "UCAN1_LG_BMS_PID"},
|
{"uavcan.sub.legacy_bms.0.id", "UCAN1_LG_BMS_PID"},
|
||||||
|
{"uavcan.sub.uorb.sensor_gps.0.id", "UCAN1_UORB_GPS"},
|
||||||
//{"uavcan.sub.bms.0.id", "UCAN1_BMS0_PID"}, //FIXME instancing
|
//{"uavcan.sub.bms.0.id", "UCAN1_BMS0_PID"}, //FIXME instancing
|
||||||
//{"uavcan.sub.bms.1.id", "UCAN1_BMS1_PID"},
|
//{"uavcan.sub.bms.1.id", "UCAN1_BMS1_PID"},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,84 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (c) 2021 PX4 Development Team. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* 3. Neither the name PX4 nor the names of its contributors may be
|
||||||
|
* used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||||
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file sensor_gps.hpp
|
||||||
|
*
|
||||||
|
* Defines uORB over UAVCANv1 sensor_gps publisher
|
||||||
|
*
|
||||||
|
* @author Peter van der Perk <peter.vanderperk@nxp.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <uORB/topics/sensor_gps.h>
|
||||||
|
|
||||||
|
#include "../Publisher.hpp"
|
||||||
|
|
||||||
|
class UORB_over_UAVCAN_sensor_gps_Publisher : public UavcanPublisher
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
UORB_over_UAVCAN_sensor_gps_Publisher(CanardInstance &ins, UavcanParamManager &pmgr, uint8_t instance = 0) :
|
||||||
|
UavcanPublisher(ins, pmgr, "sensor_gps", instance)
|
||||||
|
{};
|
||||||
|
|
||||||
|
// Update the uORB Subscription and broadcast a UAVCAN message
|
||||||
|
virtual void update() override
|
||||||
|
{
|
||||||
|
// Not sure if actuator_armed is a good indication of readiness but seems close to it
|
||||||
|
if (_sensor_gps_sub.updated() && _port_id != CANARD_PORT_ID_UNSET && _port_id != 0) {
|
||||||
|
sensor_gps_s gps_msg {};
|
||||||
|
_sensor_gps_sub.update(&gps_msg);
|
||||||
|
|
||||||
|
CanardTransfer transfer = {
|
||||||
|
.timestamp_usec = hrt_absolute_time() + PUBLISHER_DEFAULT_TIMEOUT_USEC,
|
||||||
|
.priority = CanardPriorityNominal,
|
||||||
|
.transfer_kind = CanardTransferKindMessage,
|
||||||
|
.port_id = _port_id, // This is the subject-ID.
|
||||||
|
.remote_node_id = CANARD_NODE_ID_UNSET,
|
||||||
|
.transfer_id = _transfer_id,
|
||||||
|
.payload_size = sizeof(struct sensor_gps_s),
|
||||||
|
.payload = &gps_msg,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (result == 0) {
|
||||||
|
// set the data ready in the buffer and chop if needed
|
||||||
|
++_transfer_id; // The transfer-ID shall be incremented after every transmission on this subject.
|
||||||
|
result = canardTxPush(&_canard_instance, &transfer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
uORB::Subscription _sensor_gps_sub{ORB_ID(sensor_gps)};
|
||||||
|
};
|
||||||
@@ -52,45 +52,55 @@
|
|||||||
class UavcanAccessServiceRequest
|
class UavcanAccessServiceRequest
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
UavcanAccessServiceRequest(CanardInstance &ins) :
|
UavcanAccessServiceRequest(CanardInstance &ins, UavcanParamManager &pmgr) :
|
||||||
_canard_instance(ins) { };
|
_canard_instance(ins), _param_manager(pmgr) { };
|
||||||
|
|
||||||
void setPortId(CanardNodeID node_id, const char *register_name, uint16_t port_id)
|
bool setPortId(CanardNodeID node_id, uavcan_register_Name_1_0 &name)
|
||||||
{
|
{
|
||||||
int result {0};
|
int result {0};
|
||||||
|
|
||||||
uavcan_register_Access_Request_1_0 request_msg;
|
uavcan_register_Access_Request_1_0 request_msg;
|
||||||
strncpy((char *)&request_msg.name.name.elements[0], register_name, sizeof(uavcan_register_Name_1_0));
|
|
||||||
request_msg.name.name.count = strlen(register_name);
|
|
||||||
|
|
||||||
uavcan_register_Value_1_0_select_natural16_(&request_msg.value);
|
|
||||||
request_msg.value.natural16.value.count = 1;
|
request_msg.value.natural16.value.count = 1;
|
||||||
request_msg.value.natural16.value.elements[0] = port_id;
|
uavcan_register_Value_1_0_select_natural16_(&request_msg.value); // Set to natural16 so that ParamManager casts type
|
||||||
|
|
||||||
uint8_t request_payload_buffer[uavcan_register_Access_Request_1_0_SERIALIZATION_BUFFER_SIZE_BYTES_];
|
//FIXME ParamManager only has notion of being either sub/pub have to find a portable way to address trhis
|
||||||
|
name.name.elements[7] = 's'; //HACK Change pub into sub
|
||||||
|
|
||||||
CanardTransfer transfer = {
|
if (_param_manager.GetParamByName(name, request_msg.value)) {
|
||||||
.timestamp_usec = hrt_absolute_time() + PUBLISHER_DEFAULT_TIMEOUT_USEC,
|
name.name.elements[7] = 'p'; //HACK Change sub into pub
|
||||||
.priority = CanardPriorityNominal,
|
memcpy(&request_msg.name, &name, sizeof(request_msg.name));
|
||||||
.transfer_kind = CanardTransferKindRequest,
|
|
||||||
.port_id = uavcan_register_Access_1_0_FIXED_PORT_ID_, // This is the subject-ID.
|
|
||||||
.remote_node_id = node_id, // Messages cannot be unicast, so use UNSET.
|
|
||||||
.transfer_id = access_request_transfer_id,
|
|
||||||
.payload_size = uavcan_register_Access_Request_1_0_SERIALIZATION_BUFFER_SIZE_BYTES_,
|
|
||||||
.payload = &request_payload_buffer,
|
|
||||||
};
|
|
||||||
|
|
||||||
result = uavcan_register_Access_Request_1_0_serialize_(&request_msg, request_payload_buffer, &transfer.payload_size);
|
uint8_t request_payload_buffer[uavcan_register_Access_Request_1_0_SERIALIZATION_BUFFER_SIZE_BYTES_];
|
||||||
|
|
||||||
if (result == 0) {
|
CanardTransfer transfer = {
|
||||||
// set the data ready in the buffer and chop if needed
|
.timestamp_usec = hrt_absolute_time() + PUBLISHER_DEFAULT_TIMEOUT_USEC,
|
||||||
++access_request_transfer_id; // The transfer-ID shall be incremented after every transmission on this subject.
|
.priority = CanardPriorityNominal,
|
||||||
result = canardTxPush(&_canard_instance, &transfer);
|
.transfer_kind = CanardTransferKindRequest,
|
||||||
|
.port_id = uavcan_register_Access_1_0_FIXED_PORT_ID_, // This is the subject-ID.
|
||||||
|
.remote_node_id = node_id, // Messages cannot be unicast, so use UNSET.
|
||||||
|
.transfer_id = access_request_transfer_id,
|
||||||
|
.payload_size = uavcan_register_Access_Request_1_0_SERIALIZATION_BUFFER_SIZE_BYTES_,
|
||||||
|
.payload = &request_payload_buffer,
|
||||||
|
};
|
||||||
|
|
||||||
|
result = uavcan_register_Access_Request_1_0_serialize_(&request_msg, request_payload_buffer, &transfer.payload_size);
|
||||||
|
|
||||||
|
if (result == 0) {
|
||||||
|
// set the data ready in the buffer and chop if needed
|
||||||
|
++access_request_transfer_id; // The transfer-ID shall be incremented after every transmission on this subject.
|
||||||
|
result = canardTxPush(&_canard_instance, &transfer);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result > 0;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CanardInstance &_canard_instance;
|
CanardInstance &_canard_instance;
|
||||||
CanardTransferID access_request_transfer_id = 0;
|
CanardTransferID access_request_transfer_id = 0;
|
||||||
|
UavcanParamManager &_param_manager;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -68,25 +68,27 @@ public:
|
|||||||
|
|
||||||
// Set _port_id from _uavcan_param
|
// Set _port_id from _uavcan_param
|
||||||
uavcan_register_Value_1_0 value;
|
uavcan_register_Value_1_0 value;
|
||||||
_param_manager.GetParamByName(uavcan_param, value);
|
|
||||||
int32_t new_id = value.integer32.value.elements[0];
|
|
||||||
|
|
||||||
/* FIXME how about partial subscribing */
|
if (_param_manager.GetParamByName(uavcan_param, value)) {
|
||||||
if (curSubj->_canard_sub._port_id != new_id) {
|
int32_t new_id = value.integer32.value.elements[0];
|
||||||
if (new_id == CANARD_PORT_ID_UNSET) {
|
|
||||||
// Cancel subscription
|
|
||||||
unsubscribe();
|
|
||||||
|
|
||||||
} else {
|
/* FIXME how about partial subscribing */
|
||||||
if (curSubj->_canard_sub._port_id != CANARD_PORT_ID_UNSET) {
|
if (curSubj->_canard_sub._port_id != new_id) {
|
||||||
// Already active; unsubscribe first
|
if (new_id == CANARD_PORT_ID_UNSET) {
|
||||||
|
// Cancel subscription
|
||||||
unsubscribe();
|
unsubscribe();
|
||||||
}
|
|
||||||
|
|
||||||
// Subscribe on the new port ID
|
} else {
|
||||||
curSubj->_canard_sub._port_id = (CanardPortID)new_id;
|
if (curSubj->_canard_sub._port_id != CANARD_PORT_ID_UNSET) {
|
||||||
PX4_INFO("Subscribing %s.%d on port %d", curSubj->_subject_name, _instance, curSubj->_canard_sub._port_id);
|
// Already active; unsubscribe first
|
||||||
subscribe();
|
unsubscribe();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Subscribe on the new port ID
|
||||||
|
curSubj->_canard_sub._port_id = (CanardPortID)new_id;
|
||||||
|
PX4_INFO("Subscribing %s.%d on port %d", curSubj->_subject_name, _instance, curSubj->_canard_sub._port_id);
|
||||||
|
subscribe();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,83 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (c) 2021 PX4 Development Team. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* 3. Neither the name PX4 nor the names of its contributors may be
|
||||||
|
* used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||||
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file sensor_gps.hpp
|
||||||
|
*
|
||||||
|
* Defines uORB over UAVCANv1 sensor_gps subscriber
|
||||||
|
*
|
||||||
|
* @author Peter van der Perk <peter.vanderperk@nxp.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <uORB/topics/sensor_gps.h>
|
||||||
|
#include <uORB/PublicationMulti.hpp>
|
||||||
|
|
||||||
|
#include "../DynamicPortSubscriber.hpp"
|
||||||
|
|
||||||
|
class UORB_over_UAVCAN_sensor_gps_Subscriber : public UavcanDynamicPortSubscriber
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
UORB_over_UAVCAN_sensor_gps_Subscriber(CanardInstance &ins, UavcanParamManager &pmgr, uint8_t instance = 0) :
|
||||||
|
UavcanDynamicPortSubscriber(ins, pmgr, "uorb.sensor_gps", instance) { };
|
||||||
|
|
||||||
|
void subscribe() override
|
||||||
|
{
|
||||||
|
// Subscribe to messages uORB sensor_gps payload over UAVCAN
|
||||||
|
canardRxSubscribe(&_canard_instance,
|
||||||
|
CanardTransferKindMessage,
|
||||||
|
_subj_sub._canard_sub._port_id,
|
||||||
|
sizeof(struct sensor_gps_s),
|
||||||
|
CANARD_DEFAULT_TRANSFER_ID_TIMEOUT_USEC * 10000,
|
||||||
|
&_subj_sub._canard_sub);
|
||||||
|
};
|
||||||
|
|
||||||
|
void callback(const CanardTransfer &receive) override
|
||||||
|
{
|
||||||
|
//PX4_INFO("uORB sensor_gps Callback");
|
||||||
|
|
||||||
|
if (receive.payload_size == sizeof(struct sensor_gps_s)) {
|
||||||
|
sensor_gps_s *gps_msg = (sensor_gps_s *)receive.payload;
|
||||||
|
_sensor_gps_pub.publish(*gps_msg);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
PX4_ERR("uORB over UAVCAN %s playload size mismatch got %d expected %d",
|
||||||
|
_subj_sub._subject_name, receive.payload_size, sizeof(struct sensor_gps_s));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
uORB::PublicationMulti<sensor_gps_s> _sensor_gps_pub{ORB_ID(sensor_gps)};
|
||||||
|
|
||||||
|
};
|
||||||
@@ -56,8 +56,7 @@ static void memFree(CanardInstance *const ins, void *const pointer) { o1heapFree
|
|||||||
UavcanNode::UavcanNode(CanardInterface *interface, uint32_t node_id) :
|
UavcanNode::UavcanNode(CanardInterface *interface, uint32_t node_id) :
|
||||||
ModuleParams(nullptr),
|
ModuleParams(nullptr),
|
||||||
ScheduledWorkItem(MODULE_NAME, px4::wq_configurations::uavcan),
|
ScheduledWorkItem(MODULE_NAME, px4::wq_configurations::uavcan),
|
||||||
_can_interface(interface)//,
|
_can_interface(interface)
|
||||||
// _subscribers{&_gps0_sub, &_gps1_sub, &_bms0_sub, &_bms1_sub}
|
|
||||||
{
|
{
|
||||||
pthread_mutex_init(&_node_mutex, nullptr);
|
pthread_mutex_init(&_node_mutex, nullptr);
|
||||||
|
|
||||||
@@ -168,13 +167,6 @@ void UavcanNode::init()
|
|||||||
CANARD_DEFAULT_TRANSFER_ID_TIMEOUT_USEC,
|
CANARD_DEFAULT_TRANSFER_ID_TIMEOUT_USEC,
|
||||||
&_heartbeat_subscription);
|
&_heartbeat_subscription);
|
||||||
|
|
||||||
canardRxSubscribe(&_canard_instance, // uORB over UAVCAN GPS message
|
|
||||||
CanardTransferKindMessage,
|
|
||||||
gps_port_id,
|
|
||||||
sizeof(struct sensor_gps_s),
|
|
||||||
CANARD_DEFAULT_TRANSFER_ID_TIMEOUT_USEC,
|
|
||||||
&_drone_srv_gps_subscription);
|
|
||||||
|
|
||||||
for (auto &subscriber : _subscribers) {
|
for (auto &subscriber : _subscribers) {
|
||||||
subscriber->subscribe();
|
subscriber->subscribe();
|
||||||
}
|
}
|
||||||
@@ -238,7 +230,69 @@ void UavcanNode::Run()
|
|||||||
|
|
||||||
_node_manager.update();
|
_node_manager.update();
|
||||||
|
|
||||||
// Transmitting
|
transmit();
|
||||||
|
|
||||||
|
/* Process received messages */
|
||||||
|
|
||||||
|
uint8_t data[64] {};
|
||||||
|
CanardFrame received_frame{};
|
||||||
|
received_frame.payload = &data;
|
||||||
|
|
||||||
|
while (_can_interface->receive(&received_frame) > 0) {
|
||||||
|
CanardTransfer receive{};
|
||||||
|
int32_t result = canardRxAccept(&_canard_instance, &received_frame, 0, &receive);
|
||||||
|
|
||||||
|
if (result < 0) {
|
||||||
|
// An error has occurred: either an argument is invalid or we've ran out of memory.
|
||||||
|
// It is possible to statically prove that an out-of-memory will never occur for a given application if
|
||||||
|
// the heap is sized correctly; for background, refer to the Robson's Proof and the documentation for O1Heap.
|
||||||
|
// Reception of an invalid frame is NOT an error.
|
||||||
|
PX4_ERR("Receive error %d\n", result);
|
||||||
|
|
||||||
|
} else if (result == 1) {
|
||||||
|
// A transfer has been received, process it.
|
||||||
|
// PX4_INFO("received Port ID: %d", receive.port_id);
|
||||||
|
|
||||||
|
if (receive.port_id > 0) {
|
||||||
|
// If not a fixed port ID, check any subscribers which may have registered it
|
||||||
|
for (auto &subscriber : _subscribers) {
|
||||||
|
if (subscriber->hasPortID(receive.port_id)) {
|
||||||
|
subscriber->callback(receive);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto &subscriber : _dynsubscribers) {
|
||||||
|
if (subscriber->hasPortID(receive.port_id)) {
|
||||||
|
subscriber->callback(receive);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deallocate the dynamic memory afterwards.
|
||||||
|
_canard_instance.memory_free(&_canard_instance, (void *)receive.payload);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
//PX4_INFO("RX canard %d", result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pop canardTx queue to send out responses to requets
|
||||||
|
transmit();
|
||||||
|
|
||||||
|
perf_end(_cycle_perf);
|
||||||
|
|
||||||
|
if (_task_should_exit.load()) {
|
||||||
|
_can_interface->close();
|
||||||
|
|
||||||
|
ScheduleClear();
|
||||||
|
_instance = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&_node_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UavcanNode::transmit()
|
||||||
|
{
|
||||||
// Look at the top of the TX queue.
|
// Look at the top of the TX queue.
|
||||||
for (const CanardFrame *txf = nullptr; (txf = canardTxPeek(&_canard_instance)) != nullptr;) {
|
for (const CanardFrame *txf = nullptr; (txf = canardTxPeek(&_canard_instance)) != nullptr;) {
|
||||||
// Attempt transmission only if the frame is not yet timed out while waiting in the TX queue.
|
// Attempt transmission only if the frame is not yet timed out while waiting in the TX queue.
|
||||||
@@ -268,67 +322,6 @@ void UavcanNode::Run()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Process received messages */
|
|
||||||
|
|
||||||
uint8_t data[64] {};
|
|
||||||
CanardFrame received_frame{};
|
|
||||||
received_frame.payload = &data;
|
|
||||||
|
|
||||||
/* FIXME this flawed we've to go through the whole loop to get the next frame in the buffer */
|
|
||||||
|
|
||||||
if (_can_interface->receive(&received_frame) > 0) {
|
|
||||||
|
|
||||||
CanardTransfer receive{};
|
|
||||||
int32_t result = canardRxAccept(&_canard_instance, &received_frame, 0, &receive);
|
|
||||||
|
|
||||||
if (result < 0) {
|
|
||||||
// An error has occurred: either an argument is invalid or we've ran out of memory.
|
|
||||||
// It is possible to statically prove that an out-of-memory will never occur for a given application if
|
|
||||||
// the heap is sized correctly; for background, refer to the Robson's Proof and the documentation for O1Heap.
|
|
||||||
// Reception of an invalid frame is NOT an error.
|
|
||||||
PX4_ERR("Receive error %d\n", result);
|
|
||||||
|
|
||||||
} else if (result == 1) {
|
|
||||||
// A transfer has been received, process it.
|
|
||||||
// PX4_INFO("received Port ID: %d", receive.port_id);
|
|
||||||
|
|
||||||
if (receive.port_id == gps_port_id) {
|
|
||||||
result = handleUORBSensorGPS(receive);
|
|
||||||
|
|
||||||
} else if (receive.port_id > 0) {
|
|
||||||
// If not a fixed port ID, check any subscribers which may have registered it
|
|
||||||
for (auto &subscriber : _subscribers) {
|
|
||||||
if (subscriber->hasPortID(receive.port_id)) {
|
|
||||||
subscriber->callback(receive);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto &subscriber : _dynsubscribers) {
|
|
||||||
if (subscriber->hasPortID(receive.port_id)) {
|
|
||||||
subscriber->callback(receive);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deallocate the dynamic memory afterwards.
|
|
||||||
_canard_instance.memory_free(&_canard_instance, (void *)receive.payload);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
//PX4_INFO("RX canard %d\r\n", result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
perf_end(_cycle_perf);
|
|
||||||
|
|
||||||
if (_task_should_exit.load()) {
|
|
||||||
_can_interface->close();
|
|
||||||
|
|
||||||
ScheduleClear();
|
|
||||||
_instance = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
pthread_mutex_unlock(&_node_mutex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void UavcanNode::print_info()
|
void UavcanNode::print_info()
|
||||||
@@ -338,6 +331,13 @@ void UavcanNode::print_info()
|
|||||||
perf_print_counter(_cycle_perf);
|
perf_print_counter(_cycle_perf);
|
||||||
perf_print_counter(_interval_perf);
|
perf_print_counter(_interval_perf);
|
||||||
|
|
||||||
|
O1HeapDiagnostics heap_diagnostics = o1heapGetDiagnostics(uavcan_allocator);
|
||||||
|
|
||||||
|
PX4_INFO("Heap status %zu/%zu Peak alloc %zu Peak req %zu OOM count %" PRIu64,
|
||||||
|
heap_diagnostics.allocated, heap_diagnostics.capacity,
|
||||||
|
heap_diagnostics.peak_allocated, heap_diagnostics.peak_request_size,
|
||||||
|
heap_diagnostics.oom_count);
|
||||||
|
|
||||||
for (auto &publisher : _publishers) {
|
for (auto &publisher : _publishers) {
|
||||||
publisher->printInfo();
|
publisher->printInfo();
|
||||||
}
|
}
|
||||||
@@ -346,6 +346,10 @@ void UavcanNode::print_info()
|
|||||||
subscriber->printInfo();
|
subscriber->printInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto &subscriber : _dynsubscribers) {
|
||||||
|
subscriber->printInfo();
|
||||||
|
}
|
||||||
|
|
||||||
_mixing_output.printInfo();
|
_mixing_output.printInfo();
|
||||||
_esc_controller.printInfo();
|
_esc_controller.printInfo();
|
||||||
|
|
||||||
@@ -442,16 +446,6 @@ void UavcanNode::sendHeartbeat()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int UavcanNode::handleUORBSensorGPS(const CanardTransfer &receive)
|
|
||||||
{
|
|
||||||
PX4_INFO("NodeID %i GPS sensor msg", receive.remote_node_id);
|
|
||||||
|
|
||||||
sensor_gps_s *gps_msg = (sensor_gps_s *)receive.payload;
|
|
||||||
|
|
||||||
return _sensor_gps_pub.publish(*gps_msg) ? 0 : -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool UavcanMixingInterface::updateOutputs(bool stop_motors, uint16_t outputs[MAX_ACTUATORS], unsigned num_outputs,
|
bool UavcanMixingInterface::updateOutputs(bool stop_motors, uint16_t outputs[MAX_ACTUATORS], unsigned num_outputs,
|
||||||
unsigned num_control_groups_updated)
|
unsigned num_control_groups_updated)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -78,6 +78,9 @@
|
|||||||
#include "Subscribers/NodeIDAllocationData.hpp"
|
#include "Subscribers/NodeIDAllocationData.hpp"
|
||||||
#include "Subscribers/LegacyBatteryInfo.hpp"
|
#include "Subscribers/LegacyBatteryInfo.hpp"
|
||||||
|
|
||||||
|
// uORB over UAVCAN subscribers
|
||||||
|
#include "Subscribers/uORB/sensor_gps.hpp"
|
||||||
|
|
||||||
#include "ServiceClients/GetInfo.hpp"
|
#include "ServiceClients/GetInfo.hpp"
|
||||||
#include "ServiceClients/Access.hpp"
|
#include "ServiceClients/Access.hpp"
|
||||||
|
|
||||||
@@ -162,14 +165,11 @@ private:
|
|||||||
void Run() override;
|
void Run() override;
|
||||||
void fill_node_info();
|
void fill_node_info();
|
||||||
|
|
||||||
|
void transmit();
|
||||||
|
|
||||||
// Sends a heartbeat at 1s intervals
|
// Sends a heartbeat at 1s intervals
|
||||||
void sendHeartbeat();
|
void sendHeartbeat();
|
||||||
|
|
||||||
int handlePnpNodeIDAllocationData(const CanardTransfer &receive);
|
|
||||||
int handleRegisterList(const CanardTransfer &receive);
|
|
||||||
int handleRegisterAccess(const CanardTransfer &receive);
|
|
||||||
int handleUORBSensorGPS(const CanardTransfer &receive);
|
|
||||||
|
|
||||||
void *_uavcan_heap{nullptr};
|
void *_uavcan_heap{nullptr};
|
||||||
|
|
||||||
CanardInterface *const _can_interface;
|
CanardInterface *const _can_interface;
|
||||||
@@ -185,14 +185,9 @@ private:
|
|||||||
pthread_mutex_t _node_mutex;
|
pthread_mutex_t _node_mutex;
|
||||||
|
|
||||||
CanardRxSubscription _heartbeat_subscription;
|
CanardRxSubscription _heartbeat_subscription;
|
||||||
CanardRxSubscription _drone_srv_gps_subscription;
|
|
||||||
|
|
||||||
uORB::Subscription _battery_status_sub{ORB_ID(battery_status)};
|
|
||||||
uORB::Subscription _parameter_update_sub{ORB_ID(parameter_update)};
|
uORB::Subscription _parameter_update_sub{ORB_ID(parameter_update)};
|
||||||
|
|
||||||
uORB::Publication<battery_status_s> _battery_status_pub{ORB_ID(battery_status)};
|
|
||||||
uORB::Publication<sensor_gps_s> _sensor_gps_pub{ORB_ID(sensor_gps)};
|
|
||||||
|
|
||||||
perf_counter_t _cycle_perf{perf_alloc(PC_ELAPSED, MODULE_NAME": cycle time")};
|
perf_counter_t _cycle_perf{perf_alloc(PC_ELAPSED, MODULE_NAME": cycle time")};
|
||||||
perf_counter_t _interval_perf{perf_alloc(PC_INTERVAL, MODULE_NAME": cycle interval")};
|
perf_counter_t _interval_perf{perf_alloc(PC_INTERVAL, MODULE_NAME": cycle interval")};
|
||||||
|
|
||||||
@@ -201,15 +196,6 @@ private:
|
|||||||
hrt_abstime _uavcan_node_heartbeat_last{0};
|
hrt_abstime _uavcan_node_heartbeat_last{0};
|
||||||
CanardTransferID _uavcan_node_heartbeat_transfer_id{0};
|
CanardTransferID _uavcan_node_heartbeat_transfer_id{0};
|
||||||
|
|
||||||
/* Temporary hardcoded port IDs used by the register interface
|
|
||||||
* for demo purposes untill we have nice interface (QGC or latter)
|
|
||||||
* to configure the nodes
|
|
||||||
*/
|
|
||||||
const uint16_t gps_port_id = 1235;
|
|
||||||
|
|
||||||
CanardTransferID _uavcan_register_list_request_transfer_id{0};
|
|
||||||
CanardTransferID _uavcan_register_access_request_transfer_id{0};
|
|
||||||
|
|
||||||
DEFINE_PARAMETERS(
|
DEFINE_PARAMETERS(
|
||||||
(ParamInt<px4::params::UAVCAN_V1_ENABLE>) _param_uavcan_v1_enable,
|
(ParamInt<px4::params::UAVCAN_V1_ENABLE>) _param_uavcan_v1_enable,
|
||||||
(ParamInt<px4::params::UAVCAN_V1_ID>) _param_uavcan_v1_id,
|
(ParamInt<px4::params::UAVCAN_V1_ID>) _param_uavcan_v1_id,
|
||||||
@@ -220,7 +206,7 @@ private:
|
|||||||
|
|
||||||
UavcanParamManager _param_manager;
|
UavcanParamManager _param_manager;
|
||||||
|
|
||||||
NodeManager _node_manager {_canard_instance};
|
NodeManager _node_manager {_canard_instance, _param_manager};
|
||||||
|
|
||||||
UavcanGnssPublisher _gps_pub {_canard_instance, _param_manager};
|
UavcanGnssPublisher _gps_pub {_canard_instance, _param_manager};
|
||||||
|
|
||||||
@@ -238,6 +224,8 @@ private:
|
|||||||
UavcanLegacyBatteryInfoSubscriber _legacybms_sub {_canard_instance, _param_manager, 0};
|
UavcanLegacyBatteryInfoSubscriber _legacybms_sub {_canard_instance, _param_manager, 0};
|
||||||
UavcanNodeIDAllocationDataSubscriber _nodeid_sub {_canard_instance, _node_manager};
|
UavcanNodeIDAllocationDataSubscriber _nodeid_sub {_canard_instance, _node_manager};
|
||||||
|
|
||||||
|
UORB_over_UAVCAN_sensor_gps_Subscriber _sensor_gps_sub {_canard_instance, _param_manager, 0};
|
||||||
|
|
||||||
UavcanGetInfoResponse _getinfo_rsp {_canard_instance};
|
UavcanGetInfoResponse _getinfo_rsp {_canard_instance};
|
||||||
UavcanAccessResponse _access_rsp {_canard_instance, _param_manager};
|
UavcanAccessResponse _access_rsp {_canard_instance, _param_manager};
|
||||||
|
|
||||||
@@ -245,7 +233,7 @@ private:
|
|||||||
UavcanListServiceReply _list_service {_canard_instance, _node_manager};
|
UavcanListServiceReply _list_service {_canard_instance, _node_manager};
|
||||||
|
|
||||||
// Subscriber objects: Any object used to bridge a UAVCAN message to a uORB message
|
// Subscriber objects: Any object used to bridge a UAVCAN message to a uORB message
|
||||||
UavcanDynamicPortSubscriber *_dynsubscribers[5] {&_gps0_sub, &_gps1_sub, &_bms0_sub, &_esc_sub, &_legacybms_sub}; /// TODO: turn into List<UavcanSubscription*>
|
UavcanDynamicPortSubscriber *_dynsubscribers[6] {&_gps0_sub, &_gps1_sub, &_bms0_sub, &_esc_sub, &_legacybms_sub, &_sensor_gps_sub}; /// TODO: turn into List<UavcanSubscription*>
|
||||||
UavcanBaseSubscriber *_subscribers[5] {&_nodeid_sub, &_getinfo_rsp, &_access_rsp, &_access_service, &_list_service}; /// TODO: turn into List<UavcanSubscription*>
|
UavcanBaseSubscriber *_subscribers[5] {&_nodeid_sub, &_getinfo_rsp, &_access_rsp, &_access_service, &_list_service}; /// TODO: turn into List<UavcanSubscription*>
|
||||||
|
|
||||||
UavcanMixingInterface _mixing_output {_node_mutex, _esc_controller};
|
UavcanMixingInterface _mixing_output {_node_mutex, _esc_controller};
|
||||||
|
|||||||
@@ -103,3 +103,6 @@ PARAM_DEFINE_INT32(UCAN1_LG_BMS_PID, 0);
|
|||||||
PARAM_DEFINE_INT32(UCAN1_ESC_PUB, 0);
|
PARAM_DEFINE_INT32(UCAN1_ESC_PUB, 0);
|
||||||
PARAM_DEFINE_INT32(UCAN1_GPS_PUB, 0);
|
PARAM_DEFINE_INT32(UCAN1_GPS_PUB, 0);
|
||||||
PARAM_DEFINE_INT32(UCAN1_SERVO_PUB, 0);
|
PARAM_DEFINE_INT32(UCAN1_SERVO_PUB, 0);
|
||||||
|
|
||||||
|
// uORB over UAVCAN
|
||||||
|
PARAM_DEFINE_INT32(UCAN1_UORB_GPS, 0);
|
||||||
|
|||||||
@@ -381,7 +381,7 @@ static int canard_daemon(int argc, char *argv[])
|
|||||||
/* Init UAVCAN register interfaces */
|
/* Init UAVCAN register interfaces */
|
||||||
uavcan_node_GetInfo_Response_1_0 node_information; // TODO ADD INFO
|
uavcan_node_GetInfo_Response_1_0 node_information; // TODO ADD INFO
|
||||||
uavcan_register_interface_init(&ins, &node_information);
|
uavcan_register_interface_init(&ins, &node_information);
|
||||||
uavcan_register_interface_add_entry("gnss_uorb", set_gps_uorb_port_id, get_gps_uorb_port_id);
|
uavcan_register_interface_add_entry("uorb.sensor_gps.0", set_gps_uorb_port_id, get_gps_uorb_port_id);
|
||||||
uavcan_register_interface_add_entry("gnss_fix", set_gps_fix_port_id, get_gps_fix_port_id);
|
uavcan_register_interface_add_entry("gnss_fix", set_gps_fix_port_id, get_gps_fix_port_id);
|
||||||
uavcan_register_interface_add_entry("gnss_aux", set_gps_aux_port_id, get_gps_aux_port_id);
|
uavcan_register_interface_add_entry("gnss_aux", set_gps_aux_port_id, get_gps_aux_port_id);
|
||||||
|
|
||||||
|
|||||||
@@ -238,10 +238,13 @@ int32_t uavcan_register_interface_list_response(CanardInstance *ins, CanardTrans
|
|||||||
|
|
||||||
// Reponse magic start
|
// Reponse magic start
|
||||||
|
|
||||||
if (msg.index <= register_list_size) {
|
if (msg.index < register_list_size) {
|
||||||
response_msg.name.name.count = sprintf(response_msg.name.name.elements,
|
response_msg.name.name.count = sprintf(response_msg.name.name.elements,
|
||||||
"uavcan.pub.%s.id",
|
"uavcan.pub.%s.id",
|
||||||
register_list[msg.index].name);
|
register_list[msg.index].name);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
response_msg.name.name.count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO more option then pub (sub rate
|
//TODO more option then pub (sub rate
|
||||||
|
|||||||
@@ -164,6 +164,14 @@ bool param_modify_on_import(bson_node_t node)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 2021-04-30: translate ASPD_STALL to FW_AIRSPD_STALL
|
||||||
|
{
|
||||||
|
if (strcmp("ASPD_STALL", node->name) == 0) {
|
||||||
|
strcpy(node->name, "FW_AIRSPD_STALL");
|
||||||
|
PX4_INFO("copying %s -> %s", "ASPD_STALL", "FW_AIRSPD_STALL");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// translate (SPI) calibration ID parameters. This can be removed after the next release (current release=1.10)
|
// translate (SPI) calibration ID parameters. This can be removed after the next release (current release=1.10)
|
||||||
|
|
||||||
if (node->type != BSON_INT32) {
|
if (node->type != BSON_INT32) {
|
||||||
|
|||||||
@@ -171,7 +171,8 @@ private:
|
|||||||
(ParamFloat<px4::params::ASPD_FS_INTEG>) _tas_innov_integ_threshold, /**< innovation check integrator threshold */
|
(ParamFloat<px4::params::ASPD_FS_INTEG>) _tas_innov_integ_threshold, /**< innovation check integrator threshold */
|
||||||
(ParamInt<px4::params::ASPD_FS_T_STOP>) _checks_fail_delay, /**< delay to declare airspeed invalid */
|
(ParamInt<px4::params::ASPD_FS_T_STOP>) _checks_fail_delay, /**< delay to declare airspeed invalid */
|
||||||
(ParamInt<px4::params::ASPD_FS_T_START>) _checks_clear_delay, /**< delay to declare airspeed valid again */
|
(ParamInt<px4::params::ASPD_FS_T_START>) _checks_clear_delay, /**< delay to declare airspeed valid again */
|
||||||
(ParamFloat<px4::params::ASPD_STALL>) _airspeed_stall /**< stall speed*/
|
|
||||||
|
(ParamFloat<px4::params::FW_AIRSPD_STALL>) _param_fw_airspd_stall
|
||||||
)
|
)
|
||||||
|
|
||||||
void init(); /**< initialization of the airspeed validator instances */
|
void init(); /**< initialization of the airspeed validator instances */
|
||||||
@@ -295,8 +296,6 @@ AirspeedModule::Run()
|
|||||||
update_params();
|
update_params();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool armed = (_vehicle_status.arming_state == vehicle_status_s::ARMING_STATE_ARMED);
|
bool armed = (_vehicle_status.arming_state == vehicle_status_s::ARMING_STATE_ARMED);
|
||||||
|
|
||||||
// check for new connected airspeed sensors as long as we're disarmed
|
// check for new connected airspeed sensors as long as we're disarmed
|
||||||
@@ -315,7 +314,7 @@ AirspeedModule::Run()
|
|||||||
// for fixed-wing landings.
|
// for fixed-wing landings.
|
||||||
const bool in_air_fixed_wing = !_vehicle_land_detected.landed &&
|
const bool in_air_fixed_wing = !_vehicle_land_detected.landed &&
|
||||||
_position_setpoint.type != position_setpoint_s::SETPOINT_TYPE_LAND &&
|
_position_setpoint.type != position_setpoint_s::SETPOINT_TYPE_LAND &&
|
||||||
_vehicle_status.system_type == vehicle_status_s::VEHICLE_TYPE_FIXED_WING;
|
_vehicle_status.vehicle_type == vehicle_status_s::VEHICLE_TYPE_FIXED_WING;
|
||||||
|
|
||||||
// Prepare data for airspeed_validator
|
// Prepare data for airspeed_validator
|
||||||
struct airspeed_validator_update_data input_data = {};
|
struct airspeed_validator_update_data input_data = {};
|
||||||
@@ -349,7 +348,9 @@ AirspeedModule::Run()
|
|||||||
input_data.air_temperature_celsius = airspeed_raw.air_temperature_celsius;
|
input_data.air_temperature_celsius = airspeed_raw.air_temperature_celsius;
|
||||||
|
|
||||||
// takeoff situation is active from start till one of the sensors' IAS or groundspeed_CAS is above stall speed
|
// takeoff situation is active from start till one of the sensors' IAS or groundspeed_CAS is above stall speed
|
||||||
if (airspeed_raw.indicated_airspeed_m_s > _airspeed_stall.get() || _ground_minus_wind_CAS > _airspeed_stall.get()) {
|
if (_in_takeoff_situation &&
|
||||||
|
(airspeed_raw.indicated_airspeed_m_s > _param_fw_airspd_stall.get() ||
|
||||||
|
_ground_minus_wind_CAS > _param_fw_airspd_stall.get())) {
|
||||||
_in_takeoff_situation = false;
|
_in_takeoff_situation = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -410,7 +411,7 @@ void AirspeedModule::update_params()
|
|||||||
_airspeed_validator[i].set_tas_innov_integ_threshold(_tas_innov_integ_threshold.get());
|
_airspeed_validator[i].set_tas_innov_integ_threshold(_tas_innov_integ_threshold.get());
|
||||||
_airspeed_validator[i].set_checks_fail_delay(_checks_fail_delay.get());
|
_airspeed_validator[i].set_checks_fail_delay(_checks_fail_delay.get());
|
||||||
_airspeed_validator[i].set_checks_clear_delay(_checks_clear_delay.get());
|
_airspeed_validator[i].set_checks_clear_delay(_checks_clear_delay.get());
|
||||||
_airspeed_validator[i].set_airspeed_stall(_airspeed_stall.get());
|
_airspeed_validator[i].set_airspeed_stall(_param_fw_airspd_stall.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the airspeed scale estimation is enabled and the airspeed is valid,
|
// if the airspeed scale estimation is enabled and the airspeed is valid,
|
||||||
|
|||||||
@@ -184,15 +184,3 @@ PARAM_DEFINE_INT32(ASPD_FS_T_STOP, 2);
|
|||||||
* @max 1000
|
* @max 1000
|
||||||
*/
|
*/
|
||||||
PARAM_DEFINE_INT32(ASPD_FS_T_START, -1);
|
PARAM_DEFINE_INT32(ASPD_FS_T_START, -1);
|
||||||
|
|
||||||
/**
|
|
||||||
* Airspeed fault detection stall airspeed
|
|
||||||
*
|
|
||||||
* This is the minimum indicated airspeed at which the wing can produce 1g of lift.
|
|
||||||
* It is used by the airspeed sensor fault detection and failsafe calculation to detect a
|
|
||||||
* significant airspeed low measurement error condition and should be set based on flight test for reliable operation.
|
|
||||||
*
|
|
||||||
* @group Airspeed Validator
|
|
||||||
* @unit m/s
|
|
||||||
*/
|
|
||||||
PARAM_DEFINE_FLOAT(ASPD_STALL, 10.0f);
|
|
||||||
|
|||||||
@@ -184,10 +184,10 @@ bool PreFlightCheck::preflightCheck(orb_advert_t *mavlink_log_pub, vehicle_statu
|
|||||||
int32_t max_airspeed_check_en = 0;
|
int32_t max_airspeed_check_en = 0;
|
||||||
param_get(param_find("COM_ARM_ARSP_EN"), &max_airspeed_check_en);
|
param_get(param_find("COM_ARM_ARSP_EN"), &max_airspeed_check_en);
|
||||||
|
|
||||||
float airspeed_stall = 10.0f;
|
float airspeed_trim = 10.0f;
|
||||||
param_get(param_find("ASPD_STALL"), &airspeed_stall);
|
param_get(param_find("FW_AIRSPD_TRIM"), &airspeed_trim);
|
||||||
|
|
||||||
const float arming_max_airspeed_allowed = airspeed_stall / 2.0f; // set to half of stall speed
|
const float arming_max_airspeed_allowed = airspeed_trim / 2.0f; // set to half of trim airspeed
|
||||||
|
|
||||||
if (!airspeedCheck(mavlink_log_pub, status, optional, report_failures, prearm, (bool)max_airspeed_check_en,
|
if (!airspeedCheck(mavlink_log_pub, status, optional, report_failures, prearm, (bool)max_airspeed_check_en,
|
||||||
arming_max_airspeed_allowed)
|
arming_max_airspeed_allowed)
|
||||||
|
|||||||
@@ -86,6 +86,7 @@ public:
|
|||||||
bool esc_check = false;
|
bool esc_check = false;
|
||||||
bool global_position = false;
|
bool global_position = false;
|
||||||
bool mission = false;
|
bool mission = false;
|
||||||
|
bool geofence = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool preArmCheck(orb_advert_t *mavlink_log_pub, const vehicle_status_flags_s &status_flags,
|
static bool preArmCheck(orb_advert_t *mavlink_log_pub, const vehicle_status_flags_s &status_flags,
|
||||||
|
|||||||
@@ -65,7 +65,12 @@ bool PreFlightCheck::accelerometerCheck(orb_advert_t *mavlink_log_pub, vehicle_s
|
|||||||
|
|
||||||
device_id = accel.get().device_id;
|
device_id = accel.get().device_id;
|
||||||
|
|
||||||
calibration_valid = (calibration::FindCalibrationIndex("ACC", device_id) >= 0);
|
if (status.hil_state == vehicle_status_s::HIL_STATE_ON) {
|
||||||
|
calibration_valid = true;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
calibration_valid = (calibration::FindCalibrationIndex("ACC", device_id) >= 0);
|
||||||
|
}
|
||||||
|
|
||||||
if (!calibration_valid) {
|
if (!calibration_valid) {
|
||||||
if (report_fail) {
|
if (report_fail) {
|
||||||
|
|||||||
@@ -64,7 +64,12 @@ bool PreFlightCheck::gyroCheck(orb_advert_t *mavlink_log_pub, vehicle_status_s &
|
|||||||
|
|
||||||
device_id = gyro.get().device_id;
|
device_id = gyro.get().device_id;
|
||||||
|
|
||||||
calibration_valid = (calibration::FindCalibrationIndex("GYRO", device_id) >= 0);
|
if (status.hil_state == vehicle_status_s::HIL_STATE_ON) {
|
||||||
|
calibration_valid = true;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
calibration_valid = (calibration::FindCalibrationIndex("GYRO", device_id) >= 0);
|
||||||
|
}
|
||||||
|
|
||||||
if (!calibration_valid) {
|
if (!calibration_valid) {
|
||||||
if (report_fail) {
|
if (report_fail) {
|
||||||
|
|||||||
@@ -66,7 +66,12 @@ bool PreFlightCheck::magnetometerCheck(orb_advert_t *mavlink_log_pub, vehicle_st
|
|||||||
|
|
||||||
device_id = magnetometer.get().device_id;
|
device_id = magnetometer.get().device_id;
|
||||||
|
|
||||||
calibration_valid = (calibration::FindCalibrationIndex("MAG", device_id) >= 0);
|
if (status.hil_state == vehicle_status_s::HIL_STATE_ON) {
|
||||||
|
calibration_valid = true;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
calibration_valid = (calibration::FindCalibrationIndex("MAG", device_id) >= 0);
|
||||||
|
}
|
||||||
|
|
||||||
if (!calibration_valid) {
|
if (!calibration_valid) {
|
||||||
if (report_fail) {
|
if (report_fail) {
|
||||||
|
|||||||
@@ -63,6 +63,11 @@ bool PreFlightCheck::powerCheck(orb_advert_t *mavlink_log_pub, const vehicle_sta
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (status.hil_state == vehicle_status_s::HIL_STATE_ON) {
|
||||||
|
// Ignore power check in HITL.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
uORB::SubscriptionData<system_power_s> system_power_sub{ORB_ID(system_power)};
|
uORB::SubscriptionData<system_power_s> system_power_sub{ORB_ID(system_power)};
|
||||||
system_power_sub.update();
|
system_power_sub.update();
|
||||||
const system_power_s &system_power = system_power_sub.get();
|
const system_power_s &system_power = system_power_sub.get();
|
||||||
|
|||||||
@@ -168,6 +168,14 @@ bool PreFlightCheck::preArmCheck(orb_advert_t *mavlink_log_pub, const vehicle_st
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (arm_requirements.geofence && status.geofence_violated) {
|
||||||
|
if (report_fail) {
|
||||||
|
mavlink_log_critical(mavlink_log_pub, "Arming denied, vehicle outside geofence");
|
||||||
|
}
|
||||||
|
|
||||||
|
prearm_ok = false;
|
||||||
|
}
|
||||||
|
|
||||||
// Arm Requirements: authorization
|
// Arm Requirements: authorization
|
||||||
// check last, and only if everything else has passed
|
// check last, and only if everything else has passed
|
||||||
if (arm_requirements.arm_authorization && prearm_ok) {
|
if (arm_requirements.arm_authorization && prearm_ok) {
|
||||||
|
|||||||
@@ -1733,6 +1733,7 @@ Commander::run()
|
|||||||
_arm_requirements.esc_check = _param_escs_checks_required.get();
|
_arm_requirements.esc_check = _param_escs_checks_required.get();
|
||||||
_arm_requirements.global_position = !_param_arm_without_gps.get();
|
_arm_requirements.global_position = !_param_arm_without_gps.get();
|
||||||
_arm_requirements.mission = _param_arm_mission_required.get();
|
_arm_requirements.mission = _param_arm_mission_required.get();
|
||||||
|
_arm_requirements.geofence = _param_geofence_action.get() > geofence_result_s::GF_ACTION_NONE;
|
||||||
|
|
||||||
/* flight mode slots */
|
/* flight mode slots */
|
||||||
_flight_mode_slots[0] = _param_fltmode_1.get();
|
_flight_mode_slots[0] = _param_fltmode_1.get();
|
||||||
@@ -2114,6 +2115,7 @@ Commander::run()
|
|||||||
|
|
||||||
/* start geofence result check */
|
/* start geofence result check */
|
||||||
_geofence_result_sub.update(&_geofence_result);
|
_geofence_result_sub.update(&_geofence_result);
|
||||||
|
_status.geofence_violated = _geofence_result.geofence_violated;
|
||||||
|
|
||||||
const bool in_low_battery_failsafe = _battery_warning > battery_status_s::BATTERY_WARNING_LOW;
|
const bool in_low_battery_failsafe = _battery_warning > battery_status_s::BATTERY_WARNING_LOW;
|
||||||
|
|
||||||
|
|||||||
@@ -199,7 +199,7 @@ int do_airspeed_calibration(orb_advert_t *mavlink_log_pub)
|
|||||||
/* wait 500 ms to ensure parameter propagated through the system */
|
/* wait 500 ms to ensure parameter propagated through the system */
|
||||||
px4_usleep(500 * 1000);
|
px4_usleep(500 * 1000);
|
||||||
|
|
||||||
calibration_log_critical(mavlink_log_pub, "[cal] Blow across front of pitot without touching");
|
calibration_log_critical(mavlink_log_pub, "[cal] Blow into front of pitot without touching");
|
||||||
|
|
||||||
calibration_counter = 0;
|
calibration_counter = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -989,7 +989,7 @@ PARAM_DEFINE_FLOAT(COM_LKDOWN_TKO, 3.0f);
|
|||||||
/**
|
/**
|
||||||
* Enable preflight check for maximal allowed airspeed when arming.
|
* Enable preflight check for maximal allowed airspeed when arming.
|
||||||
*
|
*
|
||||||
* Deny arming if the current airspeed measurement is greater than half the stall speed (ASPD_STALL).
|
* Deny arming if the current airspeed measurement is greater than half the cruise airspeed (FW_AIRSPD_TRIM).
|
||||||
* Excessive airspeed measurements on ground are either caused by wind or bad airspeed calibration.
|
* Excessive airspeed measurements on ground are either caused by wind or bad airspeed calibration.
|
||||||
*
|
*
|
||||||
* @group Commander
|
* @group Commander
|
||||||
|
|||||||
@@ -467,6 +467,18 @@ static calibrate_return mag_calibration_worker(detect_orientation_return orienta
|
|||||||
|
|
||||||
calibrate_return mag_calibrate_all(orb_advert_t *mavlink_log_pub, int32_t cal_mask)
|
calibrate_return mag_calibrate_all(orb_advert_t *mavlink_log_pub, int32_t cal_mask)
|
||||||
{
|
{
|
||||||
|
// We should not try to subscribe if the topic doesn't actually exist and can be counted.
|
||||||
|
const unsigned orb_mag_count = orb_group_count(ORB_ID(sensor_mag));
|
||||||
|
|
||||||
|
// Warn that we will not calibrate more than MAX_GYROS gyroscopes
|
||||||
|
if (orb_mag_count > MAX_MAGS) {
|
||||||
|
calibration_log_critical(mavlink_log_pub, "Detected %u mags, but will calibrate only %u", orb_mag_count, MAX_MAGS);
|
||||||
|
|
||||||
|
} else if (orb_mag_count < 1) {
|
||||||
|
calibration_log_critical(mavlink_log_pub, "No mags found");
|
||||||
|
return calibrate_return_error;
|
||||||
|
}
|
||||||
|
|
||||||
calibrate_return result = calibrate_return_ok;
|
calibrate_return result = calibrate_return_ok;
|
||||||
|
|
||||||
mag_worker_data_t worker_data{};
|
mag_worker_data_t worker_data{};
|
||||||
|
|||||||
@@ -1742,7 +1742,8 @@ int EKF2::task_spawn(int argc, char *argv[])
|
|||||||
|
|
||||||
while ((multi_instances_allocated < multi_instances)
|
while ((multi_instances_allocated < multi_instances)
|
||||||
&& (vehicle_status_sub.get().arming_state != vehicle_status_s::ARMING_STATE_ARMED)
|
&& (vehicle_status_sub.get().arming_state != vehicle_status_s::ARMING_STATE_ARMED)
|
||||||
&& (hrt_elapsed_time(&time_started) < 30_s)) {
|
&& ((hrt_elapsed_time(&time_started) < 30_s)
|
||||||
|
|| (vehicle_status_sub.get().hil_state == vehicle_status_s::HIL_STATE_ON))) {
|
||||||
|
|
||||||
vehicle_status_sub.update();
|
vehicle_status_sub.update();
|
||||||
|
|
||||||
|
|||||||
@@ -315,6 +315,11 @@ bool EKF2Selector::UpdateErrorScores()
|
|||||||
if (error_delta > 0 || error_delta < -threshold) {
|
if (error_delta > 0 || error_delta < -threshold) {
|
||||||
_instance[i].relative_test_ratio += error_delta;
|
_instance[i].relative_test_ratio += error_delta;
|
||||||
_instance[i].relative_test_ratio = constrain(_instance[i].relative_test_ratio, -_rel_err_score_lim, _rel_err_score_lim);
|
_instance[i].relative_test_ratio = constrain(_instance[i].relative_test_ratio, -_rel_err_score_lim, _rel_err_score_lim);
|
||||||
|
|
||||||
|
if ((error_delta < -threshold) && (_instance[i].relative_test_ratio < 1.f)) {
|
||||||
|
// increase status publication rate if there's movement towards a potential instance change
|
||||||
|
_selector_status_publish = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -650,7 +655,6 @@ void EKF2Selector::Run()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (updated) {
|
if (updated) {
|
||||||
|
|
||||||
const uint8_t available_instances_prev = _available_instances;
|
const uint8_t available_instances_prev = _available_instances;
|
||||||
const uint8_t selected_instance_prev = _selected_instance;
|
const uint8_t selected_instance_prev = _selected_instance;
|
||||||
const uint32_t instance_changed_count_prev = _instance_changed_count;
|
const uint32_t instance_changed_count_prev = _instance_changed_count;
|
||||||
@@ -719,32 +723,7 @@ void EKF2Selector::Run()
|
|||||||
|| (last_instance_change_prev != _last_instance_change)
|
|| (last_instance_change_prev != _last_instance_change)
|
||||||
|| _accel_fault_detected || _gyro_fault_detected) {
|
|| _accel_fault_detected || _gyro_fault_detected) {
|
||||||
|
|
||||||
estimator_selector_status_s selector_status{};
|
PublishEstimatorSelectorStatus();
|
||||||
selector_status.primary_instance = _selected_instance;
|
|
||||||
selector_status.instances_available = _available_instances;
|
|
||||||
selector_status.instance_changed_count = _instance_changed_count;
|
|
||||||
selector_status.last_instance_change = _last_instance_change;
|
|
||||||
selector_status.accel_device_id = _instance[_selected_instance].accel_device_id;
|
|
||||||
selector_status.baro_device_id = _instance[_selected_instance].baro_device_id;
|
|
||||||
selector_status.gyro_device_id = _instance[_selected_instance].gyro_device_id;
|
|
||||||
selector_status.mag_device_id = _instance[_selected_instance].mag_device_id;
|
|
||||||
selector_status.gyro_fault_detected = _gyro_fault_detected;
|
|
||||||
selector_status.accel_fault_detected = _accel_fault_detected;
|
|
||||||
|
|
||||||
for (int i = 0; i < EKF2_MAX_INSTANCES; i++) {
|
|
||||||
selector_status.combined_test_ratio[i] = _instance[i].combined_test_ratio;
|
|
||||||
selector_status.relative_test_ratio[i] = _instance[i].relative_test_ratio;
|
|
||||||
selector_status.healthy[i] = _instance[i].healthy;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < IMU_STATUS_SIZE; i++) {
|
|
||||||
selector_status.accumulated_gyro_error[i] = _accumulated_gyro_error[i];
|
|
||||||
selector_status.accumulated_accel_error[i] = _accumulated_accel_error[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
selector_status.timestamp = hrt_absolute_time();
|
|
||||||
_estimator_selector_status_pub.publish(selector_status);
|
|
||||||
_last_status_publish = selector_status.timestamp;
|
|
||||||
_selector_status_publish = false;
|
_selector_status_publish = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -757,6 +736,36 @@ void EKF2Selector::Run()
|
|||||||
PublishWindEstimate();
|
PublishWindEstimate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EKF2Selector::PublishEstimatorSelectorStatus()
|
||||||
|
{
|
||||||
|
estimator_selector_status_s selector_status{};
|
||||||
|
selector_status.primary_instance = _selected_instance;
|
||||||
|
selector_status.instances_available = _available_instances;
|
||||||
|
selector_status.instance_changed_count = _instance_changed_count;
|
||||||
|
selector_status.last_instance_change = _last_instance_change;
|
||||||
|
selector_status.accel_device_id = _instance[_selected_instance].accel_device_id;
|
||||||
|
selector_status.baro_device_id = _instance[_selected_instance].baro_device_id;
|
||||||
|
selector_status.gyro_device_id = _instance[_selected_instance].gyro_device_id;
|
||||||
|
selector_status.mag_device_id = _instance[_selected_instance].mag_device_id;
|
||||||
|
selector_status.gyro_fault_detected = _gyro_fault_detected;
|
||||||
|
selector_status.accel_fault_detected = _accel_fault_detected;
|
||||||
|
|
||||||
|
for (int i = 0; i < EKF2_MAX_INSTANCES; i++) {
|
||||||
|
selector_status.combined_test_ratio[i] = _instance[i].combined_test_ratio;
|
||||||
|
selector_status.relative_test_ratio[i] = _instance[i].relative_test_ratio;
|
||||||
|
selector_status.healthy[i] = _instance[i].healthy;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < IMU_STATUS_SIZE; i++) {
|
||||||
|
selector_status.accumulated_gyro_error[i] = _accumulated_gyro_error[i];
|
||||||
|
selector_status.accumulated_accel_error[i] = _accumulated_accel_error[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
selector_status.timestamp = hrt_absolute_time();
|
||||||
|
_estimator_selector_status_pub.publish(selector_status);
|
||||||
|
_last_status_publish = selector_status.timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
void EKF2Selector::PrintStatus()
|
void EKF2Selector::PrintStatus()
|
||||||
{
|
{
|
||||||
PX4_INFO("available instances: %d", _available_instances);
|
PX4_INFO("available instances: %d", _available_instances);
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ private:
|
|||||||
static constexpr uint64_t FILTER_UPDATE_PERIOD{10_ms};
|
static constexpr uint64_t FILTER_UPDATE_PERIOD{10_ms};
|
||||||
|
|
||||||
void Run() override;
|
void Run() override;
|
||||||
|
void PublishEstimatorSelectorStatus();
|
||||||
void PublishVehicleAttitude();
|
void PublishVehicleAttitude();
|
||||||
void PublishVehicleLocalPosition();
|
void PublishVehicleLocalPosition();
|
||||||
void PublishVehicleGlobalPosition();
|
void PublishVehicleGlobalPosition();
|
||||||
|
|||||||
@@ -242,21 +242,21 @@ float FixedwingAttitudeControl::get_airspeed_and_update_scaling()
|
|||||||
} else {
|
} else {
|
||||||
// VTOL: if we have no airspeed available and we are in hover mode then assume the lowest airspeed possible
|
// VTOL: if we have no airspeed available and we are in hover mode then assume the lowest airspeed possible
|
||||||
// this assumption is good as long as the vehicle is not hovering in a headwind which is much larger
|
// this assumption is good as long as the vehicle is not hovering in a headwind which is much larger
|
||||||
// than the minimum airspeed
|
// than the stall airspeed
|
||||||
if (_vehicle_status.is_vtol && _vehicle_status.vehicle_type == vehicle_status_s::VEHICLE_TYPE_ROTARY_WING
|
if (_vehicle_status.is_vtol && _vehicle_status.vehicle_type == vehicle_status_s::VEHICLE_TYPE_ROTARY_WING
|
||||||
&& !_vehicle_status.in_transition_mode) {
|
&& !_vehicle_status.in_transition_mode) {
|
||||||
airspeed = _param_fw_airspd_min.get();
|
airspeed = _param_fw_airspd_stall.get();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For scaling our actuators using anything less than the min (close to stall)
|
* For scaling our actuators using anything less than the stall
|
||||||
* speed doesn't make any sense - its the strongest reasonable deflection we
|
* speed doesn't make any sense - its the strongest reasonable deflection we
|
||||||
* want to do in flight and its the baseline a human pilot would choose.
|
* want to do in flight and its the baseline a human pilot would choose.
|
||||||
*
|
*
|
||||||
* Forcing the scaling to this value allows reasonable handheld tests.
|
* Forcing the scaling to this value allows reasonable handheld tests.
|
||||||
*/
|
*/
|
||||||
const float airspeed_constrained = constrain(constrain(airspeed, _param_fw_airspd_min.get(),
|
const float airspeed_constrained = constrain(constrain(airspeed, _param_fw_airspd_stall.get(),
|
||||||
_param_fw_airspd_max.get()), 0.1f, 1000.0f);
|
_param_fw_airspd_max.get()), 0.1f, 1000.0f);
|
||||||
|
|
||||||
_airspeed_scaling = (_param_fw_arsp_scale_en.get()) ? (_param_fw_airspd_trim.get() / airspeed_constrained) : 1.0f;
|
_airspeed_scaling = (_param_fw_arsp_scale_en.get()) ? (_param_fw_airspd_trim.get() / airspeed_constrained) : 1.0f;
|
||||||
@@ -427,7 +427,7 @@ void FixedwingAttitudeControl::Run()
|
|||||||
control_input.roll_setpoint = _att_sp.roll_body;
|
control_input.roll_setpoint = _att_sp.roll_body;
|
||||||
control_input.pitch_setpoint = _att_sp.pitch_body;
|
control_input.pitch_setpoint = _att_sp.pitch_body;
|
||||||
control_input.yaw_setpoint = _att_sp.yaw_body;
|
control_input.yaw_setpoint = _att_sp.yaw_body;
|
||||||
control_input.airspeed_min = _param_fw_airspd_min.get();
|
control_input.airspeed_min = _param_fw_airspd_stall.get();
|
||||||
control_input.airspeed_max = _param_fw_airspd_max.get();
|
control_input.airspeed_max = _param_fw_airspd_max.get();
|
||||||
control_input.airspeed = airspeed;
|
control_input.airspeed = airspeed;
|
||||||
control_input.scaler = _airspeed_scaling;
|
control_input.scaler = _airspeed_scaling;
|
||||||
@@ -436,11 +436,11 @@ void FixedwingAttitudeControl::Run()
|
|||||||
if (wheel_control) {
|
if (wheel_control) {
|
||||||
_local_pos_sub.update(&_local_pos);
|
_local_pos_sub.update(&_local_pos);
|
||||||
|
|
||||||
/* Use min airspeed to calculate ground speed scaling region.
|
/* Use stall airspeed to calculate ground speed scaling region.
|
||||||
* Don't scale below gspd_scaling_trim
|
* Don't scale below gspd_scaling_trim
|
||||||
*/
|
*/
|
||||||
float groundspeed = sqrtf(_local_pos.vx * _local_pos.vx + _local_pos.vy * _local_pos.vy);
|
float groundspeed = sqrtf(_local_pos.vx * _local_pos.vx + _local_pos.vy * _local_pos.vy);
|
||||||
float gspd_scaling_trim = (_param_fw_airspd_min.get() * 0.6f);
|
float gspd_scaling_trim = (_param_fw_airspd_stall.get());
|
||||||
|
|
||||||
control_input.groundspeed = groundspeed;
|
control_input.groundspeed = groundspeed;
|
||||||
|
|
||||||
@@ -477,11 +477,11 @@ void FixedwingAttitudeControl::Run()
|
|||||||
float trim_yaw = _param_trim_yaw.get();
|
float trim_yaw = _param_trim_yaw.get();
|
||||||
|
|
||||||
if (airspeed < _param_fw_airspd_trim.get()) {
|
if (airspeed < _param_fw_airspd_trim.get()) {
|
||||||
trim_roll += gradual(airspeed, _param_fw_airspd_min.get(), _param_fw_airspd_trim.get(), _param_fw_dtrim_r_vmin.get(),
|
trim_roll += gradual(airspeed, _param_fw_airspd_stall.get(), _param_fw_airspd_trim.get(), _param_fw_dtrim_r_vmin.get(),
|
||||||
0.0f);
|
0.0f);
|
||||||
trim_pitch += gradual(airspeed, _param_fw_airspd_min.get(), _param_fw_airspd_trim.get(), _param_fw_dtrim_p_vmin.get(),
|
trim_pitch += gradual(airspeed, _param_fw_airspd_stall.get(), _param_fw_airspd_trim.get(), _param_fw_dtrim_p_vmin.get(),
|
||||||
0.0f);
|
0.0f);
|
||||||
trim_yaw += gradual(airspeed, _param_fw_airspd_min.get(), _param_fw_airspd_trim.get(), _param_fw_dtrim_y_vmin.get(),
|
trim_yaw += gradual(airspeed, _param_fw_airspd_stall.get(), _param_fw_airspd_trim.get(), _param_fw_dtrim_y_vmin.get(),
|
||||||
0.0f);
|
0.0f);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -147,7 +147,7 @@ private:
|
|||||||
(ParamFloat<px4::params::FW_ACRO_Z_MAX>) _param_fw_acro_z_max,
|
(ParamFloat<px4::params::FW_ACRO_Z_MAX>) _param_fw_acro_z_max,
|
||||||
|
|
||||||
(ParamFloat<px4::params::FW_AIRSPD_MAX>) _param_fw_airspd_max,
|
(ParamFloat<px4::params::FW_AIRSPD_MAX>) _param_fw_airspd_max,
|
||||||
(ParamFloat<px4::params::FW_AIRSPD_MIN>) _param_fw_airspd_min,
|
(ParamFloat<px4::params::FW_AIRSPD_STALL>) _param_fw_airspd_stall,
|
||||||
(ParamFloat<px4::params::FW_AIRSPD_TRIM>) _param_fw_airspd_trim,
|
(ParamFloat<px4::params::FW_AIRSPD_TRIM>) _param_fw_airspd_trim,
|
||||||
(ParamInt<px4::params::FW_ARSP_MODE>) _param_fw_arsp_mode,
|
(ParamInt<px4::params::FW_ARSP_MODE>) _param_fw_arsp_mode,
|
||||||
|
|
||||||
|
|||||||
@@ -141,19 +141,31 @@ FixedwingPositionControl::parameters_update()
|
|||||||
|
|
||||||
landing_status_publish();
|
landing_status_publish();
|
||||||
|
|
||||||
|
int check_ret = PX4_OK;
|
||||||
|
|
||||||
// sanity check parameters
|
// sanity check parameters
|
||||||
if ((_param_fw_airspd_max.get() < _param_fw_airspd_min.get()) ||
|
if (_param_fw_airspd_max.get() < _param_fw_airspd_min.get()) {
|
||||||
(_param_fw_airspd_max.get() < 5.0f) ||
|
mavlink_log_critical(&_mavlink_log_pub, "Config invalid: Airspeed max smaller than min");
|
||||||
(_param_fw_airspd_min.get() > 100.0f) ||
|
check_ret = PX4_ERROR;
|
||||||
(_param_fw_airspd_trim.get() < _param_fw_airspd_min.get()) ||
|
|
||||||
(_param_fw_airspd_trim.get() > _param_fw_airspd_max.get())) {
|
|
||||||
|
|
||||||
mavlink_log_critical(&_mavlink_log_pub, "Airspeed parameters invalid");
|
|
||||||
|
|
||||||
return PX4_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return PX4_OK;
|
if (_param_fw_airspd_max.get() < 5.0f || _param_fw_airspd_min.get() > 100.0f) {
|
||||||
|
mavlink_log_critical(&_mavlink_log_pub, "Config invalid: Airspeed max < 5 m/s or min > 100 m/s");
|
||||||
|
check_ret = PX4_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_param_fw_airspd_trim.get() < _param_fw_airspd_min.get() ||
|
||||||
|
_param_fw_airspd_trim.get() > _param_fw_airspd_max.get()) {
|
||||||
|
mavlink_log_critical(&_mavlink_log_pub, "Config invalid: Airspeed cruise out of min or max bounds");
|
||||||
|
check_ret = PX4_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_param_fw_airspd_stall.get() > _param_fw_airspd_min.get() * 0.9f) {
|
||||||
|
mavlink_log_critical(&_mavlink_log_pub, "Config invalid: Stall airspeed higher than 0.9 of min");
|
||||||
|
check_ret = PX4_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return check_ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
@@ -353,6 +353,7 @@ private:
|
|||||||
(ParamFloat<px4::params::FW_AIRSPD_MAX>) _param_fw_airspd_max,
|
(ParamFloat<px4::params::FW_AIRSPD_MAX>) _param_fw_airspd_max,
|
||||||
(ParamFloat<px4::params::FW_AIRSPD_MIN>) _param_fw_airspd_min,
|
(ParamFloat<px4::params::FW_AIRSPD_MIN>) _param_fw_airspd_min,
|
||||||
(ParamFloat<px4::params::FW_AIRSPD_TRIM>) _param_fw_airspd_trim,
|
(ParamFloat<px4::params::FW_AIRSPD_TRIM>) _param_fw_airspd_trim,
|
||||||
|
(ParamFloat<px4::params::FW_AIRSPD_STALL>) _param_fw_airspd_stall,
|
||||||
|
|
||||||
(ParamFloat<px4::params::FW_CLMBOUT_DIFF>) _param_fw_clmbout_diff,
|
(ParamFloat<px4::params::FW_CLMBOUT_DIFF>) _param_fw_clmbout_diff,
|
||||||
|
|
||||||
|
|||||||
@@ -433,7 +433,8 @@ PARAM_DEFINE_FLOAT(FW_LND_THRTC_SC, 1.0f);
|
|||||||
/**
|
/**
|
||||||
* Minimum Airspeed (CAS)
|
* Minimum Airspeed (CAS)
|
||||||
*
|
*
|
||||||
* If the CAS (calibrated airspeed) falls below this value, the TECS controller will try to
|
* The minimal airspeed (calibrated airspeed) the user is able to command.
|
||||||
|
* Further, if the airspeed falls below this value, the TECS controller will try to
|
||||||
* increase airspeed more aggressively.
|
* increase airspeed more aggressively.
|
||||||
*
|
*
|
||||||
* @unit m/s
|
* @unit m/s
|
||||||
@@ -476,6 +477,22 @@ PARAM_DEFINE_FLOAT(FW_AIRSPD_MAX, 20.0f);
|
|||||||
*/
|
*/
|
||||||
PARAM_DEFINE_FLOAT(FW_AIRSPD_TRIM, 15.0f);
|
PARAM_DEFINE_FLOAT(FW_AIRSPD_TRIM, 15.0f);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stall Airspeed (CAS)
|
||||||
|
*
|
||||||
|
* The stall airspeed (calibrated airspeed) of the vehicle.
|
||||||
|
* It is used for airspeed sensor failure detection and for the control
|
||||||
|
* surface scaling airspeed limits.
|
||||||
|
*
|
||||||
|
* @unit m/s
|
||||||
|
* @min 0.5
|
||||||
|
* @max 40
|
||||||
|
* @decimal 1
|
||||||
|
* @increment 0.5
|
||||||
|
* @group FW TECS
|
||||||
|
*/
|
||||||
|
PARAM_DEFINE_FLOAT(FW_AIRSPD_STALL, 7.0f);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maximum climb rate
|
* Maximum climb rate
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -401,7 +401,7 @@ LogWriterFile::LogFileBuffer::~LogFileBuffer()
|
|||||||
close(_fd);
|
close(_fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete[] _buffer;
|
free(_buffer);
|
||||||
|
|
||||||
perf_free(_perf_write);
|
perf_free(_perf_write);
|
||||||
perf_free(_perf_fsync);
|
perf_free(_perf_fsync);
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ px4_add_module(
|
|||||||
enginefailure.cpp
|
enginefailure.cpp
|
||||||
gpsfailure.cpp
|
gpsfailure.cpp
|
||||||
follow_target.cpp
|
follow_target.cpp
|
||||||
|
NavigatorCore.cpp
|
||||||
DEPENDS
|
DEPENDS
|
||||||
git_ecl
|
git_ecl
|
||||||
ecl_geo
|
ecl_geo
|
||||||
@@ -59,4 +60,5 @@ px4_add_module(
|
|||||||
motion_planning
|
motion_planning
|
||||||
)
|
)
|
||||||
|
|
||||||
px4_add_functional_gtest(SRC RangeRTLTest.cpp LINKLIBS modules__navigator modules__dataman)
|
px4_add_functional_gtest(SRC RangeRTLTest.cpp LINKLIBS modules__navigator modules__dataman)
|
||||||
|
px4_add_functional_gtest(SRC NavigatorModeTakeoffTest.cpp LINKLIBS modules__navigator modules__dataman)
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define MODULE_NAME "navigator"
|
||||||
|
|
||||||
|
#include <navigator/navigator.h>
|
||||||
|
|
||||||
|
|
||||||
|
class FakeNavigator : public Navigator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FakeNavigator() :
|
||||||
|
Navigator() {};
|
||||||
|
|
||||||
|
virtual ~FakeNavigator() {};
|
||||||
|
|
||||||
|
private:
|
||||||
|
};
|
||||||
@@ -34,7 +34,7 @@
|
|||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
#include "geofence_breach_avoidance.h"
|
#include "geofence_breach_avoidance.h"
|
||||||
#include "fake_geofence.hpp"
|
#include "fake_geofence.hpp"
|
||||||
#include "dataman_mocks.hpp"
|
#include <dataman/dataman_mocks.hpp>
|
||||||
#include <parameters/param.h>
|
#include <parameters/param.h>
|
||||||
|
|
||||||
using namespace matrix;
|
using namespace matrix;
|
||||||
|
|||||||
@@ -0,0 +1,131 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (c) 2021 PX4 Development Team. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* 3. Neither the name PX4 nor the names of its contributors may be
|
||||||
|
* used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||||
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
/**
|
||||||
|
* @file NavigatorCore.cpp
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "NavigatorCore.h"
|
||||||
|
#include <px4_platform_common/defines.h>
|
||||||
|
|
||||||
|
|
||||||
|
NavigatorCore::NavigatorCore() :
|
||||||
|
ModuleParams(nullptr)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
NavigatorCore::~NavigatorCore()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NavigatorCore::forceVTOL()
|
||||||
|
{
|
||||||
|
|
||||||
|
return _status.is_vtol && (isRotaryWing() || _status.in_transition_to_fw) && _param_nav_force_vt.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
float NavigatorCore::getHorAcceptanceRadiusMeter()
|
||||||
|
{
|
||||||
|
if (isRotaryWing()) {
|
||||||
|
return getDefaultHorAcceptanceRadiusMeter();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return math::max(_pos_ctrl_status.acceptance_radius, getDefaultHorAcceptanceRadiusMeter());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float NavigatorCore::getAltAcceptanceRadMeter()
|
||||||
|
{
|
||||||
|
if (isFixedWing()) {
|
||||||
|
const position_setpoint_s &next_sp = getCurrentTriplet().next;
|
||||||
|
|
||||||
|
if (next_sp.type == position_setpoint_s::SETPOINT_TYPE_LAND && next_sp.valid) {
|
||||||
|
// Use separate (tighter) altitude acceptance for clean altitude starting point before landing
|
||||||
|
return getFixedWingLandingAltAcceptanceRadius();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return getDefaultAltAcceptanceRadiusMeter();
|
||||||
|
}
|
||||||
|
|
||||||
|
float NavigatorCore::getDefaultAltAcceptanceRadiusMeter()
|
||||||
|
{
|
||||||
|
|
||||||
|
if (isFixedWing()) {
|
||||||
|
return getFixedWingAltAcceptanceRadiusMeter();
|
||||||
|
|
||||||
|
} else if (isRover()) {
|
||||||
|
return INFINITY;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
float alt_acceptance_radius = getMulticopterAltAcceptanceRadiusMeter();
|
||||||
|
|
||||||
|
if ((_pos_ctrl_status.timestamp > getCurrentTriplet().timestamp)
|
||||||
|
&& _pos_ctrl_status.altitude_acceptance > alt_acceptance_radius) {
|
||||||
|
alt_acceptance_radius = _pos_ctrl_status.altitude_acceptance;
|
||||||
|
}
|
||||||
|
|
||||||
|
return alt_acceptance_radius;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float NavigatorCore::getAcceptanceRadiusMeter()
|
||||||
|
{
|
||||||
|
|
||||||
|
float acceptance_radius = _param_nav_acc_rad.get();
|
||||||
|
|
||||||
|
// for fixed-wing and rover, return the max of NAV_ACC_RAD and the controller acceptance radius (e.g. L1 distance)
|
||||||
|
if (!isRotaryWing() && PX4_ISFINITE(_pos_ctrl_status.acceptance_radius) && _pos_ctrl_status.timestamp != 0) {
|
||||||
|
|
||||||
|
acceptance_radius = math::max(acceptance_radius, _pos_ctrl_status.acceptance_radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
return acceptance_radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
float NavigatorCore::getAltAcceptanceRadiusMeter()
|
||||||
|
{
|
||||||
|
|
||||||
|
if (isFixedWing()) {
|
||||||
|
const position_setpoint_s &next_sp = _triplet.next;
|
||||||
|
|
||||||
|
if (next_sp.type == position_setpoint_s::SETPOINT_TYPE_LAND && next_sp.valid) {
|
||||||
|
// Use separate (tighter) altitude acceptance for clean altitude starting point before landing
|
||||||
|
return _param_nav_fw_altl_rad.get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return getDefaultAltAcceptanceRadiusMeter();
|
||||||
|
}
|
||||||
@@ -0,0 +1,157 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013-2017 PX4 Development Team. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* 3. Neither the name PX4 nor the names of its contributors may be
|
||||||
|
* used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||||
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <px4_platform_common/module_params.h>
|
||||||
|
|
||||||
|
#include <lib/mathlib/mathlib.h>
|
||||||
|
#include <uORB/topics/vehicle_local_position.h>
|
||||||
|
#include <uORB/topics/vehicle_status.h>
|
||||||
|
#include <uORB/topics/vehicle_global_position.h>
|
||||||
|
#include <uORB/topics/vehicle_land_detected.h>
|
||||||
|
#include <uORB/topics/home_position.h>
|
||||||
|
#include <uORB/topics/position_controller_status.h>
|
||||||
|
#include <uORB/topics/position_setpoint_triplet.h>
|
||||||
|
|
||||||
|
|
||||||
|
class NavigatorCore : public ModuleParams
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
NavigatorCore();
|
||||||
|
|
||||||
|
~NavigatorCore();
|
||||||
|
|
||||||
|
typedef matrix::Vector3<float> Vector3f;
|
||||||
|
typedef matrix::Vector2<double> Vector2d;
|
||||||
|
|
||||||
|
bool getLanded() { return _landed_state.landed; }
|
||||||
|
bool getMaybeLanded() { return _landed_state.maybe_landed; }
|
||||||
|
float getLandDetectedAltMaxMeter() { return _landed_state.alt_max; }
|
||||||
|
double getLatRad() { return _global_pos.lat; }
|
||||||
|
double getLonRad() { return _global_pos.lon;}
|
||||||
|
float getAltitudeAMSLMeters() { return _global_pos.alt; }
|
||||||
|
float getTrueHeadingRad() { return _local_pos.heading; }
|
||||||
|
double getHomeLatRad() { return _home.lat; }
|
||||||
|
double getHomeLonRad() { return _home.lon; }
|
||||||
|
float getHomeAltAMSLMeter() { return _home.alt; }
|
||||||
|
float getHomeTrueHeadingRad() { return _home.yaw; }
|
||||||
|
home_position_s &getHomePosition() { return _home; }
|
||||||
|
|
||||||
|
bool isNotArmed() { return _status.arming_state != vehicle_status_s::ARMING_STATE_ARMED; }
|
||||||
|
uint8_t getArmingState() { return _status.arming_state; }
|
||||||
|
|
||||||
|
|
||||||
|
float getPosNorthMeter() { return _local_pos.x; }
|
||||||
|
float getPosEastMeter() { return _local_pos.y; }
|
||||||
|
float getPosDownMeter() { return _local_pos.z; }
|
||||||
|
|
||||||
|
float getVelNorthMPS() { return _local_pos.vx; }
|
||||||
|
float getVelEastMPS() { return _local_pos.vy; }
|
||||||
|
float getVelDownMPS() { return _local_pos.vz; }
|
||||||
|
|
||||||
|
float getLoiterRadiusMeter() { return _param_nav_loiter_rad.get(); }
|
||||||
|
|
||||||
|
bool getIsInTransitionMode() { return _status.in_transition_mode; }
|
||||||
|
|
||||||
|
position_setpoint_triplet_s getCurrentTriplet() { return _triplet; }
|
||||||
|
|
||||||
|
bool isHomeValid() { return (_home.timestamp > 0 && _home.valid_alt && _home.valid_hpos && _home.valid_lpos); }
|
||||||
|
bool isHomeAltValid() { return (_home.timestamp > 0 && _home.valid_alt); }
|
||||||
|
|
||||||
|
bool isRotaryWing() { return _status.vehicle_type == vehicle_status_s::VEHICLE_TYPE_ROTARY_WING; }
|
||||||
|
bool isFixedWing() { return _status.vehicle_type == vehicle_status_s::VEHICLE_TYPE_FIXED_WING; }
|
||||||
|
bool isRover() { return _status.vehicle_type == vehicle_status_s::VEHICLE_TYPE_ROVER; }
|
||||||
|
bool isVTOL() { return _status.is_vtol; }
|
||||||
|
uint8_t getVehicleType() { return _status.vehicle_type; }
|
||||||
|
|
||||||
|
float getDefaultAltAcceptanceRadiusMeter();
|
||||||
|
float getAltAcceptanceRadMeter();
|
||||||
|
float getFixedWingLandingAltAcceptanceRadius() { return _param_nav_fw_altl_rad.get(); }
|
||||||
|
float getDefaultHorAcceptanceRadiusMeter() { return _param_nav_acc_rad.get(); }
|
||||||
|
float getHorAcceptanceRadiusMeter();
|
||||||
|
float getMulticopterAltAcceptanceRadiusMeter() { return _param_nav_mc_alt_rad.get(); }
|
||||||
|
float getFixedWingAltAcceptanceRadiusMeter() { return _param_nav_fw_alt_rad.get(); }
|
||||||
|
|
||||||
|
float getAcceptanceRadiusMeter();
|
||||||
|
float getAltAcceptanceRadiusMeter();
|
||||||
|
|
||||||
|
float getRelativeTakeoffMinAltitudeMeter() { return _param_mis_takeoff_alt.get(); }
|
||||||
|
float getRelativeLoiterMinAltitudeMeter() { return _param_mis_ltrmin_alt.get(); }
|
||||||
|
bool isTakeoffRequired() { return _param_mis_takeoff_req.get(); }
|
||||||
|
float getWaypointHeadingTimeoutSeconds() { return _param_mis_yaw_tmt.get(); }
|
||||||
|
float getWaypointHeadingAcceptanceRad() { return _param_mis_yaw_err.get(); }
|
||||||
|
|
||||||
|
|
||||||
|
bool forceVTOL();
|
||||||
|
|
||||||
|
void updateLocalPosition(const vehicle_local_position_s &local_pos) { _local_pos = local_pos; };
|
||||||
|
void updateVehicleStatus(const vehicle_status_s &status) { _status = status; }
|
||||||
|
void updateGlobalPosition(const vehicle_global_position_s &global_pos) { _global_pos = global_pos; }
|
||||||
|
void updateLandedState(const vehicle_land_detected_s &landed_state) { _landed_state = landed_state; }
|
||||||
|
void updateHomePosition(const home_position_s &home) { _home = home; }
|
||||||
|
void updatePositionControllerStatus(const position_controller_status_s &pos_ctrl_status) { _pos_ctrl_status = pos_ctrl_status; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
vehicle_local_position_s _local_pos{};
|
||||||
|
vehicle_status_s _status{};
|
||||||
|
vehicle_global_position_s _global_pos{};
|
||||||
|
vehicle_land_detected_s _landed_state{};
|
||||||
|
home_position_s _home{};
|
||||||
|
position_controller_status_s _pos_ctrl_status{};
|
||||||
|
|
||||||
|
position_setpoint_triplet_s _triplet{};
|
||||||
|
|
||||||
|
DEFINE_PARAMETERS(
|
||||||
|
(ParamFloat<px4::params::NAV_LOITER_RAD>) _param_nav_loiter_rad, /**< loiter radius for fixedwing */
|
||||||
|
(ParamFloat<px4::params::NAV_ACC_RAD>) _param_nav_acc_rad, /**< acceptance for takeoff */
|
||||||
|
(ParamFloat<px4::params::NAV_FW_ALT_RAD>)
|
||||||
|
_param_nav_fw_alt_rad, /**< acceptance radius for fixedwing altitude */
|
||||||
|
(ParamFloat<px4::params::NAV_FW_ALTL_RAD>)
|
||||||
|
_param_nav_fw_altl_rad, /**< acceptance radius for fixedwing altitude before landing*/
|
||||||
|
(ParamFloat<px4::params::NAV_MC_ALT_RAD>)
|
||||||
|
_param_nav_mc_alt_rad, /**< acceptance radius for multicopter altitude */
|
||||||
|
(ParamInt<px4::params::NAV_FORCE_VT>) _param_nav_force_vt, /**< acceptance radius for multicopter altitude */
|
||||||
|
(ParamInt<px4::params::NAV_TRAFF_AVOID>) _param_nav_traff_avoid, /**< avoiding other aircraft is enabled */
|
||||||
|
(ParamFloat<px4::params::NAV_TRAFF_A_RADU>) _param_nav_traff_a_radu, /**< avoidance Distance Unmanned*/
|
||||||
|
(ParamFloat<px4::params::NAV_TRAFF_A_RADM>) _param_nav_traff_a_radm, /**< avoidance Distance Manned*/
|
||||||
|
|
||||||
|
// non-navigator parameters
|
||||||
|
// Mission (MIS_*)
|
||||||
|
(ParamFloat<px4::params::MIS_LTRMIN_ALT>) _param_mis_ltrmin_alt,
|
||||||
|
(ParamFloat<px4::params::MIS_TAKEOFF_ALT>) _param_mis_takeoff_alt,
|
||||||
|
(ParamBool<px4::params::MIS_TAKEOFF_REQ>) _param_mis_takeoff_req,
|
||||||
|
(ParamFloat<px4::params::MIS_YAW_TMT>) _param_mis_yaw_tmt,
|
||||||
|
(ParamFloat<px4::params::MIS_YAW_ERR>) _param_mis_yaw_err
|
||||||
|
)
|
||||||
|
};
|
||||||
@@ -0,0 +1,121 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (C) 2021 PX4 Development Team. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* 3. Neither the name PX4 nor the names of its contributors may be
|
||||||
|
* used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||||
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
#include "FakeNavigator.h"
|
||||||
|
#include "takeoff.h"
|
||||||
|
#include <dataman/dataman_mocks.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
TEST(NavigatorModeTakeoffTest, TestTakeoff)
|
||||||
|
{
|
||||||
|
FakeNavigator fake_navigator;
|
||||||
|
|
||||||
|
NavigatorCore &navigator_core = fake_navigator.getCore();
|
||||||
|
Takeoff takeoff(&fake_navigator, navigator_core);
|
||||||
|
fake_navigator.params_update();
|
||||||
|
|
||||||
|
vehicle_status_s status = {};
|
||||||
|
status.timestamp = 1e6;
|
||||||
|
status.is_vtol = true;
|
||||||
|
status.arming_state = vehicle_status_s::ARMING_STATE_ARMED;
|
||||||
|
status.vehicle_type = vehicle_status_s::VEHICLE_TYPE_ROTARY_WING;
|
||||||
|
|
||||||
|
vehicle_global_position_s global_pos = {};
|
||||||
|
global_pos.timestamp = 1e6;
|
||||||
|
global_pos.lat = 40;
|
||||||
|
global_pos.lon = 3;
|
||||||
|
global_pos.alt = 300;
|
||||||
|
|
||||||
|
vehicle_land_detected_s landed = {};
|
||||||
|
landed.landed = true;
|
||||||
|
landed.timestamp = 1e6;
|
||||||
|
|
||||||
|
home_position_s home = {};
|
||||||
|
home.timestamp = 1e6;
|
||||||
|
home.lat = global_pos.lat;
|
||||||
|
home.lon = global_pos.lon;
|
||||||
|
home.alt = global_pos.alt;
|
||||||
|
home.valid_alt = true;
|
||||||
|
home.valid_hpos = true;
|
||||||
|
home.valid_lpos = true;
|
||||||
|
|
||||||
|
vehicle_local_position_s local_pos = {};
|
||||||
|
local_pos.timestamp = 1e6;
|
||||||
|
local_pos.x = -0.2f;
|
||||||
|
local_pos.y = 0.1f;
|
||||||
|
local_pos.z = 0.1f;
|
||||||
|
|
||||||
|
local_pos.vx = local_pos.vy = local_pos.vz = 0;
|
||||||
|
local_pos.heading = -0.54f;
|
||||||
|
|
||||||
|
navigator_core.updateGlobalPosition(global_pos);
|
||||||
|
navigator_core.updateHomePosition(home);
|
||||||
|
navigator_core.updateLandedState(landed);
|
||||||
|
navigator_core.updateLocalPosition(local_pos);
|
||||||
|
navigator_core.updateVehicleStatus(status);
|
||||||
|
|
||||||
|
takeoff.on_activation();
|
||||||
|
|
||||||
|
position_setpoint_s current = fake_navigator.get_position_setpoint_triplet()->current;
|
||||||
|
|
||||||
|
ASSERT_EQ(current.lat, navigator_core.getLatRad());
|
||||||
|
ASSERT_EQ(current.lon, navigator_core.getLonRad());
|
||||||
|
ASSERT_EQ(current.type, 3); // position_setpoint_s::TYPE_TAKEOFF
|
||||||
|
ASSERT_EQ(current.valid, true);
|
||||||
|
ASSERT_EQ(current.alt_valid, true);
|
||||||
|
ASSERT_EQ(current.alt, global_pos.alt + navigator_core.getRelativeTakeoffMinAltitudeMeter());
|
||||||
|
ASSERT_EQ(current.yaw, navigator_core.getTrueHeadingRad());
|
||||||
|
ASSERT_EQ(current.yaw_valid, true);
|
||||||
|
ASSERT_EQ(current.yawspeed_valid, false);
|
||||||
|
ASSERT_EQ(current.loiter_radius, navigator_core.getLoiterRadiusMeter());
|
||||||
|
ASSERT_EQ(current.loiter_direction, 1);
|
||||||
|
ASSERT_EQ(current.acceptance_radius, navigator_core.getHorAcceptanceRadiusMeter());
|
||||||
|
ASSERT_EQ(current.cruising_speed, -1.0f);
|
||||||
|
|
||||||
|
uint64_t t_first = current.timestamp;
|
||||||
|
|
||||||
|
landed.landed = false;
|
||||||
|
navigator_core.updateLandedState(landed);
|
||||||
|
global_pos.alt += navigator_core.getRelativeTakeoffMinAltitudeMeter();
|
||||||
|
navigator_core.updateGlobalPosition(global_pos);
|
||||||
|
|
||||||
|
takeoff.on_active();
|
||||||
|
current = fake_navigator.get_position_setpoint_triplet()->current;
|
||||||
|
|
||||||
|
ASSERT_NE(t_first, current.timestamp);
|
||||||
|
ASSERT_EQ(current.type, 2);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -11,7 +11,8 @@
|
|||||||
TEST(Navigator_and_RTL, interact_correctly)
|
TEST(Navigator_and_RTL, interact_correctly)
|
||||||
{
|
{
|
||||||
Navigator n;
|
Navigator n;
|
||||||
RTL rtl(&n);
|
NavigatorCore navigator_core;
|
||||||
|
RTL rtl(&n, navigator_core);
|
||||||
|
|
||||||
|
|
||||||
home_position_s home_pos{};
|
home_position_s home_pos{};
|
||||||
|
|||||||
@@ -52,8 +52,8 @@
|
|||||||
#include "navigator.h"
|
#include "navigator.h"
|
||||||
#include "enginefailure.h"
|
#include "enginefailure.h"
|
||||||
|
|
||||||
EngineFailure::EngineFailure(Navigator *navigator) :
|
EngineFailure::EngineFailure(Navigator *navigator, NavigatorCore &navigator_core) :
|
||||||
MissionBlock(navigator),
|
MissionBlock(navigator, navigator_core),
|
||||||
_ef_state(EF_STATE_NONE)
|
_ef_state(EF_STATE_NONE)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -93,15 +93,15 @@ EngineFailure::set_ef_item()
|
|||||||
case EF_STATE_LOITERDOWN: {
|
case EF_STATE_LOITERDOWN: {
|
||||||
//XXX create mission item at ground (below?) here
|
//XXX create mission item at ground (below?) here
|
||||||
|
|
||||||
_mission_item.lat = _navigator->get_global_position()->lat;
|
_mission_item.lat = _navigator_core.getLatRad();
|
||||||
_mission_item.lon = _navigator->get_global_position()->lon;
|
_mission_item.lon = _navigator_core.getLonRad();
|
||||||
_mission_item.altitude_is_relative = false;
|
_mission_item.altitude_is_relative = false;
|
||||||
//XXX setting altitude to a very low value, evaluate other options
|
//XXX setting altitude to a very low value, evaluate other options
|
||||||
_mission_item.altitude = _navigator->get_home_position()->alt - 1000.0f;
|
_mission_item.altitude = _navigator_core.getHomeAltAMSLMeter() - 1000.0f;
|
||||||
_mission_item.yaw = NAN;
|
_mission_item.yaw = NAN;
|
||||||
_mission_item.loiter_radius = _navigator->get_loiter_radius();
|
_mission_item.loiter_radius = _navigator_core.getLoiterRadiusMeter();
|
||||||
_mission_item.nav_cmd = NAV_CMD_LOITER_UNLIMITED;
|
_mission_item.nav_cmd = NAV_CMD_LOITER_UNLIMITED;
|
||||||
_mission_item.acceptance_radius = _navigator->get_acceptance_radius();
|
_mission_item.acceptance_radius = _navigator_core.getAcceptanceRadiusMeter();
|
||||||
_mission_item.autocontinue = true;
|
_mission_item.autocontinue = true;
|
||||||
_mission_item.origin = ORIGIN_ONBOARD;
|
_mission_item.origin = ORIGIN_ONBOARD;
|
||||||
|
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ class Navigator;
|
|||||||
class EngineFailure : public MissionBlock
|
class EngineFailure : public MissionBlock
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
EngineFailure(Navigator *navigator);
|
EngineFailure(Navigator *navigator, NavigatorCore &navigator_core);
|
||||||
~EngineFailure() = default;
|
~EngineFailure() = default;
|
||||||
|
|
||||||
void on_inactive() override;
|
void on_inactive() override;
|
||||||
|
|||||||
@@ -60,8 +60,8 @@ using namespace matrix;
|
|||||||
|
|
||||||
constexpr float FollowTarget::_follow_position_matricies[4][9];
|
constexpr float FollowTarget::_follow_position_matricies[4][9];
|
||||||
|
|
||||||
FollowTarget::FollowTarget(Navigator *navigator) :
|
FollowTarget::FollowTarget(Navigator *navigator, NavigatorCore &navigator_core) :
|
||||||
MissionBlock(navigator),
|
MissionBlock(navigator, navigator_core),
|
||||||
ModuleParams(navigator)
|
ModuleParams(navigator)
|
||||||
{
|
{
|
||||||
_current_vel.zero();
|
_current_vel.zero();
|
||||||
@@ -134,7 +134,7 @@ void FollowTarget::on_active()
|
|||||||
|
|
||||||
// get distance to target
|
// get distance to target
|
||||||
|
|
||||||
map_projection_init(&target_ref, _navigator->get_global_position()->lat, _navigator->get_global_position()->lon);
|
map_projection_init(&target_ref, _navigator_core.getLatRad(), _navigator_core.getLonRad());
|
||||||
map_projection_project(&target_ref, _current_target_motion.lat, _current_target_motion.lon, &_target_distance(0),
|
map_projection_project(&target_ref, _current_target_motion.lat, _current_target_motion.lon, &_target_distance(0),
|
||||||
&_target_distance(1));
|
&_target_distance(1));
|
||||||
|
|
||||||
@@ -200,12 +200,12 @@ void FollowTarget::on_active()
|
|||||||
// this really needs to control the yaw rate directly in the attitude pid controller
|
// this really needs to control the yaw rate directly in the attitude pid controller
|
||||||
// but seems to work ok for now since the yaw rate cannot be controlled directly in auto mode
|
// but seems to work ok for now since the yaw rate cannot be controlled directly in auto mode
|
||||||
|
|
||||||
_yaw_angle = get_bearing_to_next_waypoint(_navigator->get_global_position()->lat,
|
_yaw_angle = get_bearing_to_next_waypoint(_navigator_core.getLatRad(),
|
||||||
_navigator->get_global_position()->lon,
|
_navigator_core.getLonRad(),
|
||||||
_current_target_motion.lat,
|
_current_target_motion.lat,
|
||||||
_current_target_motion.lon);
|
_current_target_motion.lon);
|
||||||
|
|
||||||
_yaw_rate = wrap_pi((_yaw_angle - _navigator->get_local_position()->heading) / (dt_ms / 1000.0f));
|
_yaw_rate = wrap_pi((_yaw_angle - _navigator_core.getTrueHeadingRad()) / (dt_ms / 1000.0f));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
_yaw_angle = _yaw_rate = NAN;
|
_yaw_angle = _yaw_rate = NAN;
|
||||||
@@ -238,7 +238,7 @@ void FollowTarget::on_active()
|
|||||||
// 3 degrees of facing target
|
// 3 degrees of facing target
|
||||||
|
|
||||||
if (PX4_ISFINITE(_yaw_rate)) {
|
if (PX4_ISFINITE(_yaw_rate)) {
|
||||||
if (fabsf(fabsf(_yaw_angle) - fabsf(_navigator->get_local_position()->heading)) < math::radians(3.0F)) {
|
if (fabsf(fabsf(_yaw_angle) - fabsf(_navigator_core.getTrueHeadingRad())) < math::radians(3.0F)) {
|
||||||
_yaw_rate = NAN;
|
_yaw_rate = NAN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -298,8 +298,8 @@ void FollowTarget::on_active()
|
|||||||
|
|
||||||
// for now set the target at the minimum height above the uav
|
// for now set the target at the minimum height above the uav
|
||||||
|
|
||||||
target.lat = _navigator->get_global_position()->lat;
|
target.lat = _navigator_core.getLatRad();
|
||||||
target.lon = _navigator->get_global_position()->lon;
|
target.lon = _navigator_core.getLonRad();
|
||||||
target.alt = 0.0F;
|
target.alt = 0.0F;
|
||||||
|
|
||||||
set_follow_target_item(&_mission_item, _param_nav_min_ft_ht.get(), target, _yaw_angle);
|
set_follow_target_item(&_mission_item, _param_nav_min_ft_ht.get(), target, _yaw_angle);
|
||||||
@@ -376,7 +376,7 @@ void
|
|||||||
FollowTarget::set_follow_target_item(struct mission_item_s *item, float min_clearance, follow_target_s &target,
|
FollowTarget::set_follow_target_item(struct mission_item_s *item, float min_clearance, follow_target_s &target,
|
||||||
float yaw)
|
float yaw)
|
||||||
{
|
{
|
||||||
if (_navigator->get_land_detected()->landed) {
|
if (_navigator_core.getLanded()) {
|
||||||
/* landed, don't takeoff, but switch to IDLE mode */
|
/* landed, don't takeoff, but switch to IDLE mode */
|
||||||
item->nav_cmd = NAV_CMD_IDLE;
|
item->nav_cmd = NAV_CMD_IDLE;
|
||||||
|
|
||||||
@@ -387,7 +387,8 @@ FollowTarget::set_follow_target_item(struct mission_item_s *item, float min_clea
|
|||||||
/* use current target position */
|
/* use current target position */
|
||||||
item->lat = target.lat;
|
item->lat = target.lat;
|
||||||
item->lon = target.lon;
|
item->lon = target.lon;
|
||||||
item->altitude = _navigator->get_home_position()->alt;
|
item->altitude = _navigator_core.getHomeAltAMSLMeter();
|
||||||
|
|
||||||
|
|
||||||
if (min_clearance > 8.0f) {
|
if (min_clearance > 8.0f) {
|
||||||
item->altitude += min_clearance;
|
item->altitude += min_clearance;
|
||||||
@@ -399,8 +400,8 @@ FollowTarget::set_follow_target_item(struct mission_item_s *item, float min_clea
|
|||||||
|
|
||||||
item->altitude_is_relative = false;
|
item->altitude_is_relative = false;
|
||||||
item->yaw = yaw;
|
item->yaw = yaw;
|
||||||
item->loiter_radius = _navigator->get_loiter_radius();
|
item->loiter_radius = _navigator_core.getLoiterRadiusMeter();
|
||||||
item->acceptance_radius = _navigator->get_acceptance_radius();
|
item->acceptance_radius = _navigator_core.getAcceptanceRadiusMeter();
|
||||||
item->time_inside = 0.0f;
|
item->time_inside = 0.0f;
|
||||||
item->autocontinue = false;
|
item->autocontinue = false;
|
||||||
item->origin = ORIGIN_ONBOARD;
|
item->origin = ORIGIN_ONBOARD;
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ class FollowTarget : public MissionBlock, public ModuleParams
|
|||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FollowTarget(Navigator *navigator);
|
FollowTarget(Navigator *navigator, NavigatorCore &navigator_core);
|
||||||
~FollowTarget() = default;
|
~FollowTarget() = default;
|
||||||
|
|
||||||
void on_inactive() override;
|
void on_inactive() override;
|
||||||
|
|||||||
@@ -224,13 +224,13 @@ bool Geofence::isCloserThanMaxDistToHome(double lat, double lon, float altitude)
|
|||||||
{
|
{
|
||||||
bool inside_fence = true;
|
bool inside_fence = true;
|
||||||
|
|
||||||
if (isHomeRequired() && _navigator->home_position_valid()) {
|
if (isHomeRequired() && _navigator->getCore().isHomeValid()) {
|
||||||
|
|
||||||
const float max_horizontal_distance = _param_gf_max_hor_dist.get();
|
const float max_horizontal_distance = _param_gf_max_hor_dist.get();
|
||||||
|
|
||||||
const double home_lat = _navigator->get_home_position()->lat;
|
const double home_lat = _navigator->getCore().getHomeLatRad();
|
||||||
const double home_lon = _navigator->get_home_position()->lon;
|
const double home_lon = _navigator->getCore().getHomeLonRad();
|
||||||
const float home_alt = _navigator->get_home_position()->alt;
|
const float home_alt = _navigator->getCore().getHomeAltAMSLMeter();
|
||||||
|
|
||||||
float dist_xy = -1.0f;
|
float dist_xy = -1.0f;
|
||||||
float dist_z = -1.0f;
|
float dist_z = -1.0f;
|
||||||
@@ -255,10 +255,10 @@ bool Geofence::isBelowMaxAltitude(float altitude)
|
|||||||
{
|
{
|
||||||
bool inside_fence = true;
|
bool inside_fence = true;
|
||||||
|
|
||||||
if (isHomeRequired() && _navigator->home_position_valid()) {
|
if (isHomeRequired() && _navigator->getCore().isHomeValid()) {
|
||||||
|
|
||||||
const float max_vertical_distance = _param_gf_max_ver_dist.get();
|
const float max_vertical_distance = _param_gf_max_ver_dist.get();
|
||||||
const float home_alt = _navigator->get_home_position()->alt;
|
const float home_alt = _navigator->getCore().getHomeAltAMSLMeter();
|
||||||
|
|
||||||
float dist_z = altitude - home_alt;
|
float dist_z = altitude - home_alt;
|
||||||
|
|
||||||
|
|||||||
@@ -52,8 +52,8 @@
|
|||||||
using matrix::Eulerf;
|
using matrix::Eulerf;
|
||||||
using matrix::Quatf;
|
using matrix::Quatf;
|
||||||
|
|
||||||
GpsFailure::GpsFailure(Navigator *navigator) :
|
GpsFailure::GpsFailure(Navigator *navigator, NavigatorCore &navigator_core) :
|
||||||
MissionBlock(navigator),
|
MissionBlock(navigator, navigator_core),
|
||||||
ModuleParams(navigator)
|
ModuleParams(navigator)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -92,7 +92,7 @@ GpsFailure::on_active()
|
|||||||
Quatf q(Eulerf(att_sp.roll_body, att_sp.pitch_body, 0.0f));
|
Quatf q(Eulerf(att_sp.roll_body, att_sp.pitch_body, 0.0f));
|
||||||
q.copyTo(att_sp.q_d);
|
q.copyTo(att_sp.q_d);
|
||||||
|
|
||||||
if (_navigator->get_vstatus()->is_vtol) {
|
if (_navigator_core.isVTOL()) {
|
||||||
_fw_virtual_att_sp_pub.publish(att_sp);
|
_fw_virtual_att_sp_pub.publish(att_sp);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ class Navigator;
|
|||||||
class GpsFailure : public MissionBlock, public ModuleParams
|
class GpsFailure : public MissionBlock, public ModuleParams
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GpsFailure(Navigator *navigator);
|
GpsFailure(Navigator *navigator, NavigatorCore &navigator_core);
|
||||||
~GpsFailure() = default;
|
~GpsFailure() = default;
|
||||||
|
|
||||||
void on_inactive() override;
|
void on_inactive() override;
|
||||||
|
|||||||
@@ -41,8 +41,8 @@
|
|||||||
#include "land.h"
|
#include "land.h"
|
||||||
#include "navigator.h"
|
#include "navigator.h"
|
||||||
|
|
||||||
Land::Land(Navigator *navigator) :
|
Land::Land(Navigator *navigator, NavigatorCore &navigator_core) :
|
||||||
MissionBlock(navigator)
|
MissionBlock(navigator, navigator_core)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,16 +71,16 @@ void
|
|||||||
Land::on_active()
|
Land::on_active()
|
||||||
{
|
{
|
||||||
/* for VTOL update landing location during back transition */
|
/* for VTOL update landing location during back transition */
|
||||||
if (_navigator->get_vstatus()->is_vtol &&
|
if (_navigator_core.isVTOL() &&
|
||||||
_navigator->get_vstatus()->in_transition_mode) {
|
_navigator_core.getIsInTransitionMode()) {
|
||||||
struct position_setpoint_triplet_s *pos_sp_triplet = _navigator->get_position_setpoint_triplet();
|
struct position_setpoint_triplet_s *pos_sp_triplet = _navigator->get_position_setpoint_triplet();
|
||||||
pos_sp_triplet->current.lat = _navigator->get_global_position()->lat;
|
pos_sp_triplet->current.lat = _navigator_core.getLatRad();
|
||||||
pos_sp_triplet->current.lon = _navigator->get_global_position()->lon;
|
pos_sp_triplet->current.lon = _navigator_core.getLonRad();
|
||||||
_navigator->set_position_setpoint_triplet_updated();
|
_navigator->set_position_setpoint_triplet_updated();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (_navigator->get_land_detected()->landed) {
|
if (_navigator_core.getLanded()) {
|
||||||
_navigator->get_mission_result()->finished = true;
|
_navigator->get_mission_result()->finished = true;
|
||||||
_navigator->set_mission_result_updated();
|
_navigator->set_mission_result_updated();
|
||||||
set_idle_item(&_mission_item);
|
set_idle_item(&_mission_item);
|
||||||
|
|||||||
@@ -46,7 +46,7 @@
|
|||||||
class Land : public MissionBlock
|
class Land : public MissionBlock
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Land(Navigator *navigator);
|
Land(Navigator *navigator, NavigatorCore &navigator_core);
|
||||||
~Land() = default;
|
~Land() = default;
|
||||||
|
|
||||||
void on_activation() override;
|
void on_activation() override;
|
||||||
|
|||||||
@@ -42,8 +42,8 @@
|
|||||||
#include "loiter.h"
|
#include "loiter.h"
|
||||||
#include "navigator.h"
|
#include "navigator.h"
|
||||||
|
|
||||||
Loiter::Loiter(Navigator *navigator) :
|
Loiter::Loiter(Navigator *navigator, NavigatorCore &navigator_core) :
|
||||||
MissionBlock(navigator),
|
MissionBlock(navigator, navigator_core),
|
||||||
ModuleParams(navigator)
|
ModuleParams(navigator)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -73,7 +73,7 @@ Loiter::on_active()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// reset the loiter position if we get disarmed
|
// reset the loiter position if we get disarmed
|
||||||
if (_navigator->get_vstatus()->arming_state != vehicle_status_s::ARMING_STATE_ARMED) {
|
if (_navigator_core.isNotArmed()) {
|
||||||
_loiter_pos_set = false;
|
_loiter_pos_set = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -81,8 +81,8 @@ Loiter::on_active()
|
|||||||
void
|
void
|
||||||
Loiter::set_loiter_position()
|
Loiter::set_loiter_position()
|
||||||
{
|
{
|
||||||
if (_navigator->get_vstatus()->arming_state != vehicle_status_s::ARMING_STATE_ARMED &&
|
if (_navigator_core.isNotArmed() &&
|
||||||
_navigator->get_land_detected()->landed) {
|
_navigator_core.getLanded()) {
|
||||||
|
|
||||||
// Not setting loiter position if disarmed and landed, instead mark the current
|
// Not setting loiter position if disarmed and landed, instead mark the current
|
||||||
// setpoint as invalid and idle (both, just to be sure).
|
// setpoint as invalid and idle (both, just to be sure).
|
||||||
@@ -101,7 +101,8 @@ Loiter::set_loiter_position()
|
|||||||
_loiter_pos_set = true;
|
_loiter_pos_set = true;
|
||||||
|
|
||||||
// set current mission item to loiter
|
// set current mission item to loiter
|
||||||
set_loiter_item(&_mission_item, _navigator->get_loiter_min_alt());
|
set_loiter_item(&_mission_item, _navigator_core.getRelativeLoiterMinAltitudeMeter());
|
||||||
|
|
||||||
|
|
||||||
// convert mission item to current setpoint
|
// convert mission item to current setpoint
|
||||||
struct position_setpoint_triplet_s *pos_sp_triplet = _navigator->get_position_setpoint_triplet();
|
struct position_setpoint_triplet_s *pos_sp_triplet = _navigator->get_position_setpoint_triplet();
|
||||||
@@ -119,7 +120,7 @@ void
|
|||||||
Loiter::reposition()
|
Loiter::reposition()
|
||||||
{
|
{
|
||||||
// we can't reposition if we are not armed yet
|
// we can't reposition if we are not armed yet
|
||||||
if (_navigator->get_vstatus()->arming_state != vehicle_status_s::ARMING_STATE_ARMED) {
|
if (_navigator_core.isNotArmed()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,10 +132,10 @@ Loiter::reposition()
|
|||||||
// convert mission item to current setpoint
|
// convert mission item to current setpoint
|
||||||
struct position_setpoint_triplet_s *pos_sp_triplet = _navigator->get_position_setpoint_triplet();
|
struct position_setpoint_triplet_s *pos_sp_triplet = _navigator->get_position_setpoint_triplet();
|
||||||
pos_sp_triplet->current.velocity_valid = false;
|
pos_sp_triplet->current.velocity_valid = false;
|
||||||
pos_sp_triplet->previous.yaw = _navigator->get_local_position()->heading;
|
pos_sp_triplet->previous.yaw = _navigator_core.getTrueHeadingRad();
|
||||||
pos_sp_triplet->previous.lat = _navigator->get_global_position()->lat;
|
pos_sp_triplet->previous.lat = _navigator_core.getLatRad();
|
||||||
pos_sp_triplet->previous.lon = _navigator->get_global_position()->lon;
|
pos_sp_triplet->previous.lon = _navigator_core.getLonRad();
|
||||||
pos_sp_triplet->previous.alt = _navigator->get_global_position()->alt;
|
pos_sp_triplet->previous.alt = _navigator_core.getAltitudeAMSLMeters();
|
||||||
memcpy(&pos_sp_triplet->current, &rep->current, sizeof(rep->current));
|
memcpy(&pos_sp_triplet->current, &rep->current, sizeof(rep->current));
|
||||||
pos_sp_triplet->next.valid = false;
|
pos_sp_triplet->next.valid = false;
|
||||||
|
|
||||||
|
|||||||
@@ -48,7 +48,7 @@
|
|||||||
class Loiter : public MissionBlock, public ModuleParams
|
class Loiter : public MissionBlock, public ModuleParams
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Loiter(Navigator *navigator);
|
Loiter(Navigator *navigator, NavigatorCore &navigator_core);
|
||||||
~Loiter() = default;
|
~Loiter() = default;
|
||||||
|
|
||||||
void on_inactive() override;
|
void on_inactive() override;
|
||||||
|
|||||||
@@ -62,8 +62,8 @@
|
|||||||
|
|
||||||
using namespace time_literals;
|
using namespace time_literals;
|
||||||
|
|
||||||
Mission::Mission(Navigator *navigator) :
|
Mission::Mission(Navigator *navigator, NavigatorCore &navigator_core) :
|
||||||
MissionBlock(navigator),
|
MissionBlock(navigator, navigator_core),
|
||||||
ModuleParams(navigator)
|
ModuleParams(navigator)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -83,7 +83,7 @@ Mission::on_inactive()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Without home a mission can't be valid yet anyway, let's wait. */
|
/* Without home a mission can't be valid yet anyway, let's wait. */
|
||||||
if (!_navigator->home_position_valid()) {
|
if (!_navigator_core.isHomeValid()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,7 +131,7 @@ Mission::on_inactive()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* require takeoff after non-loiter or landing */
|
/* require takeoff after non-loiter or landing */
|
||||||
if (!_navigator->get_can_loiter_at_sp() || _navigator->get_land_detected()->landed) {
|
if (!_navigator->get_can_loiter_at_sp() || _navigator_core.getLanded()) {
|
||||||
_need_takeoff = true;
|
_need_takeoff = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -252,7 +252,7 @@ Mission::on_active()
|
|||||||
|
|
||||||
/* see if we need to update the current yaw heading */
|
/* see if we need to update the current yaw heading */
|
||||||
if (!_param_mis_mnt_yaw_ctl.get()
|
if (!_param_mis_mnt_yaw_ctl.get()
|
||||||
&& (_navigator->get_vstatus()->vehicle_type == vehicle_status_s::VEHICLE_TYPE_ROTARY_WING)
|
&& (_navigator_core.isRotaryWing())
|
||||||
&& (_navigator->get_vroi().mode != vehicle_roi_s::ROI_NONE)
|
&& (_navigator->get_vroi().mode != vehicle_roi_s::ROI_NONE)
|
||||||
&& !(_mission_item.nav_cmd == NAV_CMD_TAKEOFF
|
&& !(_mission_item.nav_cmd == NAV_CMD_TAKEOFF
|
||||||
|| _mission_item.nav_cmd == NAV_CMD_VTOL_TAKEOFF
|
|| _mission_item.nav_cmd == NAV_CMD_VTOL_TAKEOFF
|
||||||
@@ -330,9 +330,9 @@ Mission::set_execution_mode(const uint8_t mode)
|
|||||||
case mission_result_s::MISSION_EXECUTION_MODE_FAST_FORWARD:
|
case mission_result_s::MISSION_EXECUTION_MODE_FAST_FORWARD:
|
||||||
if (mode == mission_result_s::MISSION_EXECUTION_MODE_REVERSE) {
|
if (mode == mission_result_s::MISSION_EXECUTION_MODE_REVERSE) {
|
||||||
// command a transition if in vtol mc mode
|
// command a transition if in vtol mc mode
|
||||||
if (_navigator->get_vstatus()->vehicle_type == vehicle_status_s::VEHICLE_TYPE_ROTARY_WING &&
|
if (_navigator_core.isRotaryWing() &&
|
||||||
_navigator->get_vstatus()->is_vtol &&
|
_navigator_core.isVTOL() &&
|
||||||
!_navigator->get_land_detected()->landed) {
|
!_navigator_core.getLanded()) {
|
||||||
|
|
||||||
set_vtol_transition_item(&_mission_item, vtol_vehicle_status_s::VEHICLE_VTOL_STATE_FW);
|
set_vtol_transition_item(&_mission_item, vtol_vehicle_status_s::VEHICLE_VTOL_STATE_FW);
|
||||||
|
|
||||||
@@ -418,16 +418,16 @@ Mission::find_mission_land_start()
|
|||||||
_landing_start_lat = missionitem.lat;
|
_landing_start_lat = missionitem.lat;
|
||||||
_landing_start_lon = missionitem.lon;
|
_landing_start_lon = missionitem.lon;
|
||||||
_landing_start_alt = missionitem.altitude_is_relative ? missionitem.altitude +
|
_landing_start_alt = missionitem.altitude_is_relative ? missionitem.altitude +
|
||||||
_navigator->get_home_position()->alt : missionitem.altitude;
|
_navigator_core.getHomeAltAMSLMeter() : missionitem.altitude;
|
||||||
_land_start_available = true;
|
_land_start_available = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (((missionitem.nav_cmd == NAV_CMD_VTOL_LAND) && _navigator->get_vstatus()->is_vtol) ||
|
if (((missionitem.nav_cmd == NAV_CMD_VTOL_LAND) && _navigator_core.isVTOL()) ||
|
||||||
(missionitem.nav_cmd == NAV_CMD_LAND)) {
|
(missionitem.nav_cmd == NAV_CMD_LAND)) {
|
||||||
|
|
||||||
_landing_lat = missionitem.lat;
|
_landing_lat = missionitem.lat;
|
||||||
_landing_lon = missionitem.lon;
|
_landing_lon = missionitem.lon;
|
||||||
_landing_alt = missionitem.altitude_is_relative ? missionitem.altitude + _navigator->get_home_position()->alt :
|
_landing_alt = missionitem.altitude_is_relative ? missionitem.altitude + _navigator_core.getHomeAltAMSLMeter() :
|
||||||
missionitem.altitude;
|
missionitem.altitude;
|
||||||
|
|
||||||
// don't have a valid land start yet, use the landing item itself then
|
// don't have a valid land start yet, use the landing item itself then
|
||||||
@@ -529,7 +529,7 @@ Mission::update_mission()
|
|||||||
* TODO add a flag to mission_s which actually tracks if the position of the waypoint changed */
|
* TODO add a flag to mission_s which actually tracks if the position of the waypoint changed */
|
||||||
if (((_mission.count != old_mission.count) ||
|
if (((_mission.count != old_mission.count) ||
|
||||||
(_mission.dataman_id != old_mission.dataman_id)) &&
|
(_mission.dataman_id != old_mission.dataman_id)) &&
|
||||||
!_navigator->get_land_detected()->landed) {
|
!_navigator_core.getLanded()) {
|
||||||
_mission_waypoints_changed = true;
|
_mission_waypoints_changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -640,7 +640,7 @@ Mission::set_mission_items()
|
|||||||
/* no mission available or mission finished, switch to loiter */
|
/* no mission available or mission finished, switch to loiter */
|
||||||
if (_mission_type != MISSION_TYPE_NONE) {
|
if (_mission_type != MISSION_TYPE_NONE) {
|
||||||
|
|
||||||
if (_navigator->get_land_detected()->landed) {
|
if (_navigator_core.getLanded()) {
|
||||||
mavlink_log_info(_navigator->get_mavlink_log_pub(),
|
mavlink_log_info(_navigator->get_mavlink_log_pub(),
|
||||||
_mission_execution_mode == mission_result_s::MISSION_EXECUTION_MODE_REVERSE ? "Reverse Mission finished, landed" :
|
_mission_execution_mode == mission_result_s::MISSION_EXECUTION_MODE_REVERSE ? "Reverse Mission finished, landed" :
|
||||||
"Mission finished, landed.");
|
"Mission finished, landed.");
|
||||||
@@ -661,7 +661,7 @@ Mission::set_mission_items()
|
|||||||
_mission_type = MISSION_TYPE_NONE;
|
_mission_type = MISSION_TYPE_NONE;
|
||||||
|
|
||||||
/* set loiter mission item and ensure that there is a minimum clearance from home */
|
/* set loiter mission item and ensure that there is a minimum clearance from home */
|
||||||
set_loiter_item(&_mission_item, _navigator->get_takeoff_min_alt());
|
set_loiter_item(&_mission_item, _navigator_core.getRelativeTakeoffMinAltitudeMeter());
|
||||||
|
|
||||||
/* update position setpoint triplet */
|
/* update position setpoint triplet */
|
||||||
position_setpoint_triplet_s *pos_sp_triplet = _navigator->get_position_setpoint_triplet();
|
position_setpoint_triplet_s *pos_sp_triplet = _navigator->get_position_setpoint_triplet();
|
||||||
@@ -683,7 +683,7 @@ Mission::set_mission_items()
|
|||||||
* https://en.wikipedia.org/wiki/Loiter_(aeronautics)
|
* https://en.wikipedia.org/wiki/Loiter_(aeronautics)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (_navigator->get_land_detected()->landed) {
|
if (_navigator_core.getLanded()) {
|
||||||
/* landed, refusing to take off without a mission */
|
/* landed, refusing to take off without a mission */
|
||||||
mavlink_log_critical(_navigator->get_mavlink_log_pub(), "No valid mission available, refusing takeoff.");
|
mavlink_log_critical(_navigator->get_mavlink_log_pub(), "No valid mission available, refusing takeoff.");
|
||||||
|
|
||||||
@@ -711,7 +711,7 @@ Mission::set_mission_items()
|
|||||||
case mission_result_s::MISSION_EXECUTION_MODE_NORMAL:
|
case mission_result_s::MISSION_EXECUTION_MODE_NORMAL:
|
||||||
case mission_result_s::MISSION_EXECUTION_MODE_FAST_FORWARD: {
|
case mission_result_s::MISSION_EXECUTION_MODE_FAST_FORWARD: {
|
||||||
/* force vtol land */
|
/* force vtol land */
|
||||||
if (_navigator->force_vtol() && _mission_item.nav_cmd == NAV_CMD_LAND) {
|
if (_navigator_core.forceVTOL() && _mission_item.nav_cmd == NAV_CMD_LAND) {
|
||||||
_mission_item.nav_cmd = NAV_CMD_VTOL_LAND;
|
_mission_item.nav_cmd = NAV_CMD_VTOL_LAND;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -733,13 +733,13 @@ Mission::set_mission_items()
|
|||||||
float takeoff_alt = calculate_takeoff_altitude(&_mission_item);
|
float takeoff_alt = calculate_takeoff_altitude(&_mission_item);
|
||||||
|
|
||||||
mavlink_log_info(_navigator->get_mavlink_log_pub(), "Takeoff to %.1f meters above home.",
|
mavlink_log_info(_navigator->get_mavlink_log_pub(), "Takeoff to %.1f meters above home.",
|
||||||
(double)(takeoff_alt - _navigator->get_home_position()->alt));
|
(double)(takeoff_alt - _navigator_core.getHomeAltAMSLMeter()));
|
||||||
|
|
||||||
_mission_item.nav_cmd = NAV_CMD_TAKEOFF;
|
_mission_item.nav_cmd = NAV_CMD_TAKEOFF;
|
||||||
_mission_item.lat = _navigator->get_global_position()->lat;
|
_mission_item.lat = _navigator_core.getLatRad();
|
||||||
_mission_item.lon = _navigator->get_global_position()->lon;
|
_mission_item.lon = _navigator_core.getLonRad();
|
||||||
/* hold heading for takeoff items */
|
/* hold heading for takeoff items */
|
||||||
_mission_item.yaw = _navigator->get_local_position()->heading;
|
_mission_item.yaw = _navigator_core.getTrueHeadingRad();
|
||||||
_mission_item.altitude = takeoff_alt;
|
_mission_item.altitude = takeoff_alt;
|
||||||
_mission_item.altitude_is_relative = false;
|
_mission_item.altitude_is_relative = false;
|
||||||
_mission_item.autocontinue = true;
|
_mission_item.autocontinue = true;
|
||||||
@@ -748,7 +748,7 @@ Mission::set_mission_items()
|
|||||||
} else if (_mission_item.nav_cmd == NAV_CMD_TAKEOFF
|
} else if (_mission_item.nav_cmd == NAV_CMD_TAKEOFF
|
||||||
&& _work_item_type == WORK_ITEM_TYPE_DEFAULT
|
&& _work_item_type == WORK_ITEM_TYPE_DEFAULT
|
||||||
&& new_work_item_type == WORK_ITEM_TYPE_DEFAULT
|
&& new_work_item_type == WORK_ITEM_TYPE_DEFAULT
|
||||||
&& _navigator->get_vstatus()->vehicle_type == vehicle_status_s::VEHICLE_TYPE_ROTARY_WING) {
|
&& _navigator_core.isRotaryWing()) {
|
||||||
|
|
||||||
/* if there is no need to do a takeoff but we have a takeoff item, treat is as waypoint */
|
/* if there is no need to do a takeoff but we have a takeoff item, treat is as waypoint */
|
||||||
_mission_item.nav_cmd = NAV_CMD_WAYPOINT;
|
_mission_item.nav_cmd = NAV_CMD_WAYPOINT;
|
||||||
@@ -759,7 +759,7 @@ Mission::set_mission_items()
|
|||||||
&& _work_item_type == WORK_ITEM_TYPE_DEFAULT
|
&& _work_item_type == WORK_ITEM_TYPE_DEFAULT
|
||||||
&& new_work_item_type == WORK_ITEM_TYPE_DEFAULT) {
|
&& new_work_item_type == WORK_ITEM_TYPE_DEFAULT) {
|
||||||
|
|
||||||
if (_navigator->get_vstatus()->vehicle_type == vehicle_status_s::VEHICLE_TYPE_ROTARY_WING) {
|
if (_navigator_core.isRotaryWing()) {
|
||||||
/* haven't transitioned yet, trigger vtol takeoff logic below */
|
/* haven't transitioned yet, trigger vtol takeoff logic below */
|
||||||
_work_item_type = WORK_ITEM_TYPE_TAKEOFF;
|
_work_item_type = WORK_ITEM_TYPE_TAKEOFF;
|
||||||
|
|
||||||
@@ -786,15 +786,15 @@ Mission::set_mission_items()
|
|||||||
if (_mission_item.nav_cmd == NAV_CMD_VTOL_TAKEOFF &&
|
if (_mission_item.nav_cmd == NAV_CMD_VTOL_TAKEOFF &&
|
||||||
_work_item_type == WORK_ITEM_TYPE_TAKEOFF &&
|
_work_item_type == WORK_ITEM_TYPE_TAKEOFF &&
|
||||||
new_work_item_type == WORK_ITEM_TYPE_DEFAULT &&
|
new_work_item_type == WORK_ITEM_TYPE_DEFAULT &&
|
||||||
_navigator->get_vstatus()->vehicle_type == vehicle_status_s::VEHICLE_TYPE_ROTARY_WING &&
|
_navigator_core.isRotaryWing() &&
|
||||||
!_navigator->get_land_detected()->landed) {
|
!_navigator_core.getLanded()) {
|
||||||
|
|
||||||
/* disable weathervane before front transition for allowing yaw to align */
|
/* disable weathervane before front transition for allowing yaw to align */
|
||||||
pos_sp_triplet->current.disable_weather_vane = true;
|
pos_sp_triplet->current.disable_weather_vane = true;
|
||||||
|
|
||||||
/* set yaw setpoint to heading of VTOL_TAKEOFF wp against current position */
|
/* set yaw setpoint to heading of VTOL_TAKEOFF wp against current position */
|
||||||
_mission_item.yaw = get_bearing_to_next_waypoint(
|
_mission_item.yaw = get_bearing_to_next_waypoint(
|
||||||
_navigator->get_global_position()->lat, _navigator->get_global_position()->lon,
|
_navigator_core.getLatRad(), _navigator_core.getLonRad(),
|
||||||
_mission_item.lat, _mission_item.lon);
|
_mission_item.lat, _mission_item.lon);
|
||||||
|
|
||||||
_mission_item.force_heading = true;
|
_mission_item.force_heading = true;
|
||||||
@@ -802,15 +802,15 @@ Mission::set_mission_items()
|
|||||||
new_work_item_type = WORK_ITEM_TYPE_ALIGN;
|
new_work_item_type = WORK_ITEM_TYPE_ALIGN;
|
||||||
|
|
||||||
/* set position setpoint to current while aligning */
|
/* set position setpoint to current while aligning */
|
||||||
_mission_item.lat = _navigator->get_global_position()->lat;
|
_mission_item.lat = _navigator_core.getLatRad();
|
||||||
_mission_item.lon = _navigator->get_global_position()->lon;
|
_mission_item.lon = _navigator_core.getLonRad();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* heading is aligned now, prepare transition */
|
/* heading is aligned now, prepare transition */
|
||||||
if (_mission_item.nav_cmd == NAV_CMD_VTOL_TAKEOFF &&
|
if (_mission_item.nav_cmd == NAV_CMD_VTOL_TAKEOFF &&
|
||||||
_work_item_type == WORK_ITEM_TYPE_ALIGN &&
|
_work_item_type == WORK_ITEM_TYPE_ALIGN &&
|
||||||
_navigator->get_vstatus()->vehicle_type == vehicle_status_s::VEHICLE_TYPE_ROTARY_WING &&
|
_navigator_core.isRotaryWing() &&
|
||||||
!_navigator->get_land_detected()->landed) {
|
!_navigator_core.getLanded()) {
|
||||||
|
|
||||||
/* re-enable weather vane again after alignment */
|
/* re-enable weather vane again after alignment */
|
||||||
pos_sp_triplet->current.disable_weather_vane = false;
|
pos_sp_triplet->current.disable_weather_vane = false;
|
||||||
@@ -821,7 +821,7 @@ Mission::set_mission_items()
|
|||||||
}
|
}
|
||||||
|
|
||||||
set_vtol_transition_item(&_mission_item, vtol_vehicle_status_s::VEHICLE_VTOL_STATE_FW);
|
set_vtol_transition_item(&_mission_item, vtol_vehicle_status_s::VEHICLE_VTOL_STATE_FW);
|
||||||
_mission_item.yaw = _navigator->get_local_position()->heading;
|
_mission_item.yaw = _navigator_core.getTrueHeadingRad();
|
||||||
|
|
||||||
/* set position setpoint to target during the transition */
|
/* set position setpoint to target during the transition */
|
||||||
generate_waypoint_from_heading(&pos_sp_triplet->current, _mission_item.yaw);
|
generate_waypoint_from_heading(&pos_sp_triplet->current, _mission_item.yaw);
|
||||||
@@ -842,7 +842,7 @@ Mission::set_mission_items()
|
|||||||
if (_mission_item.nav_cmd == NAV_CMD_VTOL_LAND
|
if (_mission_item.nav_cmd == NAV_CMD_VTOL_LAND
|
||||||
&& (_work_item_type == WORK_ITEM_TYPE_DEFAULT || _work_item_type == WORK_ITEM_TYPE_TRANSITON_AFTER_TAKEOFF)
|
&& (_work_item_type == WORK_ITEM_TYPE_DEFAULT || _work_item_type == WORK_ITEM_TYPE_TRANSITON_AFTER_TAKEOFF)
|
||||||
&& new_work_item_type == WORK_ITEM_TYPE_DEFAULT
|
&& new_work_item_type == WORK_ITEM_TYPE_DEFAULT
|
||||||
&& !_navigator->get_land_detected()->landed) {
|
&& !_navigator_core.getLanded()) {
|
||||||
|
|
||||||
new_work_item_type = WORK_ITEM_TYPE_MOVE_TO_LAND;
|
new_work_item_type = WORK_ITEM_TYPE_MOVE_TO_LAND;
|
||||||
|
|
||||||
@@ -850,7 +850,7 @@ Mission::set_mission_items()
|
|||||||
mission_item_next_position = _mission_item;
|
mission_item_next_position = _mission_item;
|
||||||
has_next_position_item = true;
|
has_next_position_item = true;
|
||||||
|
|
||||||
float altitude = _navigator->get_global_position()->alt;
|
float altitude = _navigator_core.getAltitudeAMSLMeters();
|
||||||
|
|
||||||
if (pos_sp_triplet->current.valid && pos_sp_triplet->current.type == position_setpoint_s::SETPOINT_TYPE_POSITION) {
|
if (pos_sp_triplet->current.valid && pos_sp_triplet->current.type == position_setpoint_s::SETPOINT_TYPE_POSITION) {
|
||||||
altitude = pos_sp_triplet->current.alt;
|
altitude = pos_sp_triplet->current.alt;
|
||||||
@@ -868,11 +868,11 @@ Mission::set_mission_items()
|
|||||||
if (_mission_item.nav_cmd == NAV_CMD_VTOL_LAND
|
if (_mission_item.nav_cmd == NAV_CMD_VTOL_LAND
|
||||||
&& _work_item_type == WORK_ITEM_TYPE_MOVE_TO_LAND
|
&& _work_item_type == WORK_ITEM_TYPE_MOVE_TO_LAND
|
||||||
&& new_work_item_type == WORK_ITEM_TYPE_DEFAULT
|
&& new_work_item_type == WORK_ITEM_TYPE_DEFAULT
|
||||||
&& _navigator->get_vstatus()->vehicle_type == vehicle_status_s::VEHICLE_TYPE_FIXED_WING
|
&& _navigator_core.isFixedWing()
|
||||||
&& !_navigator->get_land_detected()->landed) {
|
&& !_navigator_core.getLanded()) {
|
||||||
|
|
||||||
set_vtol_transition_item(&_mission_item, vtol_vehicle_status_s::VEHICLE_VTOL_STATE_MC);
|
set_vtol_transition_item(&_mission_item, vtol_vehicle_status_s::VEHICLE_VTOL_STATE_MC);
|
||||||
_mission_item.altitude = _navigator->get_global_position()->alt;
|
_mission_item.altitude = _navigator_core.getAltitudeAMSLMeters();
|
||||||
_mission_item.altitude_is_relative = false;
|
_mission_item.altitude_is_relative = false;
|
||||||
|
|
||||||
new_work_item_type = WORK_ITEM_TYPE_MOVE_TO_LAND_AFTER_TRANSITION;
|
new_work_item_type = WORK_ITEM_TYPE_MOVE_TO_LAND_AFTER_TRANSITION;
|
||||||
@@ -901,7 +901,7 @@ Mission::set_mission_items()
|
|||||||
* XXX: We might want to change that at some point if it is clear to the user
|
* XXX: We might want to change that at some point if it is clear to the user
|
||||||
* what the altitude means on this waypoint type.
|
* what the altitude means on this waypoint type.
|
||||||
*/
|
*/
|
||||||
float altitude = _navigator->get_global_position()->alt;
|
float altitude = _navigator_core.getAltitudeAMSLMeters();
|
||||||
|
|
||||||
if (pos_sp_triplet->current.valid
|
if (pos_sp_triplet->current.valid
|
||||||
&& pos_sp_triplet->current.type == position_setpoint_s::SETPOINT_TYPE_POSITION) {
|
&& pos_sp_triplet->current.type == position_setpoint_s::SETPOINT_TYPE_POSITION) {
|
||||||
@@ -1001,8 +1001,8 @@ Mission::set_mission_items()
|
|||||||
if (_mission_item.nav_cmd == NAV_CMD_DO_VTOL_TRANSITION
|
if (_mission_item.nav_cmd == NAV_CMD_DO_VTOL_TRANSITION
|
||||||
&& _work_item_type == WORK_ITEM_TYPE_DEFAULT
|
&& _work_item_type == WORK_ITEM_TYPE_DEFAULT
|
||||||
&& new_work_item_type == WORK_ITEM_TYPE_DEFAULT
|
&& new_work_item_type == WORK_ITEM_TYPE_DEFAULT
|
||||||
&& _navigator->get_vstatus()->vehicle_type == vehicle_status_s::VEHICLE_TYPE_ROTARY_WING
|
&& _navigator_core.isRotaryWing()
|
||||||
&& !_navigator->get_land_detected()->landed
|
&& !_navigator_core.getLanded()
|
||||||
&& has_next_position_item) {
|
&& has_next_position_item) {
|
||||||
|
|
||||||
/* disable weathervane before front transition for allowing yaw to align */
|
/* disable weathervane before front transition for allowing yaw to align */
|
||||||
@@ -1134,9 +1134,8 @@ Mission::set_mission_items()
|
|||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
/* allow the vehicle to decelerate before reaching a wp with a hold time */
|
const bool brake_for_hold = _navigator_core.isRotaryWing()
|
||||||
const bool brake_for_hold = _navigator->get_vstatus()->vehicle_type == vehicle_status_s::VEHICLE_TYPE_ROTARY_WING
|
&& get_time_inside(_mission_item) > FLT_EPSILON; //allow the vehicle to decelerate before reaching a wp with a hold time
|
||||||
&& get_time_inside(_mission_item) > FLT_EPSILON;
|
|
||||||
|
|
||||||
if (_mission_item.autocontinue && !brake_for_hold) {
|
if (_mission_item.autocontinue && !brake_for_hold) {
|
||||||
/* try to process next mission item */
|
/* try to process next mission item */
|
||||||
@@ -1162,19 +1161,19 @@ Mission::set_mission_items()
|
|||||||
bool
|
bool
|
||||||
Mission::do_need_vertical_takeoff()
|
Mission::do_need_vertical_takeoff()
|
||||||
{
|
{
|
||||||
if (_navigator->get_vstatus()->vehicle_type == vehicle_status_s::VEHICLE_TYPE_ROTARY_WING) {
|
if (_navigator_core.isRotaryWing()) {
|
||||||
|
|
||||||
float takeoff_alt = calculate_takeoff_altitude(&_mission_item);
|
float takeoff_alt = calculate_takeoff_altitude(&_mission_item);
|
||||||
|
|
||||||
if (_navigator->get_land_detected()->landed) {
|
if (_navigator_core.getLanded()) {
|
||||||
/* force takeoff if landed (additional protection) */
|
/* force takeoff if landed (additional protection) */
|
||||||
_need_takeoff = true;
|
_need_takeoff = true;
|
||||||
|
|
||||||
} else if (_navigator->get_global_position()->alt > takeoff_alt - _navigator->get_altitude_acceptance_radius()) {
|
} else if (_navigator_core.getAltitudeAMSLMeters() > takeoff_alt - _navigator_core.getAltAcceptanceRadiusMeter()) {
|
||||||
/* if in-air and already above takeoff height, don't do takeoff */
|
/* if in-air and already above takeoff height, don't do takeoff */
|
||||||
_need_takeoff = false;
|
_need_takeoff = false;
|
||||||
|
|
||||||
} else if (_navigator->get_global_position()->alt <= takeoff_alt - _navigator->get_altitude_acceptance_radius()
|
} else if (_navigator_core.getAltitudeAMSLMeters() <= takeoff_alt - _navigator_core.getAltAcceptanceRadiusMeter()
|
||||||
&& (_mission_item.nav_cmd == NAV_CMD_TAKEOFF
|
&& (_mission_item.nav_cmd == NAV_CMD_TAKEOFF
|
||||||
|| _mission_item.nav_cmd == NAV_CMD_VTOL_TAKEOFF)) {
|
|| _mission_item.nav_cmd == NAV_CMD_VTOL_TAKEOFF)) {
|
||||||
/* if in-air but below takeoff height and we have a takeoff item */
|
/* if in-air but below takeoff height and we have a takeoff item */
|
||||||
@@ -1200,13 +1199,13 @@ Mission::do_need_vertical_takeoff()
|
|||||||
bool
|
bool
|
||||||
Mission::do_need_move_to_land()
|
Mission::do_need_move_to_land()
|
||||||
{
|
{
|
||||||
if (_navigator->get_vstatus()->vehicle_type == vehicle_status_s::VEHICLE_TYPE_ROTARY_WING
|
if (_navigator_core.isRotaryWing()
|
||||||
&& (_mission_item.nav_cmd == NAV_CMD_LAND || _mission_item.nav_cmd == NAV_CMD_VTOL_LAND)) {
|
&& (_mission_item.nav_cmd == NAV_CMD_LAND || _mission_item.nav_cmd == NAV_CMD_VTOL_LAND)) {
|
||||||
|
|
||||||
float d_current = get_distance_to_next_waypoint(_mission_item.lat, _mission_item.lon,
|
float d_current = get_distance_to_next_waypoint(_mission_item.lat, _mission_item.lon,
|
||||||
_navigator->get_global_position()->lat, _navigator->get_global_position()->lon);
|
_navigator_core.getLatRad(), _navigator_core.getLonRad());
|
||||||
|
|
||||||
return d_current > _navigator->get_acceptance_radius();
|
return d_current > _navigator_core.getAcceptanceRadiusMeter();
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -1215,13 +1214,13 @@ Mission::do_need_move_to_land()
|
|||||||
bool
|
bool
|
||||||
Mission::do_need_move_to_takeoff()
|
Mission::do_need_move_to_takeoff()
|
||||||
{
|
{
|
||||||
if (_navigator->get_vstatus()->vehicle_type == vehicle_status_s::VEHICLE_TYPE_ROTARY_WING
|
if (_navigator_core.isRotaryWing()
|
||||||
&& _mission_item.nav_cmd == NAV_CMD_VTOL_TAKEOFF) {
|
&& _mission_item.nav_cmd == NAV_CMD_VTOL_TAKEOFF) {
|
||||||
|
|
||||||
float d_current = get_distance_to_next_waypoint(_mission_item.lat, _mission_item.lon,
|
float d_current = get_distance_to_next_waypoint(_mission_item.lat, _mission_item.lon,
|
||||||
_navigator->get_global_position()->lat, _navigator->get_global_position()->lon);
|
_navigator_core.getLatRad(), _navigator_core.getLonRad());
|
||||||
|
|
||||||
return d_current > _navigator->get_acceptance_radius();
|
return d_current > _navigator_core.getAcceptanceRadiusMeter();
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -1236,9 +1235,9 @@ Mission::copy_position_if_valid(struct mission_item_s *mission_item, struct posi
|
|||||||
mission_item->altitude = setpoint->alt;
|
mission_item->altitude = setpoint->alt;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
mission_item->lat = _navigator->get_global_position()->lat;
|
mission_item->lat = _navigator_core.getLatRad();
|
||||||
mission_item->lon = _navigator->get_global_position()->lon;
|
mission_item->lon = _navigator_core.getLonRad();
|
||||||
mission_item->altitude = _navigator->get_global_position()->alt;
|
mission_item->altitude = _navigator_core.getAltitudeAMSLMeters();
|
||||||
}
|
}
|
||||||
|
|
||||||
mission_item->altitude_is_relative = false;
|
mission_item->altitude_is_relative = false;
|
||||||
@@ -1253,7 +1252,7 @@ Mission::set_align_mission_item(struct mission_item_s *mission_item, struct miss
|
|||||||
mission_item->autocontinue = true;
|
mission_item->autocontinue = true;
|
||||||
mission_item->time_inside = 0.0f;
|
mission_item->time_inside = 0.0f;
|
||||||
mission_item->yaw = get_bearing_to_next_waypoint(
|
mission_item->yaw = get_bearing_to_next_waypoint(
|
||||||
_navigator->get_global_position()->lat, _navigator->get_global_position()->lon,
|
_navigator_core.getLatRad(), _navigator_core.getLonRad(),
|
||||||
mission_item_next->lat, mission_item_next->lon);
|
mission_item_next->lat, mission_item_next->lon);
|
||||||
mission_item->force_heading = true;
|
mission_item->force_heading = true;
|
||||||
}
|
}
|
||||||
@@ -1265,11 +1264,13 @@ Mission::calculate_takeoff_altitude(struct mission_item_s *mission_item)
|
|||||||
float takeoff_alt = get_absolute_altitude_for_item(*mission_item);
|
float takeoff_alt = get_absolute_altitude_for_item(*mission_item);
|
||||||
|
|
||||||
/* takeoff to at least MIS_TAKEOFF_ALT above home/ground, even if first waypoint is lower */
|
/* takeoff to at least MIS_TAKEOFF_ALT above home/ground, even if first waypoint is lower */
|
||||||
if (_navigator->get_land_detected()->landed) {
|
if (_navigator_core.getLanded()) {
|
||||||
takeoff_alt = fmaxf(takeoff_alt, _navigator->get_global_position()->alt + _navigator->get_takeoff_min_alt());
|
takeoff_alt = fmaxf(takeoff_alt, _navigator_core.getAltitudeAMSLMeters() +
|
||||||
|
_navigator_core.getRelativeTakeoffMinAltitudeMeter());
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
takeoff_alt = fmaxf(takeoff_alt, _navigator->get_home_position()->alt + _navigator->get_takeoff_min_alt());
|
takeoff_alt = fmaxf(takeoff_alt, _navigator_core.getHomeAltAMSLMeter() +
|
||||||
|
_navigator_core.getRelativeTakeoffMinAltitudeMeter());
|
||||||
}
|
}
|
||||||
|
|
||||||
return takeoff_alt;
|
return takeoff_alt;
|
||||||
@@ -1284,11 +1285,11 @@ Mission::heading_sp_update()
|
|||||||
// Only update if current triplet is valid
|
// Only update if current triplet is valid
|
||||||
if (pos_sp_triplet->current.valid) {
|
if (pos_sp_triplet->current.valid) {
|
||||||
|
|
||||||
double point_from_latlon[2] = { _navigator->get_global_position()->lat,
|
double point_from_latlon[2] = { _navigator_core.getLatRad(),
|
||||||
_navigator->get_global_position()->lon
|
_navigator_core.getLonRad()
|
||||||
};
|
};
|
||||||
double point_to_latlon[2] = { _navigator->get_global_position()->lat,
|
double point_to_latlon[2] = { _navigator_core.getLatRad(),
|
||||||
_navigator->get_global_position()->lon
|
_navigator_core.getLonRad()
|
||||||
};
|
};
|
||||||
float yaw_offset = 0.0f;
|
float yaw_offset = 0.0f;
|
||||||
|
|
||||||
@@ -1327,7 +1328,7 @@ Mission::heading_sp_update()
|
|||||||
float d_current = get_distance_to_next_waypoint(point_from_latlon[0],
|
float d_current = get_distance_to_next_waypoint(point_from_latlon[0],
|
||||||
point_from_latlon[1], point_to_latlon[0], point_to_latlon[1]);
|
point_from_latlon[1], point_to_latlon[0], point_to_latlon[1]);
|
||||||
|
|
||||||
if (d_current > _navigator->get_acceptance_radius()) {
|
if (d_current > _navigator_core.getAcceptanceRadiusMeter()) {
|
||||||
float yaw = matrix::wrap_pi(
|
float yaw = matrix::wrap_pi(
|
||||||
get_bearing_to_next_waypoint(point_from_latlon[0],
|
get_bearing_to_next_waypoint(point_from_latlon[0],
|
||||||
point_from_latlon[1], point_to_latlon[0],
|
point_from_latlon[1], point_to_latlon[0],
|
||||||
@@ -1339,7 +1340,7 @@ Mission::heading_sp_update()
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (!pos_sp_triplet->current.yaw_valid) {
|
if (!pos_sp_triplet->current.yaw_valid) {
|
||||||
_mission_item.yaw = _navigator->get_local_position()->heading;
|
_mission_item.yaw = _navigator_core.getTrueHeadingRad();
|
||||||
pos_sp_triplet->current.yaw = _mission_item.yaw;
|
pos_sp_triplet->current.yaw = _mission_item.yaw;
|
||||||
pos_sp_triplet->current.yaw_valid = true;
|
pos_sp_triplet->current.yaw_valid = true;
|
||||||
}
|
}
|
||||||
@@ -1383,15 +1384,15 @@ Mission::do_abort_landing()
|
|||||||
// loiter at the larger of MIS_LTRMIN_ALT above the landing point
|
// loiter at the larger of MIS_LTRMIN_ALT above the landing point
|
||||||
// or 2 * FW_CLMBOUT_DIFF above the current altitude
|
// or 2 * FW_CLMBOUT_DIFF above the current altitude
|
||||||
const float alt_landing = get_absolute_altitude_for_item(_mission_item);
|
const float alt_landing = get_absolute_altitude_for_item(_mission_item);
|
||||||
const float alt_sp = math::max(alt_landing + _navigator->get_loiter_min_alt(),
|
const float alt_sp = math::max(alt_landing + _navigator_core.getRelativeLoiterMinAltitudeMeter(),
|
||||||
_navigator->get_global_position()->alt + 20.0f);
|
_navigator_core.getAltitudeAMSLMeters() + 20.0f);
|
||||||
|
|
||||||
// turn current landing waypoint into an indefinite loiter
|
// turn current landing waypoint into an indefinite loiter
|
||||||
_mission_item.nav_cmd = NAV_CMD_LOITER_UNLIMITED;
|
_mission_item.nav_cmd = NAV_CMD_LOITER_UNLIMITED;
|
||||||
_mission_item.altitude_is_relative = false;
|
_mission_item.altitude_is_relative = false;
|
||||||
_mission_item.altitude = alt_sp;
|
_mission_item.altitude = alt_sp;
|
||||||
_mission_item.loiter_radius = _navigator->get_loiter_radius();
|
_mission_item.loiter_radius = _navigator_core.getLoiterRadiusMeter();
|
||||||
_mission_item.acceptance_radius = _navigator->get_acceptance_radius();
|
_mission_item.acceptance_radius = _navigator_core.getAcceptanceRadiusMeter();
|
||||||
_mission_item.autocontinue = false;
|
_mission_item.autocontinue = false;
|
||||||
_mission_item.origin = ORIGIN_ONBOARD;
|
_mission_item.origin = ORIGIN_ONBOARD;
|
||||||
|
|
||||||
@@ -1659,7 +1660,7 @@ Mission::set_current_mission_item()
|
|||||||
void
|
void
|
||||||
Mission::check_mission_valid(bool force)
|
Mission::check_mission_valid(bool force)
|
||||||
{
|
{
|
||||||
if ((!_home_inited && _navigator->home_position_valid()) || force) {
|
if ((!_home_inited && _navigator_core.isHomeValid()) || force) {
|
||||||
|
|
||||||
MissionFeasibilityChecker _missionFeasibilityChecker(_navigator);
|
MissionFeasibilityChecker _missionFeasibilityChecker(_navigator);
|
||||||
|
|
||||||
@@ -1672,7 +1673,7 @@ Mission::check_mission_valid(bool force)
|
|||||||
_navigator->get_mission_result()->seq_total = _mission.count;
|
_navigator->get_mission_result()->seq_total = _mission.count;
|
||||||
_navigator->increment_mission_instance_count();
|
_navigator->increment_mission_instance_count();
|
||||||
_navigator->set_mission_result_updated();
|
_navigator->set_mission_result_updated();
|
||||||
_home_inited = _navigator->home_position_valid();
|
_home_inited = _navigator_core.isHomeValid();
|
||||||
|
|
||||||
// find and store landing start marker (if available)
|
// find and store landing start marker (if available)
|
||||||
find_mission_land_start();
|
find_mission_land_start();
|
||||||
@@ -1733,7 +1734,7 @@ bool
|
|||||||
Mission::need_to_reset_mission()
|
Mission::need_to_reset_mission()
|
||||||
{
|
{
|
||||||
/* reset mission state when disarmed */
|
/* reset mission state when disarmed */
|
||||||
if (_navigator->get_vstatus()->arming_state != vehicle_status_s::ARMING_STATE_ARMED && _need_mission_reset) {
|
if (_navigator_core.isNotArmed() && _need_mission_reset) {
|
||||||
_need_mission_reset = false;
|
_need_mission_reset = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -1745,7 +1746,7 @@ void
|
|||||||
Mission::generate_waypoint_from_heading(struct position_setpoint_s *setpoint, float yaw)
|
Mission::generate_waypoint_from_heading(struct position_setpoint_s *setpoint, float yaw)
|
||||||
{
|
{
|
||||||
waypoint_from_heading_and_distance(
|
waypoint_from_heading_and_distance(
|
||||||
_navigator->get_global_position()->lat, _navigator->get_global_position()->lon,
|
_navigator_core.getLatRad(), _navigator_core.getLonRad(),
|
||||||
yaw, 1000000.0f,
|
yaw, 1000000.0f,
|
||||||
&(setpoint->lat), &(setpoint->lon));
|
&(setpoint->lat), &(setpoint->lon));
|
||||||
setpoint->type = position_setpoint_s::SETPOINT_TYPE_POSITION;
|
setpoint->type = position_setpoint_s::SETPOINT_TYPE_POSITION;
|
||||||
@@ -1773,13 +1774,13 @@ Mission::index_closest_mission_item() const
|
|||||||
if (item_contains_position(missionitem)) {
|
if (item_contains_position(missionitem)) {
|
||||||
// do not consider land waypoints for a fw
|
// do not consider land waypoints for a fw
|
||||||
if (!((missionitem.nav_cmd == NAV_CMD_LAND) &&
|
if (!((missionitem.nav_cmd == NAV_CMD_LAND) &&
|
||||||
(_navigator->get_vstatus()->vehicle_type == vehicle_status_s::VEHICLE_TYPE_FIXED_WING) &&
|
(_navigator_core.isFixedWing()) &&
|
||||||
(!_navigator->get_vstatus()->is_vtol))) {
|
(!_navigator_core.isVTOL()))) {
|
||||||
float dist = get_distance_to_point_global_wgs84(missionitem.lat, missionitem.lon,
|
float dist = get_distance_to_point_global_wgs84(missionitem.lat, missionitem.lon,
|
||||||
get_absolute_altitude_for_item(missionitem),
|
get_absolute_altitude_for_item(missionitem),
|
||||||
_navigator->get_global_position()->lat,
|
_navigator_core.getLatRad(),
|
||||||
_navigator->get_global_position()->lon,
|
_navigator_core.getLonRad(),
|
||||||
_navigator->get_global_position()->alt,
|
_navigator_core.getAltitudeAMSLMeters(),
|
||||||
&dist_xy, &dist_z);
|
&dist_xy, &dist_z);
|
||||||
|
|
||||||
if (dist < min_dist) {
|
if (dist < min_dist) {
|
||||||
@@ -1793,12 +1794,12 @@ Mission::index_closest_mission_item() const
|
|||||||
// for mission reverse also consider the home position
|
// for mission reverse also consider the home position
|
||||||
if (_mission_execution_mode == mission_result_s::MISSION_EXECUTION_MODE_REVERSE) {
|
if (_mission_execution_mode == mission_result_s::MISSION_EXECUTION_MODE_REVERSE) {
|
||||||
float dist = get_distance_to_point_global_wgs84(
|
float dist = get_distance_to_point_global_wgs84(
|
||||||
_navigator->get_home_position()->lat,
|
_navigator_core.getHomeLatRad(),
|
||||||
_navigator->get_home_position()->lon,
|
_navigator_core.getHomeLonRad(),
|
||||||
_navigator->get_home_position()->alt,
|
_navigator_core.getHomeAltAMSLMeter(),
|
||||||
_navigator->get_global_position()->lat,
|
_navigator_core.getLatRad(),
|
||||||
_navigator->get_global_position()->lon,
|
_navigator_core.getLonRad(),
|
||||||
_navigator->get_global_position()->alt,
|
_navigator_core.getAltitudeAMSLMeters(),
|
||||||
&dist_xy, &dist_z);
|
&dist_xy, &dist_z);
|
||||||
|
|
||||||
if (dist < min_dist) {
|
if (dist < min_dist) {
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ class Navigator;
|
|||||||
class Mission : public MissionBlock, public ModuleParams
|
class Mission : public MissionBlock, public ModuleParams
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Mission(Navigator *navigator);
|
Mission(Navigator *navigator, NavigatorCore &navigator_core);
|
||||||
~Mission() override = default;
|
~Mission() override = default;
|
||||||
|
|
||||||
void on_inactive() override;
|
void on_inactive() override;
|
||||||
|
|||||||
@@ -56,14 +56,15 @@
|
|||||||
|
|
||||||
using matrix::wrap_pi;
|
using matrix::wrap_pi;
|
||||||
|
|
||||||
MissionBlock::MissionBlock(Navigator *navigator) :
|
MissionBlock::MissionBlock(Navigator *navigator, NavigatorCore &navigator_core) :
|
||||||
NavigatorMode(navigator)
|
NavigatorMode(navigator),
|
||||||
|
_navigator_core(navigator_core)
|
||||||
{
|
{
|
||||||
_mission_item.lat = (double)NAN;
|
_mission_item.lat = (double)NAN;
|
||||||
_mission_item.lon = (double)NAN;
|
_mission_item.lon = (double)NAN;
|
||||||
_mission_item.yaw = NAN;
|
_mission_item.yaw = NAN;
|
||||||
_mission_item.loiter_radius = _navigator->get_loiter_radius();
|
//_mission_item.loiter_radius = _navigator_core.getLoiterRadiusMeter();
|
||||||
_mission_item.acceptance_radius = _navigator->get_acceptance_radius();
|
//_mission_item.acceptance_radius = _navigator_core.getHorAcceptanceRadiusMeter();
|
||||||
_mission_item.time_inside = 0.0f;
|
_mission_item.time_inside = 0.0f;
|
||||||
_mission_item.autocontinue = true;
|
_mission_item.autocontinue = true;
|
||||||
_mission_item.origin = ORIGIN_ONBOARD;
|
_mission_item.origin = ORIGIN_ONBOARD;
|
||||||
@@ -80,7 +81,7 @@ MissionBlock::is_mission_item_reached()
|
|||||||
|
|
||||||
case NAV_CMD_LAND: /* fall through */
|
case NAV_CMD_LAND: /* fall through */
|
||||||
case NAV_CMD_VTOL_LAND:
|
case NAV_CMD_VTOL_LAND:
|
||||||
return _navigator->get_land_detected()->landed;
|
return _navigator_core.getLanded();
|
||||||
|
|
||||||
case NAV_CMD_IDLE: /* fall through */
|
case NAV_CMD_IDLE: /* fall through */
|
||||||
case NAV_CMD_LOITER_UNLIMITED:
|
case NAV_CMD_LOITER_UNLIMITED:
|
||||||
@@ -114,11 +115,11 @@ MissionBlock::is_mission_item_reached()
|
|||||||
|
|
||||||
if (int(_mission_item.params[0]) == 3) {
|
if (int(_mission_item.params[0]) == 3) {
|
||||||
// transition to RW requested, only accept waypoint if vehicle state has changed accordingly
|
// transition to RW requested, only accept waypoint if vehicle state has changed accordingly
|
||||||
return _navigator->get_vstatus()->vehicle_type == vehicle_status_s::VEHICLE_TYPE_ROTARY_WING;
|
return _navigator_core.isRotaryWing();
|
||||||
|
|
||||||
} else if (int(_mission_item.params[0]) == 4) {
|
} else if (int(_mission_item.params[0]) == 4) {
|
||||||
// transition to FW requested, only accept waypoint if vehicle state has changed accordingly
|
// transition to FW requested, only accept waypoint if vehicle state has changed accordingly
|
||||||
return _navigator->get_vstatus()->vehicle_type == vehicle_status_s::VEHICLE_TYPE_FIXED_WING;
|
return _navigator_core.isFixedWing();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// invalid vtol transition request
|
// invalid vtol transition request
|
||||||
@@ -136,8 +137,7 @@ MissionBlock::is_mission_item_reached()
|
|||||||
|
|
||||||
hrt_abstime now = hrt_absolute_time();
|
hrt_abstime now = hrt_absolute_time();
|
||||||
|
|
||||||
if (!_navigator->get_land_detected()->landed && !_waypoint_position_reached) {
|
if (!_navigator_core.getLanded() && !_waypoint_position_reached) {
|
||||||
|
|
||||||
float dist = -1.0f;
|
float dist = -1.0f;
|
||||||
float dist_xy = -1.0f;
|
float dist_xy = -1.0f;
|
||||||
float dist_z = -1.0f;
|
float dist_z = -1.0f;
|
||||||
@@ -145,23 +145,22 @@ MissionBlock::is_mission_item_reached()
|
|||||||
const float mission_item_altitude_amsl = get_absolute_altitude_for_item(_mission_item);
|
const float mission_item_altitude_amsl = get_absolute_altitude_for_item(_mission_item);
|
||||||
|
|
||||||
dist = get_distance_to_point_global_wgs84(_mission_item.lat, _mission_item.lon, mission_item_altitude_amsl,
|
dist = get_distance_to_point_global_wgs84(_mission_item.lat, _mission_item.lon, mission_item_altitude_amsl,
|
||||||
_navigator->get_global_position()->lat,
|
_navigator_core.getLatRad(),
|
||||||
_navigator->get_global_position()->lon,
|
_navigator_core.getLonRad(),
|
||||||
_navigator->get_global_position()->alt,
|
_navigator_core.getAltitudeAMSLMeters(),
|
||||||
&dist_xy, &dist_z);
|
&dist_xy, &dist_z);
|
||||||
|
|
||||||
if ((_mission_item.nav_cmd == NAV_CMD_TAKEOFF || _mission_item.nav_cmd == NAV_CMD_VTOL_TAKEOFF)
|
if ((_mission_item.nav_cmd == NAV_CMD_TAKEOFF || _mission_item.nav_cmd == NAV_CMD_VTOL_TAKEOFF)
|
||||||
&& _navigator->get_vstatus()->vehicle_type == vehicle_status_s::VEHICLE_TYPE_ROTARY_WING) {
|
&& _navigator_core.isRotaryWing()) {
|
||||||
|
|
||||||
/* We want to avoid the edge case where the acceptance radius is bigger or equal than
|
/* We want to avoid the edge case where the acceptance radius is bigger or equal than
|
||||||
* the altitude of the takeoff waypoint above home. Otherwise, we do not really follow
|
* the altitude of the takeoff waypoint above home. Otherwise, we do not really follow
|
||||||
* take-off procedures like leaving the landing gear down. */
|
* take-off procedures like leaving the landing gear down. */
|
||||||
|
|
||||||
float takeoff_alt = _mission_item.altitude_is_relative ?
|
float takeoff_alt = _mission_item.altitude_is_relative ?
|
||||||
_mission_item.altitude :
|
_mission_item.altitude :
|
||||||
(_mission_item.altitude - _navigator->get_home_position()->alt);
|
(_mission_item.altitude - _navigator_core.getHomeAltAMSLMeter());
|
||||||
|
|
||||||
float altitude_acceptance_radius = _navigator->get_altitude_acceptance_radius();
|
float altitude_acceptance_radius = _navigator_core.getAltAcceptanceRadMeter();
|
||||||
|
|
||||||
/* It should be safe to just use half of the takoeff_alt as an acceptance radius. */
|
/* It should be safe to just use half of the takoeff_alt as an acceptance radius. */
|
||||||
if (takeoff_alt > 0 && takeoff_alt < altitude_acceptance_radius) {
|
if (takeoff_alt > 0 && takeoff_alt < altitude_acceptance_radius) {
|
||||||
@@ -169,26 +168,26 @@ MissionBlock::is_mission_item_reached()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* require only altitude for takeoff for multicopter */
|
/* require only altitude for takeoff for multicopter */
|
||||||
if (_navigator->get_global_position()->alt >
|
if (_navigator_core.getAltitudeAMSLMeters() >
|
||||||
mission_item_altitude_amsl - altitude_acceptance_radius) {
|
mission_item_altitude_amsl - altitude_acceptance_radius) {
|
||||||
_waypoint_position_reached = true;
|
_waypoint_position_reached = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (_mission_item.nav_cmd == NAV_CMD_TAKEOFF
|
} else if (_mission_item.nav_cmd == NAV_CMD_TAKEOFF
|
||||||
&& _navigator->get_vstatus()->vehicle_type == vehicle_status_s::VEHICLE_TYPE_ROVER) {
|
&& _navigator_core.isRover()) {
|
||||||
/* for takeoff mission items use the parameter for the takeoff acceptance radius */
|
/* for takeoff mission items use the parameter for the takeoff acceptance radius */
|
||||||
if (dist_xy >= 0.0f && dist_xy <= _navigator->get_acceptance_radius()) {
|
if (dist_xy >= 0.0f && dist_xy <= _navigator_core.getHorAcceptanceRadiusMeter()) {
|
||||||
_waypoint_position_reached = true;
|
_waypoint_position_reached = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (_mission_item.nav_cmd == NAV_CMD_TAKEOFF) {
|
} else if (_mission_item.nav_cmd == NAV_CMD_TAKEOFF) {
|
||||||
/* for takeoff mission items use the parameter for the takeoff acceptance radius */
|
/* for takeoff mission items use the parameter for the takeoff acceptance radius */
|
||||||
if (dist >= 0.0f && dist <= _navigator->get_acceptance_radius()
|
if (dist >= 0.0f && dist <= _navigator_core.getHorAcceptanceRadiusMeter()
|
||||||
&& dist_z <= _navigator->get_altitude_acceptance_radius()) {
|
&& dist_z <= _navigator_core.getAltAcceptanceRadMeter()) {
|
||||||
_waypoint_position_reached = true;
|
_waypoint_position_reached = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (_navigator->get_vstatus()->vehicle_type == vehicle_status_s::VEHICLE_TYPE_FIXED_WING &&
|
} else if (_navigator_core.isFixedWing() &&
|
||||||
(_mission_item.nav_cmd == NAV_CMD_LOITER_UNLIMITED ||
|
(_mission_item.nav_cmd == NAV_CMD_LOITER_UNLIMITED ||
|
||||||
_mission_item.nav_cmd == NAV_CMD_LOITER_TIME_LIMIT)) {
|
_mission_item.nav_cmd == NAV_CMD_LOITER_TIME_LIMIT)) {
|
||||||
|
|
||||||
@@ -200,8 +199,8 @@ MissionBlock::is_mission_item_reached()
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// check if within loiter radius around wp, if yes then set altitude sp to mission item
|
// check if within loiter radius around wp, if yes then set altitude sp to mission item
|
||||||
if (dist >= 0.0f && dist_xy <= (_navigator->get_acceptance_radius() + fabsf(_mission_item.loiter_radius))
|
if (dist >= 0.0f && dist_xy <= (_navigator_core.getHorAcceptanceRadiusMeter() + fabsf(_mission_item.loiter_radius))
|
||||||
&& dist_z <= _navigator->get_altitude_acceptance_radius()) {
|
&& dist_z <= _navigator_core.getAltAcceptanceRadMeter()) {
|
||||||
|
|
||||||
_waypoint_position_reached = true;
|
_waypoint_position_reached = true;
|
||||||
}
|
}
|
||||||
@@ -216,22 +215,22 @@ MissionBlock::is_mission_item_reached()
|
|||||||
dist_z = -1.0f;
|
dist_z = -1.0f;
|
||||||
|
|
||||||
dist = get_distance_to_point_global_wgs84(_mission_item.lat, _mission_item.lon, curr_sp->alt,
|
dist = get_distance_to_point_global_wgs84(_mission_item.lat, _mission_item.lon, curr_sp->alt,
|
||||||
_navigator->get_global_position()->lat,
|
_navigator_core.getLatRad(),
|
||||||
_navigator->get_global_position()->lon,
|
_navigator_core.getLonRad(),
|
||||||
_navigator->get_global_position()->alt,
|
_navigator_core.getAltitudeAMSLMeters(),
|
||||||
&dist_xy, &dist_z);
|
&dist_xy, &dist_z);
|
||||||
|
|
||||||
// check if within loiter radius around wp, if yes then set altitude sp to mission item
|
// check if within loiter radius around wp, if yes then set altitude sp to mission item
|
||||||
if (dist >= 0.0f && dist_xy <= (_navigator->get_acceptance_radius() + fabsf(_mission_item.loiter_radius))
|
if (dist >= 0.0f && dist_xy <= (_navigator_core.getHorAcceptanceRadiusMeter() + fabsf(_mission_item.loiter_radius))
|
||||||
&& dist_z <= _navigator->get_default_altitude_acceptance_radius()) {
|
&& dist_z <= _navigator_core.getDefaultAltAcceptanceRadiusMeter()) {
|
||||||
|
|
||||||
curr_sp->alt = mission_item_altitude_amsl;
|
curr_sp->alt = mission_item_altitude_amsl;
|
||||||
curr_sp->type = position_setpoint_s::SETPOINT_TYPE_LOITER;
|
curr_sp->type = position_setpoint_s::SETPOINT_TYPE_LOITER;
|
||||||
_navigator->set_position_setpoint_triplet_updated();
|
_navigator->set_position_setpoint_triplet_updated();
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (dist >= 0.f && dist_xy <= (_navigator->get_acceptance_radius() + fabsf(_mission_item.loiter_radius))
|
} else if (dist >= 0.f && dist_xy <= (_navigator_core.getAcceptanceRadiusMeter() + fabsf(_mission_item.loiter_radius))
|
||||||
&& dist_z <= _navigator->get_altitude_acceptance_radius()) {
|
&& dist_z <= _navigator_core.getAltAcceptanceRadiusMeter()) {
|
||||||
// loitering, check if new altitude is reached, while still also having check on position
|
// loitering, check if new altitude is reached, while still also having check on position
|
||||||
|
|
||||||
_waypoint_position_reached = true;
|
_waypoint_position_reached = true;
|
||||||
@@ -257,7 +256,7 @@ MissionBlock::is_mission_item_reached()
|
|||||||
|
|
||||||
// system position
|
// system position
|
||||||
matrix::Vector2f vehicle_pos;
|
matrix::Vector2f vehicle_pos;
|
||||||
map_projection_project(&ref_pos, _navigator->get_global_position()->lat, _navigator->get_global_position()->lon,
|
map_projection_project(&ref_pos, _navigator_core.getLatRad(), _navigator_core.getLonRad(),
|
||||||
&vehicle_pos(0), &vehicle_pos(1));
|
&vehicle_pos(0), &vehicle_pos(1));
|
||||||
const float dot_product = vehicle_pos.dot(gate_to_curr_sp.normalized());
|
const float dot_product = vehicle_pos.dot(gate_to_curr_sp.normalized());
|
||||||
|
|
||||||
@@ -279,14 +278,14 @@ MissionBlock::is_mission_item_reached()
|
|||||||
} else {
|
} else {
|
||||||
/*normal mission items */
|
/*normal mission items */
|
||||||
|
|
||||||
float mission_acceptance_radius = _navigator->get_acceptance_radius();
|
float mission_acceptance_radius = _navigator_core.getHorAcceptanceRadiusMeter();
|
||||||
|
|
||||||
/* for vtol back transition calculate acceptance radius based on time and ground speed */
|
/* for vtol back transition calculate acceptance radius based on time and ground speed */
|
||||||
if (_mission_item.vtol_back_transition
|
if (_mission_item.vtol_back_transition
|
||||||
&& _navigator->get_vstatus()->vehicle_type == vehicle_status_s::VEHICLE_TYPE_FIXED_WING) {
|
&& _navigator_core.isFixedWing()) {
|
||||||
|
|
||||||
float velocity = sqrtf(_navigator->get_local_position()->vx * _navigator->get_local_position()->vx +
|
float velocity = sqrtf(_navigator_core.getVelNorthMPS() * _navigator_core.getVelNorthMPS() +
|
||||||
_navigator->get_local_position()->vy * _navigator->get_local_position()->vy);
|
_navigator_core.getVelEastMPS() * _navigator_core.getVelEastMPS());
|
||||||
|
|
||||||
const float back_trans_dec = _navigator->get_vtol_back_trans_deceleration();
|
const float back_trans_dec = _navigator->get_vtol_back_trans_deceleration();
|
||||||
const float reverse_delay = _navigator->get_vtol_reverse_delay();
|
const float reverse_delay = _navigator->get_vtol_reverse_delay();
|
||||||
@@ -299,7 +298,7 @@ MissionBlock::is_mission_item_reached()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (dist_xy >= 0.0f && dist_xy <= mission_acceptance_radius
|
if (dist_xy >= 0.0f && dist_xy <= mission_acceptance_radius
|
||||||
&& dist_z <= _navigator->get_altitude_acceptance_radius()) {
|
&& dist_z <= _navigator_core.getAltAcceptanceRadiusMeter()) {
|
||||||
_waypoint_position_reached = true;
|
_waypoint_position_reached = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -310,7 +309,7 @@ MissionBlock::is_mission_item_reached()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// consider yaw reached for non-rotary wing vehicles (such as fixed-wing)
|
// consider yaw reached for non-rotary wing vehicles (such as fixed-wing)
|
||||||
if (_navigator->get_vstatus()->vehicle_type != vehicle_status_s::VEHICLE_TYPE_ROTARY_WING) {
|
if (!_navigator_core.isRotaryWing()) {
|
||||||
_waypoint_yaw_reached = true;
|
_waypoint_yaw_reached = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -319,22 +318,22 @@ MissionBlock::is_mission_item_reached()
|
|||||||
|
|
||||||
if (_waypoint_position_reached && !_waypoint_yaw_reached) {
|
if (_waypoint_position_reached && !_waypoint_yaw_reached) {
|
||||||
|
|
||||||
if (_navigator->get_vstatus()->vehicle_type == vehicle_status_s::VEHICLE_TYPE_ROTARY_WING
|
if (_navigator_core.isRotaryWing()
|
||||||
&& PX4_ISFINITE(_navigator->get_yaw_acceptance(_mission_item.yaw))) {
|
&& PX4_ISFINITE(_navigator->get_yaw_acceptance(_mission_item.yaw))) {
|
||||||
|
|
||||||
const float yaw_err = wrap_pi(_mission_item.yaw - _navigator->get_local_position()->heading);
|
const float yaw_err = wrap_pi(_mission_item.yaw - _navigator_core.getTrueHeadingRad());
|
||||||
|
|
||||||
/* accept yaw if reached or if timeout is set in which case we ignore not forced headings */
|
/* accept yaw if reached or if timeout is set in which case we ignore not forced headings */
|
||||||
if (fabsf(yaw_err) < _navigator->get_yaw_threshold()
|
if (fabsf(yaw_err) < _navigator_core.getWaypointHeadingAcceptanceRad()
|
||||||
|| (_navigator->get_yaw_timeout() >= FLT_EPSILON && !_mission_item.force_heading)) {
|
|| (_navigator_core.getWaypointHeadingTimeoutSeconds() >= FLT_EPSILON && !_mission_item.force_heading)) {
|
||||||
|
|
||||||
_waypoint_yaw_reached = true;
|
_waypoint_yaw_reached = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if heading needs to be reached, the timeout is enabled and we don't make it, abort mission */
|
/* if heading needs to be reached, the timeout is enabled and we don't make it, abort mission */
|
||||||
if (!_waypoint_yaw_reached && _mission_item.force_heading &&
|
if (!_waypoint_yaw_reached && _mission_item.force_heading &&
|
||||||
(_navigator->get_yaw_timeout() >= FLT_EPSILON) &&
|
(_navigator_core.getWaypointHeadingTimeoutSeconds() >= FLT_EPSILON) &&
|
||||||
(now - _time_wp_reached >= (hrt_abstime)_navigator->get_yaw_timeout() * 1e6f)) {
|
(now - _time_wp_reached >= (hrt_abstime)_navigator_core.getWaypointHeadingTimeoutSeconds() * 1e6f)) {
|
||||||
|
|
||||||
_navigator->set_mission_failure("unable to reach heading within timeout");
|
_navigator->set_mission_failure("unable to reach heading within timeout");
|
||||||
}
|
}
|
||||||
@@ -365,7 +364,7 @@ MissionBlock::is_mission_item_reached()
|
|||||||
|
|
||||||
/* enforce exit heading if in FW, the next wp is valid, the vehicle is currently loitering and either having force_heading set,
|
/* enforce exit heading if in FW, the next wp is valid, the vehicle is currently loitering and either having force_heading set,
|
||||||
or if loitering to achieve altitdue at a NAV_CMD_WAYPOINT */
|
or if loitering to achieve altitdue at a NAV_CMD_WAYPOINT */
|
||||||
const bool enforce_exit_heading = _navigator->get_vstatus()->vehicle_type != vehicle_status_s::VEHICLE_TYPE_ROTARY_WING
|
const bool enforce_exit_heading = !_navigator_core.isRotaryWing()
|
||||||
&&
|
&&
|
||||||
next_sp.valid &&
|
next_sp.valid &&
|
||||||
curr_sp_new->type == position_setpoint_s::SETPOINT_TYPE_LOITER &&
|
curr_sp_new->type == position_setpoint_s::SETPOINT_TYPE_LOITER &&
|
||||||
@@ -379,12 +378,12 @@ MissionBlock::is_mission_item_reached()
|
|||||||
|
|
||||||
float yaw_err = 0.0f;
|
float yaw_err = 0.0f;
|
||||||
|
|
||||||
if (dist_current_next > 1.2f * _navigator->get_loiter_radius()) {
|
if (dist_current_next > 1.2f * _navigator_core.getLoiterRadiusMeter()) {
|
||||||
// set required yaw from bearing to the next mission item
|
// set required yaw from bearing to the next mission item
|
||||||
_mission_item.yaw = get_bearing_to_next_waypoint(_navigator->get_global_position()->lat,
|
_mission_item.yaw = get_bearing_to_next_waypoint(_navigator_core.getLatRad(),
|
||||||
_navigator->get_global_position()->lon,
|
_navigator_core.getLonRad(),
|
||||||
next_sp.lat, next_sp.lon);
|
next_sp.lat, next_sp.lon);
|
||||||
const float cog = atan2f(_navigator->get_local_position()->vy, _navigator->get_local_position()->vx);
|
const float cog = atan2f(_navigator_core.getVelEastMPS(), _navigator_core.getVelNorthMPS());
|
||||||
yaw_err = wrap_pi(_mission_item.yaw - cog);
|
yaw_err = wrap_pi(_mission_item.yaw - cog);
|
||||||
|
|
||||||
|
|
||||||
@@ -392,7 +391,7 @@ MissionBlock::is_mission_item_reached()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (fabsf(yaw_err) < _navigator->get_yaw_threshold()) {
|
if (fabsf(yaw_err) < _navigator_core.getWaypointHeadingAcceptanceRad()) {
|
||||||
exit_heading_reached = true;
|
exit_heading_reached = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -489,7 +488,7 @@ MissionBlock::issue_command(const mission_item_s &item)
|
|||||||
if (item.nav_cmd == NAV_CMD_DO_SET_ROI_LOCATION && item.altitude_is_relative) {
|
if (item.nav_cmd == NAV_CMD_DO_SET_ROI_LOCATION && item.altitude_is_relative) {
|
||||||
vcmd.param5 = item.lat;
|
vcmd.param5 = item.lat;
|
||||||
vcmd.param6 = item.lon;
|
vcmd.param6 = item.lon;
|
||||||
vcmd.param7 = item.altitude + _navigator->get_home_position()->alt;
|
vcmd.param7 = item.altitude + _navigator_core.getHomeAltAMSLMeter();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
vcmd.param5 = (double)item.params[4];
|
vcmd.param5 = (double)item.params[4];
|
||||||
@@ -505,7 +504,7 @@ float
|
|||||||
MissionBlock::get_time_inside(const mission_item_s &item) const
|
MissionBlock::get_time_inside(const mission_item_s &item) const
|
||||||
{
|
{
|
||||||
if ((item.nav_cmd == NAV_CMD_WAYPOINT
|
if ((item.nav_cmd == NAV_CMD_WAYPOINT
|
||||||
&& _navigator->get_vstatus()->vehicle_type == vehicle_status_s::VEHICLE_TYPE_ROTARY_WING) ||
|
&& _navigator_core.isRotaryWing()) ||
|
||||||
item.nav_cmd == NAV_CMD_LOITER_TIME_LIMIT ||
|
item.nav_cmd == NAV_CMD_LOITER_TIME_LIMIT ||
|
||||||
item.nav_cmd == NAV_CMD_DELAY) {
|
item.nav_cmd == NAV_CMD_DELAY) {
|
||||||
|
|
||||||
@@ -553,10 +552,11 @@ MissionBlock::mission_item_to_position_setpoint(const mission_item_s &item, posi
|
|||||||
sp->lat = item.lat;
|
sp->lat = item.lat;
|
||||||
sp->lon = item.lon;
|
sp->lon = item.lon;
|
||||||
sp->alt = get_absolute_altitude_for_item(item);
|
sp->alt = get_absolute_altitude_for_item(item);
|
||||||
|
sp->alt_valid = true;
|
||||||
sp->yaw = item.yaw;
|
sp->yaw = item.yaw;
|
||||||
sp->yaw_valid = PX4_ISFINITE(item.yaw);
|
sp->yaw_valid = PX4_ISFINITE(item.yaw);
|
||||||
sp->loiter_radius = (fabsf(item.loiter_radius) > NAV_EPSILON_POSITION) ? fabsf(item.loiter_radius) :
|
sp->loiter_radius = (fabsf(item.loiter_radius) > NAV_EPSILON_POSITION) ? fabsf(item.loiter_radius) :
|
||||||
_navigator->get_loiter_radius();
|
_navigator_core.getLoiterRadiusMeter();
|
||||||
sp->loiter_direction = (item.loiter_radius > 0) ? 1 : -1;
|
sp->loiter_direction = (item.loiter_radius > 0) ? 1 : -1;
|
||||||
|
|
||||||
if (item.acceptance_radius > 0.0f && PX4_ISFINITE(item.acceptance_radius)) {
|
if (item.acceptance_radius > 0.0f && PX4_ISFINITE(item.acceptance_radius)) {
|
||||||
@@ -564,7 +564,7 @@ MissionBlock::mission_item_to_position_setpoint(const mission_item_s &item, posi
|
|||||||
sp->acceptance_radius = item.acceptance_radius;
|
sp->acceptance_radius = item.acceptance_radius;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
sp->acceptance_radius = _navigator->get_default_acceptance_radius();
|
sp->acceptance_radius = _navigator->getCore().getDefaultHorAcceptanceRadiusMeter();
|
||||||
}
|
}
|
||||||
|
|
||||||
sp->cruising_speed = _navigator->get_cruising_speed();
|
sp->cruising_speed = _navigator->get_cruising_speed();
|
||||||
@@ -578,9 +578,8 @@ MissionBlock::mission_item_to_position_setpoint(const mission_item_s &item, posi
|
|||||||
case NAV_CMD_TAKEOFF:
|
case NAV_CMD_TAKEOFF:
|
||||||
|
|
||||||
// if already flying (armed and !landed) treat TAKEOFF like regular POSITION
|
// if already flying (armed and !landed) treat TAKEOFF like regular POSITION
|
||||||
if ((_navigator->get_vstatus()->arming_state == vehicle_status_s::ARMING_STATE_ARMED)
|
if ((_navigator_core.getArmingState() == vehicle_status_s::ARMING_STATE_ARMED)
|
||||||
&& !_navigator->get_land_detected()->landed && !_navigator->get_land_detected()->maybe_landed) {
|
&& !_navigator_core.getLanded() && !_navigator_core.getMaybeLanded()) {
|
||||||
|
|
||||||
sp->type = position_setpoint_s::SETPOINT_TYPE_POSITION;
|
sp->type = position_setpoint_s::SETPOINT_TYPE_POSITION;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@@ -601,12 +600,12 @@ MissionBlock::mission_item_to_position_setpoint(const mission_item_s &item, posi
|
|||||||
case NAV_CMD_LOITER_TO_ALT:
|
case NAV_CMD_LOITER_TO_ALT:
|
||||||
|
|
||||||
// initially use current altitude, and switch to mission item altitude once in loiter position
|
// initially use current altitude, and switch to mission item altitude once in loiter position
|
||||||
if (_navigator->get_loiter_min_alt() > 0.f) { // ignore _param_loiter_min_alt if smaller than 0
|
if (_navigator_core.getRelativeLoiterMinAltitudeMeter() > 0.f) { // ignore _param_loiter_min_alt if smaller than 0
|
||||||
sp->alt = math::max(_navigator->get_global_position()->alt,
|
sp->alt = math::max(_navigator_core.getAltitudeAMSLMeters(),
|
||||||
_navigator->get_home_position()->alt + _navigator->get_loiter_min_alt());
|
_navigator_core.getHomeAltAMSLMeter() + _navigator_core.getRelativeLoiterMinAltitudeMeter());
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
sp->alt = _navigator->get_global_position()->alt;
|
sp->alt = _navigator_core.getAltitudeAMSLMeters();
|
||||||
}
|
}
|
||||||
|
|
||||||
// FALLTHROUGH
|
// FALLTHROUGH
|
||||||
@@ -630,7 +629,7 @@ MissionBlock::mission_item_to_position_setpoint(const mission_item_s &item, posi
|
|||||||
void
|
void
|
||||||
MissionBlock::set_loiter_item(struct mission_item_s *item, float min_clearance)
|
MissionBlock::set_loiter_item(struct mission_item_s *item, float min_clearance)
|
||||||
{
|
{
|
||||||
if (_navigator->get_land_detected()->landed) {
|
if (_navigator_core.getLanded()) {
|
||||||
/* landed, don't takeoff, but switch to IDLE mode */
|
/* landed, don't takeoff, but switch to IDLE mode */
|
||||||
item->nav_cmd = NAV_CMD_IDLE;
|
item->nav_cmd = NAV_CMD_IDLE;
|
||||||
|
|
||||||
@@ -647,19 +646,19 @@ MissionBlock::set_loiter_item(struct mission_item_s *item, float min_clearance)
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
/* use current position and use return altitude as clearance */
|
/* use current position and use return altitude as clearance */
|
||||||
item->lat = _navigator->get_global_position()->lat;
|
item->lat = _navigator_core.getLatRad();
|
||||||
item->lon = _navigator->get_global_position()->lon;
|
item->lon = _navigator_core.getLonRad();
|
||||||
item->altitude = _navigator->get_global_position()->alt;
|
item->altitude = _navigator_core.getAltitudeAMSLMeters();
|
||||||
|
|
||||||
if (min_clearance > 0.0f && item->altitude < _navigator->get_home_position()->alt + min_clearance) {
|
if (min_clearance > 0.0f && item->altitude < _navigator_core.getHomeAltAMSLMeter() + min_clearance) {
|
||||||
item->altitude = _navigator->get_home_position()->alt + min_clearance;
|
item->altitude = _navigator_core.getHomeAltAMSLMeter() + min_clearance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
item->altitude_is_relative = false;
|
item->altitude_is_relative = false;
|
||||||
item->yaw = NAN;
|
item->yaw = NAN;
|
||||||
item->loiter_radius = _navigator->get_loiter_radius();
|
item->loiter_radius = _navigator_core.getLoiterRadiusMeter();
|
||||||
item->acceptance_radius = _navigator->get_acceptance_radius();
|
item->acceptance_radius = _navigator_core.getHorAcceptanceRadiusMeter();
|
||||||
item->time_inside = 0.0f;
|
item->time_inside = 0.0f;
|
||||||
item->autocontinue = false;
|
item->autocontinue = false;
|
||||||
item->origin = ORIGIN_ONBOARD;
|
item->origin = ORIGIN_ONBOARD;
|
||||||
@@ -672,14 +671,14 @@ MissionBlock::set_takeoff_item(struct mission_item_s *item, float abs_altitude)
|
|||||||
item->nav_cmd = NAV_CMD_TAKEOFF;
|
item->nav_cmd = NAV_CMD_TAKEOFF;
|
||||||
|
|
||||||
/* use current position */
|
/* use current position */
|
||||||
item->lat = _navigator->get_global_position()->lat;
|
item->lat = _navigator_core.getLatRad();
|
||||||
item->lon = _navigator->get_global_position()->lon;
|
item->lon = _navigator_core.getLonRad();
|
||||||
item->yaw = _navigator->get_local_position()->heading;
|
item->yaw = _navigator_core.getTrueHeadingRad();
|
||||||
|
|
||||||
item->altitude = abs_altitude;
|
item->altitude = abs_altitude;
|
||||||
item->altitude_is_relative = false;
|
item->altitude_is_relative = false;
|
||||||
|
|
||||||
item->loiter_radius = _navigator->get_loiter_radius();
|
item->loiter_radius = _navigator_core.getLoiterRadiusMeter();
|
||||||
item->autocontinue = false;
|
item->autocontinue = false;
|
||||||
item->origin = ORIGIN_ONBOARD;
|
item->origin = ORIGIN_ONBOARD;
|
||||||
}
|
}
|
||||||
@@ -688,7 +687,7 @@ void
|
|||||||
MissionBlock::set_land_item(struct mission_item_s *item, bool at_current_location)
|
MissionBlock::set_land_item(struct mission_item_s *item, bool at_current_location)
|
||||||
{
|
{
|
||||||
/* VTOL transition to RW before landing */
|
/* VTOL transition to RW before landing */
|
||||||
if (_navigator->force_vtol()) {
|
if (_navigator_core.forceVTOL()) {
|
||||||
|
|
||||||
vehicle_command_s vcmd = {};
|
vehicle_command_s vcmd = {};
|
||||||
vcmd.command = NAV_CMD_DO_VTOL_TRANSITION;
|
vcmd.command = NAV_CMD_DO_VTOL_TRANSITION;
|
||||||
@@ -703,19 +702,19 @@ MissionBlock::set_land_item(struct mission_item_s *item, bool at_current_locatio
|
|||||||
if (at_current_location) {
|
if (at_current_location) {
|
||||||
item->lat = (double)NAN; //descend at current position
|
item->lat = (double)NAN; //descend at current position
|
||||||
item->lon = (double)NAN; //descend at current position
|
item->lon = (double)NAN; //descend at current position
|
||||||
item->yaw = _navigator->get_local_position()->heading;
|
item->yaw = _navigator_core.getTrueHeadingRad();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
/* use home position */
|
/* use home position */
|
||||||
item->lat = _navigator->get_home_position()->lat;
|
item->lat = _navigator_core.getHomeLatRad();
|
||||||
item->lon = _navigator->get_home_position()->lon;
|
item->lon = _navigator_core.getHomeLonRad();
|
||||||
item->yaw = _navigator->get_home_position()->yaw;
|
item->yaw = _navigator_core.getHomeTrueHeadingRad();
|
||||||
}
|
}
|
||||||
|
|
||||||
item->altitude = 0;
|
item->altitude = 0;
|
||||||
item->altitude_is_relative = false;
|
item->altitude_is_relative = false;
|
||||||
item->loiter_radius = _navigator->get_loiter_radius();
|
item->loiter_radius = _navigator_core.getLoiterRadiusMeter();
|
||||||
item->acceptance_radius = _navigator->get_acceptance_radius();
|
item->acceptance_radius = _navigator_core.getHorAcceptanceRadiusMeter();
|
||||||
item->time_inside = 0.0f;
|
item->time_inside = 0.0f;
|
||||||
item->autocontinue = true;
|
item->autocontinue = true;
|
||||||
item->origin = ORIGIN_ONBOARD;
|
item->origin = ORIGIN_ONBOARD;
|
||||||
@@ -725,13 +724,13 @@ void
|
|||||||
MissionBlock::set_idle_item(struct mission_item_s *item)
|
MissionBlock::set_idle_item(struct mission_item_s *item)
|
||||||
{
|
{
|
||||||
item->nav_cmd = NAV_CMD_IDLE;
|
item->nav_cmd = NAV_CMD_IDLE;
|
||||||
item->lat = _navigator->get_home_position()->lat;
|
item->lat = _navigator_core.getHomeLatRad();
|
||||||
item->lon = _navigator->get_home_position()->lon;
|
item->lon = _navigator_core.getHomeLonRad();
|
||||||
item->altitude_is_relative = false;
|
item->altitude_is_relative = false;
|
||||||
item->altitude = _navigator->get_home_position()->alt;
|
item->altitude = _navigator_core.getHomeAltAMSLMeter();
|
||||||
item->yaw = NAN;
|
item->yaw = NAN;
|
||||||
item->loiter_radius = _navigator->get_loiter_radius();
|
item->loiter_radius = _navigator_core.getLoiterRadiusMeter();
|
||||||
item->acceptance_radius = _navigator->get_acceptance_radius();
|
item->acceptance_radius = _navigator_core.getHorAcceptanceRadiusMeter();
|
||||||
item->time_inside = 0.0f;
|
item->time_inside = 0.0f;
|
||||||
item->autocontinue = true;
|
item->autocontinue = true;
|
||||||
item->origin = ORIGIN_ONBOARD;
|
item->origin = ORIGIN_ONBOARD;
|
||||||
@@ -742,7 +741,7 @@ MissionBlock::set_vtol_transition_item(struct mission_item_s *item, const uint8_
|
|||||||
{
|
{
|
||||||
item->nav_cmd = NAV_CMD_DO_VTOL_TRANSITION;
|
item->nav_cmd = NAV_CMD_DO_VTOL_TRANSITION;
|
||||||
item->params[0] = (float) new_mode;
|
item->params[0] = (float) new_mode;
|
||||||
item->yaw = _navigator->get_local_position()->heading;
|
item->yaw = _navigator_core.getTrueHeadingRad();
|
||||||
item->autocontinue = true;
|
item->autocontinue = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -754,18 +753,18 @@ MissionBlock::mission_apply_limitation(mission_item_s &item)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* do nothing if altitude max is negative */
|
/* do nothing if altitude max is negative */
|
||||||
if (_navigator->get_land_detected()->alt_max > 0.0f) {
|
if (_navigator_core.getLandDetectedAltMaxMeter() > 0.0f) {
|
||||||
|
|
||||||
/* absolute altitude */
|
/* absolute altitude */
|
||||||
float altitude_abs = item.altitude_is_relative
|
float altitude_abs = item.altitude_is_relative
|
||||||
? item.altitude + _navigator->get_home_position()->alt
|
? item.altitude + _navigator_core.getHomeAltAMSLMeter()
|
||||||
: item.altitude;
|
: item.altitude;
|
||||||
|
|
||||||
/* limit altitude to maximum allowed altitude */
|
/* limit altitude to maximum allowed altitude */
|
||||||
if ((_navigator->get_land_detected()->alt_max + _navigator->get_home_position()->alt) < altitude_abs) {
|
if ((_navigator_core.getLandDetectedAltMaxMeter() + _navigator_core.getHomeAltAMSLMeter()) < altitude_abs) {
|
||||||
item.altitude = item.altitude_is_relative ?
|
item.altitude = item.altitude_is_relative ?
|
||||||
_navigator->get_land_detected()->alt_max :
|
_navigator_core.getLandDetectedAltMaxMeter() :
|
||||||
_navigator->get_land_detected()->alt_max + _navigator->get_home_position()->alt;
|
_navigator_core.getLandDetectedAltMaxMeter() + _navigator_core.getHomeAltAMSLMeter();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -779,7 +778,7 @@ float
|
|||||||
MissionBlock::get_absolute_altitude_for_item(const mission_item_s &mission_item) const
|
MissionBlock::get_absolute_altitude_for_item(const mission_item_s &mission_item) const
|
||||||
{
|
{
|
||||||
if (mission_item.altitude_is_relative) {
|
if (mission_item.altitude_is_relative) {
|
||||||
return mission_item.altitude + _navigator->get_home_position()->alt;
|
return mission_item.altitude + _navigator_core.getHomeAltAMSLMeter();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
return mission_item.altitude;
|
return mission_item.altitude;
|
||||||
|
|||||||
@@ -42,6 +42,7 @@
|
|||||||
|
|
||||||
#include "navigator_mode.h"
|
#include "navigator_mode.h"
|
||||||
#include "navigation.h"
|
#include "navigation.h"
|
||||||
|
#include "NavigatorCore.h"
|
||||||
|
|
||||||
#include <drivers/drv_hrt.h>
|
#include <drivers/drv_hrt.h>
|
||||||
#include <systemlib/mavlink_log.h>
|
#include <systemlib/mavlink_log.h>
|
||||||
@@ -61,7 +62,7 @@ public:
|
|||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*/
|
*/
|
||||||
MissionBlock(Navigator *navigator);
|
MissionBlock(Navigator *navigator, NavigatorCore &navigator_core);
|
||||||
virtual ~MissionBlock() = default;
|
virtual ~MissionBlock() = default;
|
||||||
|
|
||||||
MissionBlock(const MissionBlock &) = delete;
|
MissionBlock(const MissionBlock &) = delete;
|
||||||
@@ -151,5 +152,7 @@ protected:
|
|||||||
|
|
||||||
hrt_abstime _time_wp_reached{0};
|
hrt_abstime _time_wp_reached{0};
|
||||||
|
|
||||||
|
NavigatorCore &_navigator_core;
|
||||||
|
|
||||||
uORB::Publication<actuator_controls_s> _actuator_pub{ORB_ID(actuator_controls_2)};
|
uORB::Publication<actuator_controls_s> _actuator_pub{ORB_ID(actuator_controls_2)};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -67,8 +67,8 @@ MissionFeasibilityChecker::checkMissionFeasible(const mission_s &mission,
|
|||||||
bool warned = false;
|
bool warned = false;
|
||||||
|
|
||||||
// first check if we have a valid position
|
// first check if we have a valid position
|
||||||
const bool home_valid = _navigator->home_position_valid();
|
const bool home_valid = _navigator->getCore().isHomeValid();
|
||||||
const bool home_alt_valid = _navigator->home_alt_valid();
|
const bool home_alt_valid = _navigator->getCore().isHomeAltValid();
|
||||||
|
|
||||||
if (!home_alt_valid) {
|
if (!home_alt_valid) {
|
||||||
failed = true;
|
failed = true;
|
||||||
@@ -79,7 +79,7 @@ MissionFeasibilityChecker::checkMissionFeasible(const mission_s &mission,
|
|||||||
failed = failed || !checkDistanceToFirstWaypoint(mission, max_distance_to_1st_waypoint);
|
failed = failed || !checkDistanceToFirstWaypoint(mission, max_distance_to_1st_waypoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
const float home_alt = _navigator->get_home_position()->alt;
|
const float home_alt = _navigator->getCore().getHomeAltAMSLMeter();
|
||||||
|
|
||||||
// check if all mission item commands are supported
|
// check if all mission item commands are supported
|
||||||
failed = failed || !checkMissionItemValidity(mission);
|
failed = failed || !checkMissionItemValidity(mission);
|
||||||
@@ -87,10 +87,10 @@ MissionFeasibilityChecker::checkMissionFeasible(const mission_s &mission,
|
|||||||
failed = failed || !checkGeofence(mission, home_alt, home_valid);
|
failed = failed || !checkGeofence(mission, home_alt, home_valid);
|
||||||
failed = failed || !checkHomePositionAltitude(mission, home_alt, home_alt_valid, warned);
|
failed = failed || !checkHomePositionAltitude(mission, home_alt, home_alt_valid, warned);
|
||||||
|
|
||||||
if (_navigator->get_vstatus()->is_vtol) {
|
if (_navigator->getCore().isVTOL()) {
|
||||||
failed = failed || !checkVTOL(mission, home_alt, false);
|
failed = failed || !checkVTOL(mission, home_alt, false);
|
||||||
|
|
||||||
} else if (_navigator->get_vstatus()->vehicle_type == vehicle_status_s::VEHICLE_TYPE_ROTARY_WING) {
|
} else if (_navigator->getCore().isRotaryWing()) {
|
||||||
failed = failed || !checkRotarywing(mission, home_alt);
|
failed = failed || !checkRotarywing(mission, home_alt);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@@ -300,7 +300,7 @@ MissionFeasibilityChecker::checkMissionItemValidity(const mission_s &mission)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// check if the mission starts with a land command while the vehicle is landed
|
// check if the mission starts with a land command while the vehicle is landed
|
||||||
if ((i == 0) && missionitem.nav_cmd == NAV_CMD_LAND && _navigator->get_land_detected()->landed) {
|
if ((i == 0) && missionitem.nav_cmd == NAV_CMD_LAND && _navigator->getCore().getLanded()) {
|
||||||
|
|
||||||
mavlink_log_critical(_navigator->get_mavlink_log_pub(), "Mission rejected: starts with landing");
|
mavlink_log_critical(_navigator->get_mavlink_log_pub(), "Mission rejected: starts with landing");
|
||||||
return false;
|
return false;
|
||||||
@@ -336,7 +336,7 @@ MissionFeasibilityChecker::checkTakeoff(const mission_s &mission, float home_alt
|
|||||||
: missionitem.altitude - home_alt;
|
: missionitem.altitude - home_alt;
|
||||||
|
|
||||||
// check if we should use default acceptance radius
|
// check if we should use default acceptance radius
|
||||||
float acceptance_radius = _navigator->get_default_acceptance_radius();
|
float acceptance_radius = _navigator->getCore().getDefaultHorAcceptanceRadiusMeter();
|
||||||
|
|
||||||
if (missionitem.acceptance_radius > NAV_EPSILON_POSITION) {
|
if (missionitem.acceptance_radius > NAV_EPSILON_POSITION) {
|
||||||
acceptance_radius = missionitem.acceptance_radius;
|
acceptance_radius = missionitem.acceptance_radius;
|
||||||
@@ -408,7 +408,7 @@ MissionFeasibilityChecker::checkTakeoff(const mission_s &mission, float home_alt
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_navigator->get_takeoff_required() && _navigator->get_land_detected()->landed) {
|
if (_navigator->getCore().isTakeoffRequired() && _navigator->getCore().getLanded()) {
|
||||||
// check for a takeoff waypoint, after the above conditions have been met
|
// check for a takeoff waypoint, after the above conditions have been met
|
||||||
// MIS_TAKEOFF_REQ param has to be set and the vehicle has to be landed - one can load a mission
|
// MIS_TAKEOFF_REQ param has to be set and the vehicle has to be landed - one can load a mission
|
||||||
// while the vehicle is flying and it does not require a takeoff waypoint
|
// while the vehicle is flying and it does not require a takeoff waypoint
|
||||||
@@ -653,7 +653,7 @@ MissionFeasibilityChecker::checkDistanceToFirstWaypoint(const mission_s &mission
|
|||||||
/* check distance from current position to item */
|
/* check distance from current position to item */
|
||||||
float dist_to_1wp = get_distance_to_next_waypoint(
|
float dist_to_1wp = get_distance_to_next_waypoint(
|
||||||
mission_item.lat, mission_item.lon,
|
mission_item.lat, mission_item.lon,
|
||||||
_navigator->get_home_position()->lat, _navigator->get_home_position()->lon);
|
_navigator->getCore().getHomeLatRad(), _navigator->getCore().getHomeLonRad());
|
||||||
|
|
||||||
if (dist_to_1wp < max_distance) {
|
if (dist_to_1wp < max_distance) {
|
||||||
|
|
||||||
|
|||||||
@@ -122,6 +122,8 @@ public:
|
|||||||
|
|
||||||
void publish_vehicle_cmd(vehicle_command_s *vcmd);
|
void publish_vehicle_cmd(vehicle_command_s *vcmd);
|
||||||
|
|
||||||
|
void params_update();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate an artificial traffic indication
|
* Generate an artificial traffic indication
|
||||||
*
|
*
|
||||||
@@ -165,39 +167,39 @@ public:
|
|||||||
const vehicle_roi_s &get_vroi() { return _vroi; }
|
const vehicle_roi_s &get_vroi() { return _vroi; }
|
||||||
void reset_vroi() { _vroi = {}; }
|
void reset_vroi() { _vroi = {}; }
|
||||||
|
|
||||||
bool home_alt_valid() { return (_home_pos.timestamp > 0 && _home_pos.valid_alt); }
|
//bool home_alt_valid() { return (_home_pos.timestamp > 0 && _home_pos.valid_alt); }
|
||||||
bool home_position_valid() { return (_home_pos.timestamp > 0 && _home_pos.valid_alt && _home_pos.valid_hpos && _home_pos.valid_lpos); }
|
//bool _navigator_core.isHomeValid() { return (_home_pos.timestamp > 0 && _home_pos.valid_alt && _home_pos.valid_hpos && _home_pos.valid_lpos); }
|
||||||
|
|
||||||
Geofence &get_geofence() { return _geofence; }
|
Geofence &get_geofence() { return _geofence; }
|
||||||
|
|
||||||
bool get_can_loiter_at_sp() { return _can_loiter_at_sp; }
|
bool get_can_loiter_at_sp() { return _can_loiter_at_sp; }
|
||||||
float get_loiter_radius() { return _param_nav_loiter_rad.get(); }
|
//float _navigator_core.getLoiterRadiusMeter() { return _param_nav_loiter_rad.get(); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the default acceptance radius defined by the parameter
|
* Returns the default acceptance radius defined by the parameter
|
||||||
*/
|
*/
|
||||||
float get_default_acceptance_radius();
|
//float get_default_acceptance_radius();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the acceptance radius
|
* Get the acceptance radius
|
||||||
*
|
*
|
||||||
* @return the distance at which the next waypoint should be used
|
* @return the distance at which the next waypoint should be used
|
||||||
*/
|
*/
|
||||||
float get_acceptance_radius();
|
//float get_acceptance_radius();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the default altitude acceptance radius (i.e. from parameters)
|
* Get the default altitude acceptance radius (i.e. from parameters)
|
||||||
*
|
*
|
||||||
* @return the distance from the target altitude before considering the waypoint reached
|
* @return the distance from the target altitude before considering the waypoint reached
|
||||||
*/
|
*/
|
||||||
float get_default_altitude_acceptance_radius();
|
//float get_default_altitude_acceptance_radius();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the altitude acceptance radius
|
* Get the altitude acceptance radius
|
||||||
*
|
*
|
||||||
* @return the distance from the target altitude before considering the waypoint reached
|
* @return the distance from the target altitude before considering the waypoint reached
|
||||||
*/
|
*/
|
||||||
float get_altitude_acceptance_radius();
|
//float get_altitude_acceptance_radius();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the cruising speed
|
* Get the cruising speed
|
||||||
@@ -290,43 +292,21 @@ public:
|
|||||||
|
|
||||||
void geofence_breach_check(bool &have_geofence_position_data);
|
void geofence_breach_check(bool &have_geofence_position_data);
|
||||||
|
|
||||||
// Param access
|
|
||||||
float get_loiter_min_alt() const { return _param_mis_ltrmin_alt.get(); }
|
|
||||||
float get_takeoff_min_alt() const { return _param_mis_takeoff_alt.get(); }
|
|
||||||
bool get_takeoff_required() const { return _param_mis_takeoff_req.get(); }
|
|
||||||
float get_yaw_timeout() const { return _param_mis_yaw_tmt.get(); }
|
|
||||||
float get_yaw_threshold() const { return math::radians(_param_mis_yaw_err.get()); }
|
|
||||||
|
|
||||||
float get_vtol_back_trans_deceleration() const { return _param_back_trans_dec_mss; }
|
float get_vtol_back_trans_deceleration() const { return _param_back_trans_dec_mss; }
|
||||||
float get_vtol_reverse_delay() const { return _param_reverse_delay; }
|
float get_vtol_reverse_delay() const { return _param_reverse_delay; }
|
||||||
|
|
||||||
bool force_vtol();
|
//bool force_vtol();
|
||||||
|
|
||||||
void acquire_gimbal_control();
|
void acquire_gimbal_control();
|
||||||
void release_gimbal_control();
|
void release_gimbal_control();
|
||||||
|
|
||||||
|
NavigatorCore &getCore() { return _navigator_core; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DEFINE_PARAMETERS(
|
DEFINE_PARAMETERS(
|
||||||
(ParamFloat<px4::params::NAV_LOITER_RAD>) _param_nav_loiter_rad, /**< loiter radius for fixedwing */
|
|
||||||
(ParamFloat<px4::params::NAV_ACC_RAD>) _param_nav_acc_rad, /**< acceptance for takeoff */
|
|
||||||
(ParamFloat<px4::params::NAV_FW_ALT_RAD>)
|
|
||||||
_param_nav_fw_alt_rad, /**< acceptance radius for fixedwing altitude */
|
|
||||||
(ParamFloat<px4::params::NAV_FW_ALTL_RAD>)
|
|
||||||
_param_nav_fw_altl_rad, /**< acceptance radius for fixedwing altitude before landing*/
|
|
||||||
(ParamFloat<px4::params::NAV_MC_ALT_RAD>)
|
|
||||||
_param_nav_mc_alt_rad, /**< acceptance radius for multicopter altitude */
|
|
||||||
(ParamInt<px4::params::NAV_FORCE_VT>) _param_nav_force_vt, /**< acceptance radius for multicopter altitude */
|
|
||||||
(ParamInt<px4::params::NAV_TRAFF_AVOID>) _param_nav_traff_avoid, /**< avoiding other aircraft is enabled */
|
(ParamInt<px4::params::NAV_TRAFF_AVOID>) _param_nav_traff_avoid, /**< avoiding other aircraft is enabled */
|
||||||
(ParamFloat<px4::params::NAV_TRAFF_A_RADU>) _param_nav_traff_a_radu, /**< avoidance Distance Unmanned*/
|
(ParamFloat<px4::params::NAV_TRAFF_A_RADU>) _param_nav_traff_a_radu, /**< avoidance Distance Unmanned*/
|
||||||
(ParamFloat<px4::params::NAV_TRAFF_A_RADM>) _param_nav_traff_a_radm, /**< avoidance Distance Manned*/
|
(ParamFloat<px4::params::NAV_TRAFF_A_RADM>) _param_nav_traff_a_radm /**< avoidance Distance Manned*/
|
||||||
|
|
||||||
// non-navigator parameters
|
|
||||||
// Mission (MIS_*)
|
|
||||||
(ParamFloat<px4::params::MIS_LTRMIN_ALT>) _param_mis_ltrmin_alt,
|
|
||||||
(ParamFloat<px4::params::MIS_TAKEOFF_ALT>) _param_mis_takeoff_alt,
|
|
||||||
(ParamBool<px4::params::MIS_TAKEOFF_REQ>) _param_mis_takeoff_req,
|
|
||||||
(ParamFloat<px4::params::MIS_YAW_TMT>) _param_mis_yaw_tmt,
|
|
||||||
(ParamFloat<px4::params::MIS_YAW_ERR>) _param_mis_yaw_err
|
|
||||||
)
|
)
|
||||||
|
|
||||||
int _local_pos_sub{-1};
|
int _local_pos_sub{-1};
|
||||||
@@ -385,6 +365,8 @@ private:
|
|||||||
bool _pos_sp_triplet_published_invalid_once{false}; /**< flags if position SP triplet has been published once to UORB */
|
bool _pos_sp_triplet_published_invalid_once{false}; /**< flags if position SP triplet has been published once to UORB */
|
||||||
bool _mission_result_updated{false}; /**< flags if mission result has seen an update */
|
bool _mission_result_updated{false}; /**< flags if mission result has seen an update */
|
||||||
|
|
||||||
|
NavigatorCore _navigator_core;
|
||||||
|
|
||||||
NavigatorMode *_navigation_mode{nullptr}; /**< abstract pointer to current navigation mode class */
|
NavigatorMode *_navigation_mode{nullptr}; /**< abstract pointer to current navigation mode class */
|
||||||
Mission _mission; /**< class that handles the missions */
|
Mission _mission; /**< class that handles the missions */
|
||||||
Loiter _loiter; /**< class that handles loiter */
|
Loiter _loiter; /**< class that handles loiter */
|
||||||
@@ -411,7 +393,7 @@ private:
|
|||||||
// if mission mode is inactive, this flag will be cleared after 2 seconds
|
// if mission mode is inactive, this flag will be cleared after 2 seconds
|
||||||
|
|
||||||
// update subscriptions
|
// update subscriptions
|
||||||
void params_update();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Publish a new position setpoint triplet for position controllers
|
* Publish a new position setpoint triplet for position controllers
|
||||||
|
|||||||
@@ -76,15 +76,16 @@ Navigator::Navigator() :
|
|||||||
_loop_perf(perf_alloc(PC_ELAPSED, "navigator")),
|
_loop_perf(perf_alloc(PC_ELAPSED, "navigator")),
|
||||||
_geofence(this),
|
_geofence(this),
|
||||||
_gf_breach_avoidance(this),
|
_gf_breach_avoidance(this),
|
||||||
_mission(this),
|
_navigator_core(),
|
||||||
_loiter(this),
|
_mission(this, _navigator_core),
|
||||||
_takeoff(this),
|
_loiter(this, _navigator_core),
|
||||||
_land(this),
|
_takeoff(this, _navigator_core),
|
||||||
_precland(this),
|
_land(this, _navigator_core),
|
||||||
_rtl(this),
|
_precland(this, _navigator_core),
|
||||||
_engineFailure(this),
|
_rtl(this, _navigator_core),
|
||||||
_gpsFailure(this),
|
_engineFailure(this, _navigator_core),
|
||||||
_follow_target(this)
|
_gpsFailure(this, _navigator_core),
|
||||||
|
_follow_target(this, _navigator_core)
|
||||||
{
|
{
|
||||||
/* Create a list of our possible navigation types */
|
/* Create a list of our possible navigation types */
|
||||||
_navigation_mode_array[0] = &_mission;
|
_navigation_mode_array[0] = &_mission;
|
||||||
@@ -177,7 +178,9 @@ Navigator::run()
|
|||||||
perf_begin(_loop_perf);
|
perf_begin(_loop_perf);
|
||||||
|
|
||||||
orb_copy(ORB_ID(vehicle_local_position), _local_pos_sub, &_local_pos);
|
orb_copy(ORB_ID(vehicle_local_position), _local_pos_sub, &_local_pos);
|
||||||
|
_navigator_core.updateLocalPosition(_local_pos);
|
||||||
orb_copy(ORB_ID(vehicle_status), _vehicle_status_sub, &_vstatus);
|
orb_copy(ORB_ID(vehicle_status), _vehicle_status_sub, &_vstatus);
|
||||||
|
_navigator_core.updateVehicleStatus(_vstatus);
|
||||||
|
|
||||||
if (fds[2].revents & POLLIN) {
|
if (fds[2].revents & POLLIN) {
|
||||||
// copy mission to clear any update
|
// copy mission to clear any update
|
||||||
@@ -197,6 +200,7 @@ Navigator::run()
|
|||||||
/* global position updated */
|
/* global position updated */
|
||||||
if (_global_pos_sub.updated()) {
|
if (_global_pos_sub.updated()) {
|
||||||
_global_pos_sub.copy(&_global_pos);
|
_global_pos_sub.copy(&_global_pos);
|
||||||
|
_navigator_core.updateGlobalPosition(_global_pos);
|
||||||
|
|
||||||
if (_geofence.getSource() == Geofence::GF_SOURCE_GLOBALPOS) {
|
if (_geofence.getSource() == Geofence::GF_SOURCE_GLOBALPOS) {
|
||||||
have_geofence_position_data = true;
|
have_geofence_position_data = true;
|
||||||
@@ -214,8 +218,10 @@ Navigator::run()
|
|||||||
}
|
}
|
||||||
|
|
||||||
_land_detected_sub.update(&_land_detected);
|
_land_detected_sub.update(&_land_detected);
|
||||||
|
_navigator_core.updateLandedState(_land_detected);
|
||||||
_position_controller_status_sub.update();
|
_position_controller_status_sub.update();
|
||||||
_home_pos_sub.update(&_home_pos);
|
_home_pos_sub.update(&_home_pos);
|
||||||
|
_navigator_core.updateHomePosition(_home_pos);
|
||||||
|
|
||||||
while (_vehicle_command_sub.updated()) {
|
while (_vehicle_command_sub.updated()) {
|
||||||
const unsigned last_generation = _vehicle_command_sub.get_last_generation();
|
const unsigned last_generation = _vehicle_command_sub.get_last_generation();
|
||||||
@@ -254,7 +260,7 @@ Navigator::run()
|
|||||||
}
|
}
|
||||||
|
|
||||||
reposition_valid = _geofence.check(test_reposition_validity, _gps_pos, _home_pos,
|
reposition_valid = _geofence.check(test_reposition_validity, _gps_pos, _home_pos,
|
||||||
home_position_valid());
|
_navigator_core.isHomeValid());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -268,7 +274,7 @@ Navigator::run()
|
|||||||
rep->previous.lon = get_global_position()->lon;
|
rep->previous.lon = get_global_position()->lon;
|
||||||
rep->previous.alt = get_global_position()->alt;
|
rep->previous.alt = get_global_position()->alt;
|
||||||
|
|
||||||
rep->current.loiter_radius = get_loiter_radius();
|
rep->current.loiter_radius = _navigator_core.getLoiterRadiusMeter();
|
||||||
rep->current.loiter_direction = 1;
|
rep->current.loiter_direction = 1;
|
||||||
rep->current.type = position_setpoint_s::SETPOINT_TYPE_LOITER;
|
rep->current.type = position_setpoint_s::SETPOINT_TYPE_LOITER;
|
||||||
|
|
||||||
@@ -281,7 +287,7 @@ Navigator::run()
|
|||||||
}
|
}
|
||||||
|
|
||||||
rep->current.cruising_throttle = get_cruising_throttle();
|
rep->current.cruising_throttle = get_cruising_throttle();
|
||||||
rep->current.acceptance_radius = get_acceptance_radius();
|
rep->current.acceptance_radius = _navigator_core.getHorAcceptanceRadiusMeter();
|
||||||
|
|
||||||
// Go on and check which changes had been requested
|
// Go on and check which changes had been requested
|
||||||
if (PX4_ISFINITE(cmd.param4)) {
|
if (PX4_ISFINITE(cmd.param4)) {
|
||||||
@@ -351,11 +357,11 @@ Navigator::run()
|
|||||||
rep->previous.lon = get_global_position()->lon;
|
rep->previous.lon = get_global_position()->lon;
|
||||||
rep->previous.alt = get_global_position()->alt;
|
rep->previous.alt = get_global_position()->alt;
|
||||||
|
|
||||||
rep->current.loiter_radius = get_loiter_radius();
|
rep->current.loiter_radius = _navigator_core.getLoiterRadiusMeter();
|
||||||
rep->current.loiter_direction = 1;
|
rep->current.loiter_direction = 1;
|
||||||
rep->current.type = position_setpoint_s::SETPOINT_TYPE_TAKEOFF;
|
rep->current.type = position_setpoint_s::SETPOINT_TYPE_TAKEOFF;
|
||||||
|
|
||||||
if (home_position_valid()) {
|
if (_navigator_core.isHomeValid()) {
|
||||||
rep->current.yaw = cmd.param4;
|
rep->current.yaw = cmd.param4;
|
||||||
|
|
||||||
rep->previous.valid = true;
|
rep->previous.valid = true;
|
||||||
@@ -721,7 +727,7 @@ void Navigator::geofence_breach_check(bool &have_geofence_position_data)
|
|||||||
vertical_test_point_distance = _gf_breach_avoidance.computeVerticalBrakingDistanceMultirotor();
|
vertical_test_point_distance = _gf_breach_avoidance.computeVerticalBrakingDistanceMultirotor();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
test_point_distance = 2.0f * get_loiter_radius();
|
test_point_distance = 2.0f * _navigator_core.getLoiterRadiusMeter();
|
||||||
vertical_test_point_distance = 5.0f;
|
vertical_test_point_distance = 5.0f;
|
||||||
|
|
||||||
if (hrt_absolute_time() - pos_ctrl_status.timestamp < 100000 && PX4_ISFINITE(pos_ctrl_status.nav_bearing)) {
|
if (hrt_absolute_time() - pos_ctrl_status.timestamp < 100000 && PX4_ISFINITE(pos_ctrl_status.nav_bearing)) {
|
||||||
@@ -739,7 +745,7 @@ void Navigator::geofence_breach_check(bool &have_geofence_position_data)
|
|||||||
_gf_breach_avoidance.setMaxHorDistHome(_geofence.getMaxHorDistanceHome());
|
_gf_breach_avoidance.setMaxHorDistHome(_geofence.getMaxHorDistanceHome());
|
||||||
_gf_breach_avoidance.setMaxVerDistHome(_geofence.getMaxVerDistanceHome());
|
_gf_breach_avoidance.setMaxVerDistHome(_geofence.getMaxVerDistanceHome());
|
||||||
|
|
||||||
if (home_position_valid()) {
|
if (_navigator_core.isHomeValid()) {
|
||||||
_gf_breach_avoidance.setHomePosition(_home_pos.lat, _home_pos.lon, _home_pos.alt);
|
_gf_breach_avoidance.setHomePosition(_home_pos.lat, _home_pos.lon, _home_pos.alt);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -767,8 +773,8 @@ void Navigator::geofence_breach_check(bool &have_geofence_position_data)
|
|||||||
/* inform other apps via the mission result */
|
/* inform other apps via the mission result */
|
||||||
_geofence_result.geofence_violated = true;
|
_geofence_result.geofence_violated = true;
|
||||||
|
|
||||||
/* Issue a warning about the geofence violation once */
|
/* Issue a warning about the geofence violation once and only if we are armed */
|
||||||
if (!_geofence_violation_warning_sent) {
|
if (!_geofence_violation_warning_sent && _vstatus.arming_state == vehicle_status_s::ARMING_STATE_ARMED) {
|
||||||
mavlink_log_critical(&_mavlink_log_pub, "Approaching on Geofence");
|
mavlink_log_critical(&_mavlink_log_pub, "Approaching on Geofence");
|
||||||
|
|
||||||
// we have predicted a geofence violation and if the action is to loiter then
|
// we have predicted a geofence violation and if the action is to loiter then
|
||||||
@@ -802,12 +808,12 @@ void Navigator::geofence_breach_check(bool &have_geofence_position_data)
|
|||||||
rep->current.lon = lointer_center_lat_lon(1);
|
rep->current.lon = lointer_center_lat_lon(1);
|
||||||
rep->current.alt = loiter_altitude_amsl;
|
rep->current.alt = loiter_altitude_amsl;
|
||||||
rep->current.valid = true;
|
rep->current.valid = true;
|
||||||
rep->current.loiter_radius = get_loiter_radius();
|
rep->current.loiter_radius = _navigator_core.getLoiterRadiusMeter();
|
||||||
rep->current.alt_valid = true;
|
rep->current.alt_valid = true;
|
||||||
rep->current.type = position_setpoint_s::SETPOINT_TYPE_LOITER;
|
rep->current.type = position_setpoint_s::SETPOINT_TYPE_LOITER;
|
||||||
rep->current.loiter_direction = 1;
|
rep->current.loiter_direction = 1;
|
||||||
rep->current.cruising_throttle = get_cruising_throttle();
|
rep->current.cruising_throttle = get_cruising_throttle();
|
||||||
rep->current.acceptance_radius = get_acceptance_radius();
|
rep->current.acceptance_radius = _navigator_core.getHorAcceptanceRadiusMeter();
|
||||||
rep->current.cruising_speed = get_cruising_speed();
|
rep->current.cruising_speed = get_cruising_speed();
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -872,36 +878,13 @@ Navigator::publish_position_setpoint_triplet()
|
|||||||
_pos_sp_triplet_updated = false;
|
_pos_sp_triplet_updated = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
float
|
// float
|
||||||
Navigator::get_default_acceptance_radius()
|
// Navigator::get_default_acceptance_radius()
|
||||||
{
|
// {
|
||||||
return _param_nav_acc_rad.get();
|
// return _navigator_core.getDefaultHorAcceptanceRadiusMeter();
|
||||||
}
|
// }
|
||||||
|
|
||||||
float
|
/* float
|
||||||
Navigator::get_default_altitude_acceptance_radius()
|
|
||||||
{
|
|
||||||
if (get_vstatus()->vehicle_type == vehicle_status_s::VEHICLE_TYPE_FIXED_WING) {
|
|
||||||
return _param_nav_fw_alt_rad.get();
|
|
||||||
|
|
||||||
} else if (get_vstatus()->vehicle_type == vehicle_status_s::VEHICLE_TYPE_ROVER) {
|
|
||||||
return INFINITY;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
float alt_acceptance_radius = _param_nav_mc_alt_rad.get();
|
|
||||||
|
|
||||||
const position_controller_status_s &pos_ctrl_status = _position_controller_status_sub.get();
|
|
||||||
|
|
||||||
if ((pos_ctrl_status.timestamp > _pos_sp_triplet.timestamp)
|
|
||||||
&& pos_ctrl_status.altitude_acceptance > alt_acceptance_radius) {
|
|
||||||
alt_acceptance_radius = pos_ctrl_status.altitude_acceptance;
|
|
||||||
}
|
|
||||||
|
|
||||||
return alt_acceptance_radius;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
float
|
|
||||||
Navigator::get_altitude_acceptance_radius()
|
Navigator::get_altitude_acceptance_radius()
|
||||||
{
|
{
|
||||||
if (get_vstatus()->vehicle_type == vehicle_status_s::VEHICLE_TYPE_FIXED_WING) {
|
if (get_vstatus()->vehicle_type == vehicle_status_s::VEHICLE_TYPE_FIXED_WING) {
|
||||||
@@ -914,7 +897,7 @@ Navigator::get_altitude_acceptance_radius()
|
|||||||
}
|
}
|
||||||
|
|
||||||
return get_default_altitude_acceptance_radius();
|
return get_default_altitude_acceptance_radius();
|
||||||
}
|
} */
|
||||||
|
|
||||||
float
|
float
|
||||||
Navigator::get_cruising_speed()
|
Navigator::get_cruising_speed()
|
||||||
@@ -973,8 +956,8 @@ Navigator::reset_position_setpoint(position_setpoint_s &sp)
|
|||||||
sp.timestamp = hrt_absolute_time();
|
sp.timestamp = hrt_absolute_time();
|
||||||
sp.lat = static_cast<double>(NAN);
|
sp.lat = static_cast<double>(NAN);
|
||||||
sp.lon = static_cast<double>(NAN);;
|
sp.lon = static_cast<double>(NAN);;
|
||||||
sp.loiter_radius = get_loiter_radius();
|
sp.loiter_radius = _navigator_core.getLoiterRadiusMeter();
|
||||||
sp.acceptance_radius = get_default_acceptance_radius();
|
sp.acceptance_radius = _navigator_core.getDefaultHorAcceptanceRadiusMeter();
|
||||||
sp.cruising_speed = get_cruising_speed();
|
sp.cruising_speed = get_cruising_speed();
|
||||||
sp.cruising_throttle = get_cruising_throttle();
|
sp.cruising_throttle = get_cruising_throttle();
|
||||||
sp.valid = false;
|
sp.valid = false;
|
||||||
@@ -994,7 +977,7 @@ Navigator::get_cruising_throttle()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float
|
/* float
|
||||||
Navigator::get_acceptance_radius()
|
Navigator::get_acceptance_radius()
|
||||||
{
|
{
|
||||||
float acceptance_radius = get_default_acceptance_radius(); // the value specified in the parameter NAV_ACC_RAD
|
float acceptance_radius = get_default_acceptance_radius(); // the value specified in the parameter NAV_ACC_RAD
|
||||||
@@ -1008,7 +991,7 @@ Navigator::get_acceptance_radius()
|
|||||||
}
|
}
|
||||||
|
|
||||||
return acceptance_radius;
|
return acceptance_radius;
|
||||||
}
|
} */
|
||||||
|
|
||||||
float
|
float
|
||||||
Navigator::get_yaw_acceptance(float mission_item_yaw)
|
Navigator::get_yaw_acceptance(float mission_item_yaw)
|
||||||
@@ -1270,13 +1253,13 @@ Navigator::abort_landing()
|
|||||||
return should_abort;
|
return should_abort;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
/* bool
|
||||||
Navigator::force_vtol()
|
Navigator::force_vtol()
|
||||||
{
|
{
|
||||||
return _vstatus.is_vtol &&
|
return _vstatus.is_vtol &&
|
||||||
(_vstatus.vehicle_type == vehicle_status_s::VEHICLE_TYPE_FIXED_WING || _vstatus.in_transition_to_fw)
|
(_vstatus.vehicle_type == vehicle_status_s::VEHICLE_TYPE_FIXED_WING || _vstatus.in_transition_to_fw)
|
||||||
&& _param_nav_force_vt.get();
|
&& _param_nav_force_vt.get();
|
||||||
}
|
} */
|
||||||
|
|
||||||
int Navigator::custom_command(int argc, char *argv[])
|
int Navigator::custom_command(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -59,8 +59,8 @@
|
|||||||
|
|
||||||
#define STATE_TIMEOUT 10000000 // [us] Maximum time to spend in any state
|
#define STATE_TIMEOUT 10000000 // [us] Maximum time to spend in any state
|
||||||
|
|
||||||
PrecLand::PrecLand(Navigator *navigator) :
|
PrecLand::PrecLand(Navigator *navigator, NavigatorCore &navigator_core) :
|
||||||
MissionBlock(navigator),
|
MissionBlock(navigator, _navigator_core),
|
||||||
ModuleParams(navigator)
|
ModuleParams(navigator)
|
||||||
{
|
{
|
||||||
_handle_param_acceleration_hor = param_find("MPC_ACC_HOR");
|
_handle_param_acceleration_hor = param_find("MPC_ACC_HOR");
|
||||||
@@ -90,9 +90,9 @@ PrecLand::on_activation()
|
|||||||
// Check that the current position setpoint is valid, otherwise land at current position
|
// Check that the current position setpoint is valid, otherwise land at current position
|
||||||
if (!pos_sp_triplet->current.valid) {
|
if (!pos_sp_triplet->current.valid) {
|
||||||
PX4_WARN("Resetting landing position to current position");
|
PX4_WARN("Resetting landing position to current position");
|
||||||
pos_sp_triplet->current.lat = _navigator->get_global_position()->lat;
|
pos_sp_triplet->current.lat = _navigator_core.getLatRad();
|
||||||
pos_sp_triplet->current.lon = _navigator->get_global_position()->lon;
|
pos_sp_triplet->current.lon = _navigator_core.getLonRad();
|
||||||
pos_sp_triplet->current.alt = _navigator->get_global_position()->alt;
|
pos_sp_triplet->current.alt = _navigator_core.getAltitudeAMSLMeters();
|
||||||
pos_sp_triplet->current.valid = true;
|
pos_sp_triplet->current.valid = true;
|
||||||
pos_sp_triplet->current.timestamp = hrt_absolute_time();
|
pos_sp_triplet->current.timestamp = hrt_absolute_time();
|
||||||
}
|
}
|
||||||
@@ -121,7 +121,7 @@ PrecLand::on_active()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// stop if we are landed
|
// stop if we are landed
|
||||||
if (_navigator->get_land_detected()->landed) {
|
if (_navigator_core.getLanded()) {
|
||||||
switch_to_state_done();
|
switch_to_state_done();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,10 +198,10 @@ PrecLand::run_state_start()
|
|||||||
|
|
||||||
position_setpoint_triplet_s *pos_sp_triplet = _navigator->get_position_setpoint_triplet();
|
position_setpoint_triplet_s *pos_sp_triplet = _navigator->get_position_setpoint_triplet();
|
||||||
float dist = get_distance_to_next_waypoint(pos_sp_triplet->current.lat, pos_sp_triplet->current.lon,
|
float dist = get_distance_to_next_waypoint(pos_sp_triplet->current.lat, pos_sp_triplet->current.lon,
|
||||||
_navigator->get_global_position()->lat, _navigator->get_global_position()->lon);
|
_navigator_core.getLatRad(), _navigator_core.getLonRad());
|
||||||
|
|
||||||
// check if we've reached the start point
|
// check if we've reached the start point
|
||||||
if (dist < _navigator->get_acceptance_radius()) {
|
if (dist < _navigator_core.getAcceptanceRadiusMeter()) {
|
||||||
if (!_point_reached_time) {
|
if (!_point_reached_time) {
|
||||||
_point_reached_time = hrt_absolute_time();
|
_point_reached_time = hrt_absolute_time();
|
||||||
}
|
}
|
||||||
@@ -235,9 +235,9 @@ PrecLand::run_state_horizontal_approach()
|
|||||||
PX4_WARN("Lost landing target while landing (horizontal approach).");
|
PX4_WARN("Lost landing target while landing (horizontal approach).");
|
||||||
|
|
||||||
// Stay at current position for searching for the landing target
|
// Stay at current position for searching for the landing target
|
||||||
pos_sp_triplet->current.lat = _navigator->get_global_position()->lat;
|
pos_sp_triplet->current.lat = _navigator_core.getLatRad();
|
||||||
pos_sp_triplet->current.lon = _navigator->get_global_position()->lon;
|
pos_sp_triplet->current.lon = _navigator_core.getLonRad();
|
||||||
pos_sp_triplet->current.alt = _navigator->get_global_position()->alt;
|
pos_sp_triplet->current.alt = _navigator_core.getAltitudeAMSLMeters();
|
||||||
|
|
||||||
if (!switch_to_state_start()) {
|
if (!switch_to_state_start()) {
|
||||||
if (!switch_to_state_fallback()) {
|
if (!switch_to_state_fallback()) {
|
||||||
@@ -300,9 +300,9 @@ PrecLand::run_state_descend_above_target()
|
|||||||
PX4_WARN("Lost landing target while landing (descending).");
|
PX4_WARN("Lost landing target while landing (descending).");
|
||||||
|
|
||||||
// Stay at current position for searching for the target
|
// Stay at current position for searching for the target
|
||||||
pos_sp_triplet->current.lat = _navigator->get_global_position()->lat;
|
pos_sp_triplet->current.lat = _navigator_core.getLatRad();
|
||||||
pos_sp_triplet->current.lon = _navigator->get_global_position()->lon;
|
pos_sp_triplet->current.lon = _navigator_core.getLonRad();
|
||||||
pos_sp_triplet->current.alt = _navigator->get_global_position()->alt;
|
pos_sp_triplet->current.alt = _navigator_core.getAltitudeAMSLMeters();
|
||||||
|
|
||||||
if (!switch_to_state_start()) {
|
if (!switch_to_state_start()) {
|
||||||
if (!switch_to_state_fallback()) {
|
if (!switch_to_state_fallback()) {
|
||||||
@@ -341,7 +341,7 @@ PrecLand::run_state_search()
|
|||||||
// target just became visible. Stop climbing, but give it some margin so we don't stop too apruptly
|
// target just became visible. Stop climbing, but give it some margin so we don't stop too apruptly
|
||||||
_target_acquired_time = hrt_absolute_time();
|
_target_acquired_time = hrt_absolute_time();
|
||||||
position_setpoint_triplet_s *pos_sp_triplet = _navigator->get_position_setpoint_triplet();
|
position_setpoint_triplet_s *pos_sp_triplet = _navigator->get_position_setpoint_triplet();
|
||||||
float new_alt = _navigator->get_global_position()->alt + 1.0f;
|
float new_alt = _navigator_core.getAltitudeAMSLMeters() + 1.0f;
|
||||||
pos_sp_triplet->current.alt = new_alt < pos_sp_triplet->current.alt ? new_alt : pos_sp_triplet->current.alt;
|
pos_sp_triplet->current.alt = new_alt < pos_sp_triplet->current.alt ? new_alt : pos_sp_triplet->current.alt;
|
||||||
_navigator->set_position_setpoint_triplet_updated();
|
_navigator->set_position_setpoint_triplet_updated();
|
||||||
}
|
}
|
||||||
@@ -395,7 +395,7 @@ bool
|
|||||||
PrecLand::switch_to_state_horizontal_approach()
|
PrecLand::switch_to_state_horizontal_approach()
|
||||||
{
|
{
|
||||||
if (check_state_conditions(PrecLandState::HorizontalApproach)) {
|
if (check_state_conditions(PrecLandState::HorizontalApproach)) {
|
||||||
_approach_alt = _navigator->get_global_position()->alt;
|
_approach_alt = _navigator_core.getAltitudeAMSLMeters();
|
||||||
|
|
||||||
_point_reached_time = 0;
|
_point_reached_time = 0;
|
||||||
|
|
||||||
@@ -454,9 +454,9 @@ PrecLand::switch_to_state_fallback()
|
|||||||
{
|
{
|
||||||
PX4_WARN("Falling back to normal land.");
|
PX4_WARN("Falling back to normal land.");
|
||||||
position_setpoint_triplet_s *pos_sp_triplet = _navigator->get_position_setpoint_triplet();
|
position_setpoint_triplet_s *pos_sp_triplet = _navigator->get_position_setpoint_triplet();
|
||||||
pos_sp_triplet->current.lat = _navigator->get_global_position()->lat;
|
pos_sp_triplet->current.lat = _navigator_core.getLatRad();
|
||||||
pos_sp_triplet->current.lon = _navigator->get_global_position()->lon;
|
pos_sp_triplet->current.lon = _navigator_core.getLonRad();
|
||||||
pos_sp_triplet->current.alt = _navigator->get_global_position()->alt;
|
pos_sp_triplet->current.alt = _navigator_core.getAltitudeAMSLMeters();
|
||||||
pos_sp_triplet->current.type = position_setpoint_s::SETPOINT_TYPE_LAND;
|
pos_sp_triplet->current.type = position_setpoint_s::SETPOINT_TYPE_LAND;
|
||||||
_navigator->set_position_setpoint_triplet_updated();
|
_navigator->set_position_setpoint_triplet_updated();
|
||||||
|
|
||||||
@@ -557,8 +557,8 @@ void PrecLand::slewrate(float &sp_x, float &sp_y)
|
|||||||
// set a best guess for previous setpoints for smooth transition
|
// set a best guess for previous setpoints for smooth transition
|
||||||
map_projection_project(&_map_ref, _navigator->get_position_setpoint_triplet()->current.lat,
|
map_projection_project(&_map_ref, _navigator->get_position_setpoint_triplet()->current.lat,
|
||||||
_navigator->get_position_setpoint_triplet()->current.lon, &_sp_pev(0), &_sp_pev(1));
|
_navigator->get_position_setpoint_triplet()->current.lon, &_sp_pev(0), &_sp_pev(1));
|
||||||
_sp_pev_prev(0) = _sp_pev(0) - _navigator->get_local_position()->vx * dt;
|
_sp_pev_prev(0) = _sp_pev(0) - _navigator_core.getVelNorthMPS() * dt;
|
||||||
_sp_pev_prev(1) = _sp_pev(1) - _navigator->get_local_position()->vy * dt;
|
_sp_pev_prev(1) = _sp_pev(1) - _navigator_core.getVelEastMPS() * dt;
|
||||||
}
|
}
|
||||||
|
|
||||||
_last_slewrate_time = now;
|
_last_slewrate_time = now;
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ enum class PrecLandMode {
|
|||||||
class PrecLand : public MissionBlock, public ModuleParams
|
class PrecLand : public MissionBlock, public ModuleParams
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PrecLand(Navigator *navigator);
|
PrecLand(Navigator *navigator, NavigatorCore &navigator_core);
|
||||||
~PrecLand() override = default;
|
~PrecLand() override = default;
|
||||||
|
|
||||||
void on_activation() override;
|
void on_activation() override;
|
||||||
|
|||||||
@@ -52,8 +52,8 @@ static constexpr float DELAY_SIGMA = 0.01f;
|
|||||||
using namespace time_literals;
|
using namespace time_literals;
|
||||||
using namespace math;
|
using namespace math;
|
||||||
|
|
||||||
RTL::RTL(Navigator *navigator) :
|
RTL::RTL(Navigator *navigator, NavigatorCore &navigator_core) :
|
||||||
MissionBlock(navigator),
|
MissionBlock(navigator, navigator_core),
|
||||||
ModuleParams(navigator)
|
ModuleParams(navigator)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -80,14 +80,14 @@ void RTL::find_RTL_destination()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_navigator->home_position_valid()) {
|
if (!_navigator_core.isHomeValid()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_destination_check_time = hrt_absolute_time();
|
_destination_check_time = hrt_absolute_time();
|
||||||
|
|
||||||
// get home position:
|
// get home position:
|
||||||
home_position_s &home_landing_position = *_navigator->get_home_position();
|
home_position_s &home_landing_position = _navigator_core.getHomePosition();
|
||||||
|
|
||||||
// get global position
|
// get global position
|
||||||
const vehicle_global_position_s &global_position = *_navigator->get_global_position();
|
const vehicle_global_position_s &global_position = *_navigator->get_global_position();
|
||||||
@@ -110,8 +110,8 @@ void RTL::find_RTL_destination()
|
|||||||
|
|
||||||
_destination.type = RTL_DESTINATION_HOME;
|
_destination.type = RTL_DESTINATION_HOME;
|
||||||
|
|
||||||
const bool vtol_in_rw_mode = _navigator->get_vstatus()->is_vtol
|
const bool vtol_in_rw_mode = _navigator_core.isVTOL()
|
||||||
&& _navigator->get_vstatus()->vehicle_type == vehicle_status_s::VEHICLE_TYPE_ROTARY_WING;
|
&& _navigator_core.isRotaryWing();
|
||||||
|
|
||||||
|
|
||||||
// consider the mission landing if not RTL_HOME type set
|
// consider the mission landing if not RTL_HOME type set
|
||||||
@@ -237,8 +237,8 @@ void RTL::find_RTL_destination()
|
|||||||
void RTL::on_activation()
|
void RTL::on_activation()
|
||||||
{
|
{
|
||||||
|
|
||||||
_deny_mission_landing = _navigator->get_vstatus()->is_vtol
|
_deny_mission_landing = _navigator_core.isVTOL()
|
||||||
&& _navigator->get_vstatus()->vehicle_type == vehicle_status_s::VEHICLE_TYPE_ROTARY_WING;
|
&& _navigator_core.isRotaryWing();
|
||||||
|
|
||||||
// output the correct message, depending on where the RTL destination is
|
// output the correct message, depending on where the RTL destination is
|
||||||
switch (_destination.type) {
|
switch (_destination.type) {
|
||||||
@@ -259,16 +259,15 @@ void RTL::on_activation()
|
|||||||
|
|
||||||
_rtl_loiter_rad = _param_rtl_loiter_rad.get();
|
_rtl_loiter_rad = _param_rtl_loiter_rad.get();
|
||||||
|
|
||||||
if (_navigator->get_vstatus()->vehicle_type == vehicle_status_s::VEHICLE_TYPE_ROTARY_WING) {
|
if (_navigator_core.isRotaryWing()) {
|
||||||
_rtl_alt = calculate_return_alt_from_cone_half_angle((float)_param_rtl_cone_half_angle_deg.get());
|
_rtl_alt = calculate_return_alt_from_cone_half_angle((float)_param_rtl_cone_half_angle_deg.get());
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
_rtl_alt = max(global_position.alt, max(_destination.alt,
|
_rtl_alt = max(global_position.alt, max(_destination.alt,
|
||||||
_navigator->get_home_position()->alt + _param_rtl_return_alt.get()));
|
_navigator_core.getHomeAltAMSLMeter() + _param_rtl_return_alt.get()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_navigator_core.getLanded()) {
|
||||||
if (_navigator->get_land_detected()->landed) {
|
|
||||||
// For safety reasons don't go into RTL if landed.
|
// For safety reasons don't go into RTL if landed.
|
||||||
_rtl_state = RTL_STATE_LANDED;
|
_rtl_state = RTL_STATE_LANDED;
|
||||||
|
|
||||||
@@ -343,7 +342,7 @@ void RTL::set_rtl_item()
|
|||||||
|
|
||||||
// do not use LOITER_TO_ALT for rotary wing mode as it would then always climb to at least MIS_LTRMIN_ALT,
|
// do not use LOITER_TO_ALT for rotary wing mode as it would then always climb to at least MIS_LTRMIN_ALT,
|
||||||
// even if current climb altitude is below (e.g. RTL immediately after take off)
|
// even if current climb altitude is below (e.g. RTL immediately after take off)
|
||||||
if (_navigator->get_vstatus()->vehicle_type == vehicle_status_s::VEHICLE_TYPE_ROTARY_WING) {
|
if (_navigator_core.isRotaryWing()) {
|
||||||
_mission_item.nav_cmd = NAV_CMD_WAYPOINT;
|
_mission_item.nav_cmd = NAV_CMD_WAYPOINT;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@@ -354,8 +353,8 @@ void RTL::set_rtl_item()
|
|||||||
_mission_item.lon = gpos.lon;
|
_mission_item.lon = gpos.lon;
|
||||||
_mission_item.altitude = _rtl_alt;
|
_mission_item.altitude = _rtl_alt;
|
||||||
_mission_item.altitude_is_relative = false;
|
_mission_item.altitude_is_relative = false;
|
||||||
_mission_item.yaw = _navigator->get_local_position()->heading;
|
_mission_item.yaw = _navigator_core.getTrueHeadingRad();
|
||||||
_mission_item.acceptance_radius = _navigator->get_acceptance_radius();
|
_mission_item.acceptance_radius = _navigator_core.getAcceptanceRadiusMeter();
|
||||||
_mission_item.time_inside = 0.0f;
|
_mission_item.time_inside = 0.0f;
|
||||||
_mission_item.autocontinue = true;
|
_mission_item.autocontinue = true;
|
||||||
_mission_item.origin = ORIGIN_ONBOARD;
|
_mission_item.origin = ORIGIN_ONBOARD;
|
||||||
@@ -383,7 +382,7 @@ void RTL::set_rtl_item()
|
|||||||
_mission_item.yaw = get_bearing_to_next_waypoint(gpos.lat, gpos.lon, _destination.lat, _destination.lon);
|
_mission_item.yaw = get_bearing_to_next_waypoint(gpos.lat, gpos.lon, _destination.lat, _destination.lon);
|
||||||
}
|
}
|
||||||
|
|
||||||
_mission_item.acceptance_radius = _navigator->get_acceptance_radius();
|
_mission_item.acceptance_radius = _navigator_core.getAcceptanceRadiusMeter();
|
||||||
_mission_item.time_inside = 0.0f;
|
_mission_item.time_inside = 0.0f;
|
||||||
_mission_item.autocontinue = true;
|
_mission_item.autocontinue = true;
|
||||||
_mission_item.origin = ORIGIN_ONBOARD;
|
_mission_item.origin = ORIGIN_ONBOARD;
|
||||||
@@ -405,18 +404,18 @@ void RTL::set_rtl_item()
|
|||||||
// Except for vtol which might be still off here and should point towards this location.
|
// Except for vtol which might be still off here and should point towards this location.
|
||||||
const float d_current = get_distance_to_next_waypoint(gpos.lat, gpos.lon, _mission_item.lat, _mission_item.lon);
|
const float d_current = get_distance_to_next_waypoint(gpos.lat, gpos.lon, _mission_item.lat, _mission_item.lon);
|
||||||
|
|
||||||
if (_navigator->get_vstatus()->is_vtol && (d_current > _navigator->get_acceptance_radius())) {
|
if (_navigator_core.isVTOL() && (d_current > _navigator_core.getAcceptanceRadiusMeter())) {
|
||||||
_mission_item.yaw = get_bearing_to_next_waypoint(gpos.lat, gpos.lon, _mission_item.lat, _mission_item.lon);
|
_mission_item.yaw = get_bearing_to_next_waypoint(gpos.lat, gpos.lon, _mission_item.lat, _mission_item.lon);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
_mission_item.yaw = _destination.yaw;
|
_mission_item.yaw = _destination.yaw;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_navigator->get_vstatus()->is_vtol) {
|
if (_navigator->getCore().isVTOL()) {
|
||||||
_mission_item.loiter_radius = _rtl_loiter_rad;
|
_mission_item.loiter_radius = _rtl_loiter_rad;
|
||||||
}
|
}
|
||||||
|
|
||||||
_mission_item.acceptance_radius = _navigator->get_acceptance_radius();
|
_mission_item.acceptance_radius = _navigator_core.getAcceptanceRadiusMeter();
|
||||||
_mission_item.time_inside = 0.0f;
|
_mission_item.time_inside = 0.0f;
|
||||||
_mission_item.autocontinue = true;
|
_mission_item.autocontinue = true;
|
||||||
_mission_item.origin = ORIGIN_ONBOARD;
|
_mission_item.origin = ORIGIN_ONBOARD;
|
||||||
@@ -438,8 +437,8 @@ void RTL::set_rtl_item()
|
|||||||
_mission_item.altitude = loiter_altitude;
|
_mission_item.altitude = loiter_altitude;
|
||||||
_mission_item.altitude_is_relative = false;
|
_mission_item.altitude_is_relative = false;
|
||||||
_mission_item.yaw = _destination.yaw;
|
_mission_item.yaw = _destination.yaw;
|
||||||
_mission_item.loiter_radius = _navigator->get_loiter_radius();
|
_mission_item.loiter_radius = _navigator_core.getLoiterRadiusMeter();
|
||||||
_mission_item.acceptance_radius = _navigator->get_acceptance_radius();
|
_mission_item.acceptance_radius = _navigator_core.getAcceptanceRadiusMeter();
|
||||||
_mission_item.time_inside = max(_param_rtl_land_delay.get(), 0.0f);
|
_mission_item.time_inside = max(_param_rtl_land_delay.get(), 0.0f);
|
||||||
_mission_item.autocontinue = autoland;
|
_mission_item.autocontinue = autoland;
|
||||||
_mission_item.origin = ORIGIN_ONBOARD;
|
_mission_item.origin = ORIGIN_ONBOARD;
|
||||||
@@ -467,7 +466,7 @@ void RTL::set_rtl_item()
|
|||||||
_mission_item.altitude = loiter_altitude;
|
_mission_item.altitude = loiter_altitude;
|
||||||
_mission_item.altitude_is_relative = false;
|
_mission_item.altitude_is_relative = false;
|
||||||
_mission_item.yaw = get_bearing_to_next_waypoint(gpos.lat, gpos.lon, _mission_item.lat, _mission_item.lon);
|
_mission_item.yaw = get_bearing_to_next_waypoint(gpos.lat, gpos.lon, _mission_item.lat, _mission_item.lon);
|
||||||
_mission_item.acceptance_radius = _navigator->get_acceptance_radius();
|
_mission_item.acceptance_radius = _navigator_core.getAcceptanceRadiusMeter();
|
||||||
_mission_item.time_inside = 0.0f;
|
_mission_item.time_inside = 0.0f;
|
||||||
_mission_item.autocontinue = true;
|
_mission_item.autocontinue = true;
|
||||||
_mission_item.origin = ORIGIN_ONBOARD;
|
_mission_item.origin = ORIGIN_ONBOARD;
|
||||||
@@ -489,7 +488,7 @@ void RTL::set_rtl_item()
|
|||||||
_mission_item.altitude = loiter_altitude;
|
_mission_item.altitude = loiter_altitude;
|
||||||
_mission_item.altitude_is_relative = false;
|
_mission_item.altitude_is_relative = false;
|
||||||
_mission_item.yaw = get_bearing_to_next_waypoint(gpos.lat, gpos.lon, _mission_item.lat, _mission_item.lon);
|
_mission_item.yaw = get_bearing_to_next_waypoint(gpos.lat, gpos.lon, _mission_item.lat, _mission_item.lon);
|
||||||
_mission_item.acceptance_radius = _navigator->get_acceptance_radius();
|
_mission_item.acceptance_radius = _navigator_core.getAcceptanceRadiusMeter();
|
||||||
_mission_item.origin = ORIGIN_ONBOARD;
|
_mission_item.origin = ORIGIN_ONBOARD;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -502,7 +501,7 @@ void RTL::set_rtl_item()
|
|||||||
_mission_item.yaw = _destination.yaw;
|
_mission_item.yaw = _destination.yaw;
|
||||||
_mission_item.altitude = _destination.alt;
|
_mission_item.altitude = _destination.alt;
|
||||||
_mission_item.altitude_is_relative = false;
|
_mission_item.altitude_is_relative = false;
|
||||||
_mission_item.acceptance_radius = _navigator->get_acceptance_radius();
|
_mission_item.acceptance_radius = _navigator_core.getAcceptanceRadiusMeter();
|
||||||
_mission_item.time_inside = 0.0f;
|
_mission_item.time_inside = 0.0f;
|
||||||
_mission_item.autocontinue = true;
|
_mission_item.autocontinue = true;
|
||||||
_mission_item.origin = ORIGIN_ONBOARD;
|
_mission_item.origin = ORIGIN_ONBOARD;
|
||||||
@@ -552,8 +551,8 @@ void RTL::advance_rtl()
|
|||||||
const bool descend_and_loiter = _param_rtl_land_delay.get() < -DELAY_SIGMA || _param_rtl_land_delay.get() > DELAY_SIGMA;
|
const bool descend_and_loiter = _param_rtl_land_delay.get() < -DELAY_SIGMA || _param_rtl_land_delay.get() > DELAY_SIGMA;
|
||||||
|
|
||||||
// vehicle is a vtol and currently in fixed wing mode
|
// vehicle is a vtol and currently in fixed wing mode
|
||||||
const bool vtol_in_fw_mode = _navigator->get_vstatus()->is_vtol
|
const bool vtol_in_fw_mode = _navigator_core.isVTOL()
|
||||||
&& _navigator->get_vstatus()->vehicle_type == vehicle_status_s::VEHICLE_TYPE_FIXED_WING;
|
&& _navigator_core.isFixedWing();
|
||||||
|
|
||||||
switch (_rtl_state) {
|
switch (_rtl_state) {
|
||||||
case RTL_STATE_CLIMB:
|
case RTL_STATE_CLIMB:
|
||||||
@@ -635,11 +634,11 @@ float RTL::calculate_return_alt_from_cone_half_angle(float cone_half_angle_deg)
|
|||||||
// We choose the minimum height to be two times the distance from the land position in order to
|
// We choose the minimum height to be two times the distance from the land position in order to
|
||||||
// avoid the vehicle touching the ground while still moving horizontally.
|
// avoid the vehicle touching the ground while still moving horizontally.
|
||||||
const float return_altitude_min_outside_acceptance_rad_amsl = _destination.alt + 2.0f *
|
const float return_altitude_min_outside_acceptance_rad_amsl = _destination.alt + 2.0f *
|
||||||
_navigator->get_acceptance_radius();
|
_navigator_core.getAcceptanceRadiusMeter();
|
||||||
|
|
||||||
float return_altitude_amsl = _destination.alt + _param_rtl_return_alt.get();
|
float return_altitude_amsl = _destination.alt + _param_rtl_return_alt.get();
|
||||||
|
|
||||||
if (destination_dist <= _navigator->get_acceptance_radius()) {
|
if (destination_dist <= _navigator_core.getAcceptanceRadiusMeter()) {
|
||||||
return_altitude_amsl = _destination.alt + 2.0f * destination_dist;
|
return_altitude_amsl = _destination.alt + 2.0f * destination_dist;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@@ -663,7 +662,7 @@ float RTL::calculate_return_alt_from_cone_half_angle(float cone_half_angle_deg)
|
|||||||
|
|
||||||
void RTL::get_rtl_xy_z_speed(float &xy, float &z)
|
void RTL::get_rtl_xy_z_speed(float &xy, float &z)
|
||||||
{
|
{
|
||||||
uint8_t vehicle_type = _navigator->get_vstatus()->vehicle_type;
|
uint8_t vehicle_type = _navigator_core.getVehicleType();
|
||||||
// Caution: here be dragons!
|
// Caution: here be dragons!
|
||||||
// Use C API to allow this code to be compiled with builds that don't have FW/MC/Rover
|
// Use C API to allow this code to be compiled with builds that don't have FW/MC/Rover
|
||||||
|
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ public:
|
|||||||
RTL_DESTINATION_SAFE_POINT,
|
RTL_DESTINATION_SAFE_POINT,
|
||||||
};
|
};
|
||||||
|
|
||||||
RTL(Navigator *navigator);
|
RTL(Navigator *navigator, NavigatorCore &navigator_core);
|
||||||
|
|
||||||
~RTL() = default;
|
~RTL() = default;
|
||||||
|
|
||||||
|
|||||||
@@ -41,8 +41,10 @@
|
|||||||
#include "takeoff.h"
|
#include "takeoff.h"
|
||||||
#include "navigator.h"
|
#include "navigator.h"
|
||||||
|
|
||||||
Takeoff::Takeoff(Navigator *navigator) :
|
using matrix::wrap_pi;
|
||||||
MissionBlock(navigator)
|
|
||||||
|
Takeoff::Takeoff(Navigator *navigator, NavigatorCore &navigator_core) :
|
||||||
|
MissionBlock(navigator, navigator_core)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,7 +66,6 @@ Takeoff::on_active()
|
|||||||
} else if (is_mission_item_reached() && !_navigator->get_mission_result()->finished) {
|
} else if (is_mission_item_reached() && !_navigator->get_mission_result()->finished) {
|
||||||
_navigator->get_mission_result()->finished = true;
|
_navigator->get_mission_result()->finished = true;
|
||||||
_navigator->set_mission_result_updated();
|
_navigator->set_mission_result_updated();
|
||||||
|
|
||||||
// set loiter item so position controllers stop doing takeoff logic
|
// set loiter item so position controllers stop doing takeoff logic
|
||||||
set_loiter_item(&_mission_item);
|
set_loiter_item(&_mission_item);
|
||||||
struct position_setpoint_triplet_s *pos_sp_triplet = _navigator->get_position_setpoint_triplet();
|
struct position_setpoint_triplet_s *pos_sp_triplet = _navigator->get_position_setpoint_triplet();
|
||||||
@@ -83,22 +84,22 @@ Takeoff::set_takeoff_position()
|
|||||||
|
|
||||||
float min_abs_altitude;
|
float min_abs_altitude;
|
||||||
|
|
||||||
if (_navigator->home_position_valid()) { //only use home position if it is valid
|
if (_navigator_core.isHomeValid()) { //only use home position if it is valid
|
||||||
min_abs_altitude = _navigator->get_global_position()->alt + _navigator->get_takeoff_min_alt();
|
min_abs_altitude = _navigator_core.getAltitudeAMSLMeters() + _navigator_core.getRelativeTakeoffMinAltitudeMeter();
|
||||||
|
|
||||||
} else { //e.g. flow
|
} else { //e.g. flow
|
||||||
min_abs_altitude = _navigator->get_takeoff_min_alt();
|
min_abs_altitude = _navigator_core.getRelativeTakeoffMinAltitudeMeter();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use altitude if it has been set. If home position is invalid use min_abs_altitude
|
// Use altitude if it has been set. If home position is invalid use min_abs_altitude
|
||||||
if (rep->current.valid && PX4_ISFINITE(rep->current.alt) && _navigator->home_position_valid()) {
|
if (rep->current.valid && PX4_ISFINITE(rep->current.alt) && _navigator_core.isHomeValid()) {
|
||||||
abs_altitude = rep->current.alt;
|
abs_altitude = rep->current.alt;
|
||||||
|
|
||||||
// If the altitude suggestion is lower than home + minimum clearance, raise it and complain.
|
// If the altitude suggestion is lower than home + minimum clearance, raise it and complain.
|
||||||
if (abs_altitude < min_abs_altitude) {
|
if (abs_altitude < min_abs_altitude) {
|
||||||
if (abs_altitude < min_abs_altitude - 0.1f) { // don't complain if difference is smaller than 10cm
|
if (abs_altitude < min_abs_altitude - 0.1f) { // don't complain if difference is smaller than 10cm
|
||||||
mavlink_log_critical(_navigator->get_mavlink_log_pub(),
|
mavlink_log_critical(_navigator->get_mavlink_log_pub(),
|
||||||
"Using minimum takeoff altitude: %.2f m", (double)_navigator->get_takeoff_min_alt());
|
"Using minimum takeoff altitude: %.2f m", (double)_navigator_core.getRelativeTakeoffMinAltitudeMeter());
|
||||||
}
|
}
|
||||||
|
|
||||||
abs_altitude = min_abs_altitude;
|
abs_altitude = min_abs_altitude;
|
||||||
@@ -108,13 +109,13 @@ Takeoff::set_takeoff_position()
|
|||||||
// Use home + minimum clearance but only notify.
|
// Use home + minimum clearance but only notify.
|
||||||
abs_altitude = min_abs_altitude;
|
abs_altitude = min_abs_altitude;
|
||||||
mavlink_log_info(_navigator->get_mavlink_log_pub(),
|
mavlink_log_info(_navigator->get_mavlink_log_pub(),
|
||||||
"Using minimum takeoff altitude: %.2f m", (double)_navigator->get_takeoff_min_alt());
|
"Using minimum takeoff altitude: %.2f m", (double)_navigator_core.getRelativeTakeoffMinAltitudeMeter());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (abs_altitude < _navigator->get_global_position()->alt) {
|
if (abs_altitude < _navigator_core.getAltitudeAMSLMeters()) {
|
||||||
// If the suggestion is lower than our current alt, let's not go down.
|
// If the suggestion is lower than our current alt, let's not go down.
|
||||||
abs_altitude = _navigator->get_global_position()->alt;
|
abs_altitude = _navigator_core.getAltitudeAMSLMeters();
|
||||||
mavlink_log_critical(_navigator->get_mavlink_log_pub(), "Already higher than takeoff altitude");
|
mavlink_log_critical(_navigator->get_mavlink_log_pub(), "Already higher than takeoff altitude");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -46,7 +46,7 @@
|
|||||||
class Takeoff : public MissionBlock
|
class Takeoff : public MissionBlock
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Takeoff(Navigator *navigator);
|
Takeoff(Navigator *navigator, NavigatorCore &navigator_core);
|
||||||
~Takeoff() = default;
|
~Takeoff() = default;
|
||||||
|
|
||||||
void on_activation() override;
|
void on_activation() override;
|
||||||
|
|||||||
Reference in New Issue
Block a user