mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-10-16 03:43:33 +08:00
Merge remote-tracking branch 'px4/master' into navigator_rewrite
Conflicts: src/modules/navigator/navigator_main.cpp
This commit is contained in:
@@ -14,19 +14,20 @@ sh /etc/init.d/rc.mc_defaults
|
||||
if [ $DO_AUTOCONFIG == yes ]
|
||||
then
|
||||
# Set all params here, then disable autoconfig
|
||||
param set MC_ROLL_P 5.0
|
||||
param set MC_ROLLRATE_P 0.13
|
||||
param set MC_ROLLRATE_I 0.0
|
||||
param set MC_ROLLRATE_D 0.0
|
||||
param set MC_PITCH_P 5.0
|
||||
param set MC_PITCHRATE_P 0.13
|
||||
param set MC_PITCHRATE_I 0.0
|
||||
param set MC_PITCHRATE_D 0.0
|
||||
param set MC_YAW_P 1.0
|
||||
param set MC_YAWRATE_P 0.15
|
||||
param set MC_YAWRATE_I 0.0
|
||||
param set MC_ROLL_P 6.0
|
||||
param set MC_ROLLRATE_P 0.14
|
||||
param set MC_ROLLRATE_I 0.1
|
||||
param set MC_ROLLRATE_D 0.002
|
||||
param set MC_PITCH_P 6.0
|
||||
param set MC_PITCHRATE_P 0.14
|
||||
param set MC_PITCHRATE_I 0.1
|
||||
param set MC_PITCHRATE_D 0.002
|
||||
param set MC_YAW_P 2.0
|
||||
param set MC_YAWRATE_P 0.2
|
||||
param set MC_YAWRATE_I 0.2
|
||||
param set MC_YAWRATE_D 0.0
|
||||
param set MC_YAW_FF 0.15
|
||||
param set MC_YAW_FF 0.8
|
||||
|
||||
param set BAT_V_SCALING 0.00838095238
|
||||
fi
|
||||
|
||||
|
||||
@@ -37,10 +37,11 @@ then
|
||||
param set MPC_LAND_SPEED 1.0
|
||||
|
||||
param set PE_VELNE_NOISE 0.5
|
||||
param set PE_VELNE_NOISE 0.7
|
||||
param set PE_VELD_NOISE 0.7
|
||||
param set PE_POSNE_NOISE 0.5
|
||||
param set PE_POSD_NOISE 1.0
|
||||
|
||||
param set NAV_ACCEPT_RAD 2.0
|
||||
fi
|
||||
|
||||
set PWM_RATE 400
|
||||
|
||||
@@ -65,12 +65,12 @@ then
|
||||
# Start CDC/ACM serial driver
|
||||
#
|
||||
sercon
|
||||
|
||||
|
||||
#
|
||||
# Start the ORB (first app to start)
|
||||
#
|
||||
uorb start
|
||||
|
||||
|
||||
#
|
||||
# Load parameters
|
||||
#
|
||||
@@ -79,7 +79,7 @@ then
|
||||
then
|
||||
set PARAM_FILE /fs/mtd_params
|
||||
fi
|
||||
|
||||
|
||||
param select $PARAM_FILE
|
||||
if param load
|
||||
then
|
||||
@@ -87,21 +87,25 @@ then
|
||||
else
|
||||
echo "[init] ERROR: Params loading failed: $PARAM_FILE"
|
||||
fi
|
||||
|
||||
|
||||
#
|
||||
# Start system state indicator
|
||||
#
|
||||
if rgbled start
|
||||
then
|
||||
echo "[init] Using external RGB Led"
|
||||
echo "[init] RGB Led"
|
||||
else
|
||||
if blinkm start
|
||||
then
|
||||
echo "[init] Using blinkm"
|
||||
echo "[init] BlinkM"
|
||||
blinkm systemstate
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
if pca8574 start
|
||||
then
|
||||
fi
|
||||
|
||||
#
|
||||
# Set default values
|
||||
#
|
||||
@@ -122,7 +126,7 @@ then
|
||||
set LOAD_DEFAULT_APPS yes
|
||||
set GPS yes
|
||||
set GPS_FAKE no
|
||||
|
||||
|
||||
#
|
||||
# Set DO_AUTOCONFIG flag to use it in AUTOSTART scripts
|
||||
#
|
||||
@@ -132,7 +136,7 @@ then
|
||||
else
|
||||
set DO_AUTOCONFIG no
|
||||
fi
|
||||
|
||||
|
||||
#
|
||||
# Set USE_IO flag
|
||||
#
|
||||
@@ -142,7 +146,7 @@ then
|
||||
else
|
||||
set USE_IO no
|
||||
fi
|
||||
|
||||
|
||||
#
|
||||
# Set parameters and env variables for selected AUTOSTART
|
||||
#
|
||||
@@ -172,9 +176,9 @@ then
|
||||
param set SYS_AUTOCONFIG 0
|
||||
param save
|
||||
fi
|
||||
|
||||
|
||||
set IO_PRESENT no
|
||||
|
||||
|
||||
if [ $USE_IO == yes ]
|
||||
then
|
||||
#
|
||||
@@ -186,19 +190,19 @@ then
|
||||
else
|
||||
set IO_FILE /etc/extras/px4io-v1_default.bin
|
||||
fi
|
||||
|
||||
|
||||
if px4io checkcrc $IO_FILE
|
||||
then
|
||||
echo "[init] PX4IO CRC OK"
|
||||
echo "PX4IO CRC OK" >> $LOG_FILE
|
||||
|
||||
|
||||
set IO_PRESENT yes
|
||||
else
|
||||
echo "[init] Trying to update"
|
||||
echo "PX4IO Trying to update" >> $LOG_FILE
|
||||
|
||||
|
||||
tone_alarm MLL32CP8MB
|
||||
|
||||
|
||||
if px4io forceupdate 14662 $IO_FILE
|
||||
then
|
||||
usleep 500000
|
||||
@@ -207,7 +211,7 @@ then
|
||||
echo "[init] PX4IO CRC OK, update successful"
|
||||
echo "PX4IO CRC OK after updating" >> $LOG_FILE
|
||||
tone_alarm MLL8CDE
|
||||
|
||||
|
||||
set IO_PRESENT yes
|
||||
else
|
||||
echo "[init] ERROR: PX4IO update failed"
|
||||
@@ -220,14 +224,14 @@ then
|
||||
tone_alarm $TUNE_OUT_ERROR
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
if [ $IO_PRESENT == no ]
|
||||
then
|
||||
echo "[init] ERROR: PX4IO not found"
|
||||
tone_alarm $TUNE_OUT_ERROR
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
#
|
||||
# Set default output if not set
|
||||
#
|
||||
@@ -246,7 +250,7 @@ then
|
||||
# Need IO for output but it not present, disable output
|
||||
set OUTPUT_MODE none
|
||||
echo "[init] ERROR: PX4IO not found, disabling output"
|
||||
|
||||
|
||||
# Avoid using ttyS0 for MAVLink on FMUv1
|
||||
if ver hwcmp PX4FMU_V1
|
||||
then
|
||||
@@ -270,17 +274,17 @@ then
|
||||
|
||||
# Try to get an USB console
|
||||
nshterm /dev/ttyACM0 &
|
||||
|
||||
|
||||
#
|
||||
# Start the Commander (needs to be this early for in-air-restarts)
|
||||
#
|
||||
commander start
|
||||
|
||||
|
||||
#
|
||||
# Start primary output
|
||||
#
|
||||
set TTYS1_BUSY no
|
||||
|
||||
|
||||
# If OUTPUT_MODE == none then something is wrong with setup and we shouldn't try to enable output
|
||||
if [ $OUTPUT_MODE != none ]
|
||||
then
|
||||
@@ -296,7 +300,7 @@ then
|
||||
tone_alarm $TUNE_OUT_ERROR
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
if [ $OUTPUT_MODE == fmu -o $OUTPUT_MODE == ardrone ]
|
||||
then
|
||||
echo "[init] Use FMU as primary output"
|
||||
@@ -307,7 +311,7 @@ then
|
||||
echo "[init] ERROR: FMU mode_$FMU_MODE start failed"
|
||||
tone_alarm $TUNE_OUT_ERROR
|
||||
fi
|
||||
|
||||
|
||||
if ver hwcmp PX4FMU_V1
|
||||
then
|
||||
if [ $FMU_MODE == pwm -o $FMU_MODE == gpio ]
|
||||
@@ -320,7 +324,7 @@ then
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
if [ $OUTPUT_MODE == mkblctrl ]
|
||||
then
|
||||
echo "[init] Use MKBLCTRL as primary output"
|
||||
@@ -333,7 +337,7 @@ then
|
||||
then
|
||||
set MKBLCTRL_ARG "-mkmode +"
|
||||
fi
|
||||
|
||||
|
||||
if mkblctrl $MKBLCTRL_ARG
|
||||
then
|
||||
echo "[init] MKBLCTRL started"
|
||||
@@ -341,9 +345,9 @@ then
|
||||
echo "[init] ERROR: MKBLCTRL start failed"
|
||||
tone_alarm $TUNE_OUT_ERROR
|
||||
fi
|
||||
|
||||
|
||||
fi
|
||||
|
||||
|
||||
if [ $OUTPUT_MODE == hil ]
|
||||
then
|
||||
echo "[init] Use HIL as primary output"
|
||||
@@ -355,7 +359,7 @@ then
|
||||
tone_alarm $TUNE_OUT_ERROR
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
#
|
||||
# Start IO or FMU for RC PPM input if needed
|
||||
#
|
||||
@@ -382,7 +386,7 @@ then
|
||||
echo "[init] ERROR: FMU mode_$FMU_MODE start failed"
|
||||
tone_alarm $TUNE_OUT_ERROR
|
||||
fi
|
||||
|
||||
|
||||
if ver hwcmp PX4FMU_V1
|
||||
then
|
||||
if [ $FMU_MODE == pwm -o $FMU_MODE == gpio ]
|
||||
@@ -397,7 +401,7 @@ then
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
#
|
||||
# MAVLink
|
||||
#
|
||||
@@ -418,7 +422,7 @@ then
|
||||
fi
|
||||
|
||||
mavlink start $MAVLINK_FLAGS
|
||||
|
||||
|
||||
#
|
||||
# Sensors, Logging, GPS
|
||||
#
|
||||
@@ -429,7 +433,7 @@ then
|
||||
echo "[init] Start logging"
|
||||
sh /etc/init.d/rc.logging
|
||||
fi
|
||||
|
||||
|
||||
if [ $GPS == yes ]
|
||||
then
|
||||
echo "[init] Start GPS"
|
||||
@@ -439,7 +443,7 @@ then
|
||||
gps start -f
|
||||
else
|
||||
gps start
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
#
|
||||
@@ -456,24 +460,24 @@ then
|
||||
if [ $VEHICLE_TYPE == fw ]
|
||||
then
|
||||
echo "[init] Vehicle type: FIXED WING"
|
||||
|
||||
|
||||
if [ $MIXER == none ]
|
||||
then
|
||||
# Set default mixer for fixed wing if not defined
|
||||
set MIXER FMU_AERT
|
||||
fi
|
||||
|
||||
|
||||
if [ $MAV_TYPE == none ]
|
||||
then
|
||||
# Use MAV_TYPE = 1 (fixed wing) if not defined
|
||||
set MAV_TYPE 1
|
||||
fi
|
||||
|
||||
|
||||
param set MAV_TYPE $MAV_TYPE
|
||||
|
||||
|
||||
# Load mixer and configure outputs
|
||||
sh /etc/init.d/rc.interface
|
||||
|
||||
|
||||
# Start standard fixedwing apps
|
||||
if [ $LOAD_DEFAULT_APPS == yes ]
|
||||
then
|
||||
@@ -521,7 +525,7 @@ then
|
||||
set MAV_TYPE 14
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
# Still no MAV_TYPE found
|
||||
if [ $MAV_TYPE == none ]
|
||||
then
|
||||
@@ -529,10 +533,10 @@ then
|
||||
else
|
||||
param set MAV_TYPE $MAV_TYPE
|
||||
fi
|
||||
|
||||
|
||||
# Load mixer and configure outputs
|
||||
sh /etc/init.d/rc.interface
|
||||
|
||||
|
||||
# Start standard multicopter apps
|
||||
if [ $LOAD_DEFAULT_APPS == yes ]
|
||||
then
|
||||
|
||||
@@ -0,0 +1,154 @@
|
||||
PX4 mixer definitions
|
||||
=====================
|
||||
|
||||
Files in this directory implement example mixers that can be used as a basis
|
||||
for customisation, or for general testing purposes.
|
||||
|
||||
Mixer basics
|
||||
------------
|
||||
|
||||
Mixers combine control values from various sources (control tasks, user inputs,
|
||||
etc.) and produce output values suitable for controlling actuators; servos,
|
||||
motors, switches and so on.
|
||||
|
||||
An actuator derives its value from the combination of one or more control
|
||||
values. Each of the control values is scaled according to the actuator's
|
||||
configuration and then combined to produce the actuator value, which may then be
|
||||
further scaled to suit the specific output type.
|
||||
|
||||
Internally, all scaling is performed using floating point values. Inputs and
|
||||
outputs are clamped to the range -1.0 to 1.0.
|
||||
|
||||
control control control
|
||||
| | |
|
||||
v v v
|
||||
scale scale scale
|
||||
| | |
|
||||
| v |
|
||||
+-------> mix <------+
|
||||
|
|
||||
scale
|
||||
|
|
||||
v
|
||||
out
|
||||
|
||||
Scaling
|
||||
-------
|
||||
|
||||
Basic scalers provide linear scaling of the input to the output.
|
||||
|
||||
Each scaler allows the input value to be scaled independently for inputs
|
||||
greater/less than zero. An offset can be applied to the output, and lower and
|
||||
upper boundary constraints can be applied. Negative scaling factors cause the
|
||||
output to be inverted (negative input produces positive output).
|
||||
|
||||
Scaler pseudocode:
|
||||
|
||||
if (input < 0)
|
||||
output = (input * NEGATIVE_SCALE) + OFFSET
|
||||
else
|
||||
output = (input * POSITIVE_SCALE) + OFFSET
|
||||
|
||||
if (output < LOWER_LIMIT)
|
||||
output = LOWER_LIMIT
|
||||
if (output > UPPER_LIMIT)
|
||||
output = UPPER_LIMIT
|
||||
|
||||
Syntax
|
||||
------
|
||||
|
||||
Mixer definitions are text files; lines beginning with a single capital letter
|
||||
followed by a colon are significant. All other lines are ignored, meaning that
|
||||
explanatory text can be freely mixed with the definitions.
|
||||
|
||||
Each file may define more than one mixer; the allocation of mixers to actuators
|
||||
is specific to the device reading the mixer definition, and the number of
|
||||
actuator outputs generated by a mixer is specific to the mixer.
|
||||
|
||||
A mixer begins with a line of the form
|
||||
|
||||
<tag>: <mixer arguments>
|
||||
|
||||
The tag selects the mixer type; 'M' for a simple summing mixer, 'R' for a
|
||||
multirotor mixer, etc.
|
||||
|
||||
Null Mixer
|
||||
..........
|
||||
|
||||
A null mixer consumes no controls and generates a single actuator output whose
|
||||
value is always zero. Typically a null mixer is used as a placeholder in a
|
||||
collection of mixers in order to achieve a specific pattern of actuator outputs.
|
||||
|
||||
The null mixer definition has the form:
|
||||
|
||||
Z:
|
||||
|
||||
Simple Mixer
|
||||
............
|
||||
|
||||
A simple mixer combines zero or more control inputs into a single actuator
|
||||
output. Inputs are scaled, and the mixing function sums the result before
|
||||
applying an output scaler.
|
||||
|
||||
A simple mixer definition begins with:
|
||||
|
||||
M: <control count>
|
||||
O: <-ve scale> <+ve scale> <offset> <lower limit> <upper limit>
|
||||
|
||||
If <control count> is zero, the sum is effectively zero and the mixer will
|
||||
output a fixed value that is <offset> constrained by <lower limit> and <upper
|
||||
limit>.
|
||||
|
||||
The second line defines the output scaler with scaler parameters as discussed
|
||||
above. Whilst the calculations are performed as floating-point operations, the
|
||||
values stored in the definition file are scaled by a factor of 10000; i.e. an
|
||||
offset of -0.5 is encoded as -5000.
|
||||
|
||||
The definition continues with <control count> entries describing the control
|
||||
inputs and their scaling, in the form:
|
||||
|
||||
S: <group> <index> <-ve scale> <+ve scale> <offset> <lower limit> <upper limit>
|
||||
|
||||
The <group> value identifies the control group from which the scaler will read,
|
||||
and the <index> value an offset within that group. These values are specific to
|
||||
the device reading the mixer definition.
|
||||
|
||||
When used to mix vehicle controls, mixer group zero is the vehicle attitude
|
||||
control group, and index values zero through three are normally roll, pitch,
|
||||
yaw and thrust respectively.
|
||||
|
||||
The remaining fields on the line configure the control scaler with parameters as
|
||||
discussed above. Whilst the calculations are performed as floating-point
|
||||
operations, the values stored in the definition file are scaled by a factor of
|
||||
10000; i.e. an offset of -0.5 is encoded as -5000.
|
||||
|
||||
Multirotor Mixer
|
||||
................
|
||||
|
||||
The multirotor mixer combines four control inputs (roll, pitch, yaw, thrust)
|
||||
into a set of actuator outputs intended to drive motor speed controllers.
|
||||
|
||||
The mixer definition is a single line of the form:
|
||||
|
||||
R: <geometry> <roll scale> <pitch scale> <yaw scale> <deadband>
|
||||
|
||||
The supported geometries include:
|
||||
|
||||
4x - quadrotor in X configuration
|
||||
4+ - quadrotor in + configuration
|
||||
6x - hexcopter in X configuration
|
||||
6+ - hexcopter in + configuration
|
||||
8x - octocopter in X configuration
|
||||
8+ - octocopter in + configuration
|
||||
|
||||
Each of the roll, pitch and yaw scale values determine scaling of the roll,
|
||||
pitch and yaw controls relative to the thrust control. Whilst the calculations
|
||||
are performed as floating-point operations, the values stored in the definition
|
||||
file are scaled by a factor of 10000; i.e. an factor of 0.5 is encoded as 5000.
|
||||
|
||||
Roll, pitch and yaw inputs are expected to range from -1.0 to 1.0, whilst the
|
||||
thrust input ranges from 0.0 to 1.0. Output for each actuator is in the
|
||||
range -1.0 to 1.0.
|
||||
|
||||
In the case where an actuator saturates, all actuator values are rescaled so that
|
||||
the saturating actuator is limited to 1.0.
|
||||
@@ -40,6 +40,7 @@ MODULES += drivers/meas_airspeed
|
||||
MODULES += drivers/frsky_telemetry
|
||||
MODULES += modules/sensors
|
||||
MODULES += drivers/mkblctrl
|
||||
MODULES += drivers/pca8574
|
||||
|
||||
|
||||
# Needs to be burned to the ground and re-written; for now,
|
||||
|
||||
@@ -24,6 +24,7 @@ MODULES += drivers/lsm303d
|
||||
MODULES += drivers/l3gd20
|
||||
MODULES += drivers/hmc5883
|
||||
MODULES += drivers/ms5611
|
||||
MODULES += drivers/pca8574
|
||||
MODULES += systemcmds/perf
|
||||
MODULES += systemcmds/reboot
|
||||
MODULES += systemcmds/tests
|
||||
|
||||
@@ -504,8 +504,8 @@ CONFIG_MTD_BYTE_WRITE=y
|
||||
#
|
||||
# USART1 Configuration
|
||||
#
|
||||
CONFIG_USART1_RXBUFSIZE=256
|
||||
CONFIG_USART1_TXBUFSIZE=128
|
||||
CONFIG_USART1_RXBUFSIZE=300
|
||||
CONFIG_USART1_TXBUFSIZE=300
|
||||
CONFIG_USART1_BAUD=57600
|
||||
CONFIG_USART1_BITS=8
|
||||
CONFIG_USART1_PARITY=0
|
||||
@@ -528,8 +528,8 @@ CONFIG_USART2_OFLOWCONTROL=y
|
||||
#
|
||||
# UART5 Configuration
|
||||
#
|
||||
CONFIG_UART5_RXBUFSIZE=256
|
||||
CONFIG_UART5_TXBUFSIZE=128
|
||||
CONFIG_UART5_RXBUFSIZE=300
|
||||
CONFIG_UART5_TXBUFSIZE=300
|
||||
CONFIG_UART5_BAUD=57600
|
||||
CONFIG_UART5_BITS=8
|
||||
CONFIG_UART5_PARITY=0
|
||||
|
||||
@@ -268,6 +268,10 @@
|
||||
#define GPIO_SPI2_MOSI (GPIO_SPI2_MOSI_1|GPIO_SPEED_50MHz)
|
||||
#define GPIO_SPI2_SCK (GPIO_SPI2_SCK_2|GPIO_SPEED_50MHz)
|
||||
|
||||
#define GPIO_SPI4_MISO (GPIO_SPI4_MISO_1|GPIO_SPEED_50MHz)
|
||||
#define GPIO_SPI4_MOSI (GPIO_SPI4_MOSI_1|GPIO_SPEED_50MHz)
|
||||
#define GPIO_SPI4_SCK (GPIO_SPI4_SCK_1|GPIO_SPEED_50MHz)
|
||||
|
||||
/************************************************************************************
|
||||
* Public Data
|
||||
************************************************************************************/
|
||||
|
||||
@@ -235,7 +235,7 @@ CONFIG_STM32_SDIO=y
|
||||
CONFIG_STM32_SPI1=y
|
||||
CONFIG_STM32_SPI2=y
|
||||
# CONFIG_STM32_SPI3 is not set
|
||||
# CONFIG_STM32_SPI4 is not set
|
||||
CONFIG_STM32_SPI4=y
|
||||
# CONFIG_STM32_SPI5 is not set
|
||||
# CONFIG_STM32_SPI6 is not set
|
||||
CONFIG_STM32_SYSCFG=y
|
||||
|
||||
@@ -86,6 +86,7 @@ __BEGIN_DECLS
|
||||
#define GPIO_SPI_CS_SDCARD (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_50MHz|GPIO_OUTPUT_SET|GPIO_PORTA|GPIO_PIN4)
|
||||
|
||||
#define PX4_SPI_BUS_SENSORS 1
|
||||
#define PX4_SPI_BUS_EXT 2
|
||||
|
||||
/*
|
||||
* Use these in place of the spi_dev_e enumeration to
|
||||
@@ -98,7 +99,7 @@ __BEGIN_DECLS
|
||||
/*
|
||||
* Optional devices on IO's external port
|
||||
*/
|
||||
#define PX4_SPIDEV_ACCEL_MAG 2
|
||||
#define PX4_SPIDEV_ACCEL_MAG 2
|
||||
|
||||
/*
|
||||
* I2C busses
|
||||
|
||||
@@ -106,8 +106,11 @@ __BEGIN_DECLS
|
||||
#define GPIO_SPI_CS_BARO (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_SET|GPIO_PORTD|GPIO_PIN7)
|
||||
#define GPIO_SPI_CS_FRAM (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_SET|GPIO_PORTD|GPIO_PIN10)
|
||||
#define GPIO_SPI_CS_MPU (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_SET|GPIO_PORTC|GPIO_PIN2)
|
||||
#define GPIO_SPI_CS_EXT0 (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_50MHz|GPIO_OUTPUT_SET|GPIO_PORTE|GPIO_PIN4)
|
||||
#define GPIO_SPI_CS_EXT1 (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_50MHz|GPIO_OUTPUT_SET|GPIO_PORTC|GPIO_PIN14)
|
||||
|
||||
#define PX4_SPI_BUS_SENSORS 1
|
||||
#define PX4_SPI_BUS_EXT 4
|
||||
|
||||
/* Use these in place of the spi_dev_e enumeration to select a specific SPI device on SPI1 */
|
||||
#define PX4_SPIDEV_GYRO 1
|
||||
@@ -115,6 +118,10 @@ __BEGIN_DECLS
|
||||
#define PX4_SPIDEV_BARO 3
|
||||
#define PX4_SPIDEV_MPU 4
|
||||
|
||||
/* External bus */
|
||||
#define PX4_SPIDEV_EXT0 1
|
||||
#define PX4_SPIDEV_EXT1 2
|
||||
|
||||
/* I2C busses */
|
||||
#define PX4_I2C_BUS_EXPANSION 1
|
||||
#define PX4_I2C_BUS_LED 2
|
||||
|
||||
@@ -192,6 +192,7 @@ stm32_boardinitialize(void)
|
||||
|
||||
static struct spi_dev_s *spi1;
|
||||
static struct spi_dev_s *spi2;
|
||||
static struct spi_dev_s *spi4;
|
||||
static struct sdio_dev_s *sdio;
|
||||
|
||||
#include <math.h>
|
||||
@@ -305,6 +306,17 @@ __EXPORT int nsh_archinitialize(void)
|
||||
|
||||
message("[boot] Initialized SPI port 2 (RAMTRON FRAM)\n");
|
||||
|
||||
spi4 = up_spiinitialize(4);
|
||||
|
||||
/* Default SPI4 to 1MHz and de-assert the known chip selects. */
|
||||
SPI_SETFREQUENCY(spi4, 10000000);
|
||||
SPI_SETBITS(spi4, 8);
|
||||
SPI_SETMODE(spi4, SPIDEV_MODE3);
|
||||
SPI_SELECT(spi4, PX4_SPIDEV_EXT0, false);
|
||||
SPI_SELECT(spi4, PX4_SPIDEV_EXT1, false);
|
||||
|
||||
message("[boot] Initialized SPI port 4\n");
|
||||
|
||||
#ifdef CONFIG_MMCSD
|
||||
/* First, get an instance of the SDIO interface */
|
||||
|
||||
|
||||
@@ -94,6 +94,13 @@ __EXPORT void weak_function stm32_spiinitialize(void)
|
||||
stm32_configgpio(GPIO_SPI_CS_FRAM);
|
||||
stm32_gpiowrite(GPIO_SPI_CS_FRAM, 1);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_STM32_SPI4
|
||||
stm32_configgpio(GPIO_SPI_CS_EXT0);
|
||||
stm32_configgpio(GPIO_SPI_CS_EXT1);
|
||||
stm32_gpiowrite(GPIO_SPI_CS_EXT0, 1);
|
||||
stm32_gpiowrite(GPIO_SPI_CS_EXT1, 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
__EXPORT void stm32_spi1select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected)
|
||||
@@ -157,3 +164,31 @@ __EXPORT uint8_t stm32_spi2status(FAR struct spi_dev_s *dev, enum spi_dev_e devi
|
||||
return SPI_STATUS_PRESENT;
|
||||
}
|
||||
#endif
|
||||
|
||||
__EXPORT void stm32_spi4select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected)
|
||||
{
|
||||
/* SPI select is active low, so write !selected to select the device */
|
||||
|
||||
switch (devid) {
|
||||
case PX4_SPIDEV_EXT0:
|
||||
/* Making sure the other peripherals are not selected */
|
||||
stm32_gpiowrite(GPIO_SPI_CS_EXT0, !selected);
|
||||
stm32_gpiowrite(GPIO_SPI_CS_EXT1, 1);
|
||||
break;
|
||||
|
||||
case PX4_SPIDEV_EXT1:
|
||||
/* Making sure the other peripherals are not selected */
|
||||
stm32_gpiowrite(GPIO_SPI_CS_EXT1, !selected);
|
||||
stm32_gpiowrite(GPIO_SPI_CS_EXT0, 1);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
__EXPORT uint8_t stm32_spi4status(FAR struct spi_dev_s *dev, enum spi_dev_e devid)
|
||||
{
|
||||
return SPI_STATUS_PRESENT;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* Copyright (c) 2014 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 drv_io_expander.h
|
||||
*
|
||||
* IO expander device API
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
/*
|
||||
* ioctl() definitions
|
||||
*/
|
||||
|
||||
#define _IOXIOCBASE (0x2800)
|
||||
#define _IOXIOC(_n) (_IOC(_IOXIOCBASE, _n))
|
||||
|
||||
/** set a bitmask (non-blocking) */
|
||||
#define IOX_SET_MASK _IOXIOC(1)
|
||||
|
||||
/** get a bitmask (blocking) */
|
||||
#define IOX_GET_MASK _IOXIOC(2)
|
||||
|
||||
/** set device mode (non-blocking) */
|
||||
#define IOX_SET_MODE _IOXIOC(3)
|
||||
|
||||
/** set constant values (non-blocking) */
|
||||
#define IOX_SET_VALUE _IOXIOC(4)
|
||||
|
||||
/* ... to IOX_SET_VALUE + 8 */
|
||||
|
||||
/* enum passed to RGBLED_SET_MODE ioctl()*/
|
||||
enum IOX_MODE {
|
||||
IOX_MODE_OFF,
|
||||
IOX_MODE_ON,
|
||||
IOX_MODE_TEST_OUT
|
||||
};
|
||||
@@ -447,8 +447,8 @@ UBX::handle_message()
|
||||
gps_bin_nav_sol_packet_t *packet = (gps_bin_nav_sol_packet_t *) _rx_buffer;
|
||||
|
||||
_gps_position->fix_type = packet->gpsFix;
|
||||
_gps_position->s_variance_m_s = packet->sAcc;
|
||||
_gps_position->p_variance_m = packet->pAcc;
|
||||
_gps_position->s_variance_m_s = (float)packet->sAcc * 1e-2f; // from cm/s to m/s
|
||||
_gps_position->p_variance_m = (float)packet->pAcc * 1e-2f; // from cm to m
|
||||
_gps_position->timestamp_variance = hrt_absolute_time();
|
||||
|
||||
ret = 1;
|
||||
|
||||
@@ -880,7 +880,7 @@ LSM303D::mag_read(struct file *filp, char *buffer, size_t buflen)
|
||||
|
||||
/* manual measurement */
|
||||
_mag_reports->flush();
|
||||
measure();
|
||||
_mag->measure();
|
||||
|
||||
/* measurement will have generated a report, copy it out */
|
||||
if (_mag_reports->get(mrb))
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
#
|
||||
# PCA8574 driver for RGB LED
|
||||
#
|
||||
|
||||
MODULE_COMMAND = pca8574
|
||||
SRCS = pca8574.cpp
|
||||
@@ -0,0 +1,554 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* Copyright (c) 2012-2014 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 pca8574.cpp
|
||||
*
|
||||
* Driver for an 8 I/O controller (PC8574) connected via I2C.
|
||||
*
|
||||
* @author Lorenz Meier <lm@inf.ethz.ch>
|
||||
* @author Julian Oes <joes@student.ethz.ch>
|
||||
* @author Anton Babushkin <anton.babushkin@me.com>
|
||||
*/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <drivers/device/i2c.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include <nuttx/wqueue.h>
|
||||
|
||||
#include <systemlib/perf_counter.h>
|
||||
#include <systemlib/err.h>
|
||||
#include <systemlib/systemlib.h>
|
||||
|
||||
#include <board_config.h>
|
||||
|
||||
#include <drivers/drv_io_expander.h>
|
||||
|
||||
#define PCA8574_ONTIME 120
|
||||
#define PCA8574_OFFTIME 120
|
||||
#define PCA8574_DEVICE_PATH "/dev/pca8574"
|
||||
|
||||
#define ADDR 0x20 ///< I2C adress of PCA8574 (default, A0-A2 pulled to GND)
|
||||
|
||||
class PCA8574 : public device::I2C
|
||||
{
|
||||
public:
|
||||
PCA8574(int bus, int pca8574);
|
||||
virtual ~PCA8574();
|
||||
|
||||
|
||||
virtual int init();
|
||||
virtual int probe();
|
||||
virtual int info();
|
||||
virtual int ioctl(struct file *filp, int cmd, unsigned long arg);
|
||||
bool is_running() { return _running; }
|
||||
|
||||
private:
|
||||
work_s _work;
|
||||
|
||||
uint8_t _values_out;
|
||||
uint8_t _values_in;
|
||||
uint8_t _blinking;
|
||||
uint8_t _blink_phase;
|
||||
|
||||
enum IOX_MODE _mode;
|
||||
bool _running;
|
||||
int _led_interval;
|
||||
bool _should_run;
|
||||
bool _update_out;
|
||||
int _counter;
|
||||
|
||||
static void led_trampoline(void *arg);
|
||||
void led();
|
||||
|
||||
int send_led_enable(uint8_t arg);
|
||||
int send_led_values();
|
||||
|
||||
int get(uint8_t &vals);
|
||||
};
|
||||
|
||||
/* for now, we only support one PCA8574 */
|
||||
namespace
|
||||
{
|
||||
PCA8574 *g_pca8574;
|
||||
}
|
||||
|
||||
void pca8574_usage();
|
||||
|
||||
extern "C" __EXPORT int pca8574_main(int argc, char *argv[]);
|
||||
|
||||
PCA8574::PCA8574(int bus, int pca8574) :
|
||||
I2C("pca8574", PCA8574_DEVICE_PATH, bus, pca8574, 100000),
|
||||
_values_out(0),
|
||||
_values_in(0),
|
||||
_blinking(0),
|
||||
_blink_phase(0),
|
||||
_mode(IOX_MODE_OFF),
|
||||
_running(false),
|
||||
_led_interval(80),
|
||||
_should_run(false),
|
||||
_update_out(false),
|
||||
_counter(0)
|
||||
{
|
||||
memset(&_work, 0, sizeof(_work));
|
||||
}
|
||||
|
||||
PCA8574::~PCA8574()
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
PCA8574::init()
|
||||
{
|
||||
int ret;
|
||||
ret = I2C::init();
|
||||
|
||||
if (ret != OK) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int
|
||||
PCA8574::probe()
|
||||
{
|
||||
uint8_t val;
|
||||
return get(val);
|
||||
}
|
||||
|
||||
int
|
||||
PCA8574::info()
|
||||
{
|
||||
int ret = OK;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
PCA8574::ioctl(struct file *filp, int cmd, unsigned long arg)
|
||||
{
|
||||
int ret = ENOTTY;
|
||||
|
||||
switch (cmd) {
|
||||
case IOX_SET_VALUE ...(IOX_SET_VALUE + 8): {
|
||||
// set the specified on / off state
|
||||
uint8_t position = (1 << (cmd - IOX_SET_VALUE));
|
||||
uint8_t prev = _values_out;
|
||||
|
||||
if (arg) {
|
||||
_values_out |= position;
|
||||
|
||||
} else {
|
||||
_values_out &= ~(position);
|
||||
}
|
||||
|
||||
if (_values_out != prev) {
|
||||
if (_values_out) {
|
||||
_mode = IOX_MODE_ON;
|
||||
}
|
||||
send_led_values();
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
case IOX_SET_MASK:
|
||||
send_led_enable(arg);
|
||||
return OK;
|
||||
|
||||
case IOX_GET_MASK: {
|
||||
uint8_t val;
|
||||
ret = get(val);
|
||||
|
||||
if (ret == OK) {
|
||||
return val;
|
||||
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
case IOX_SET_MODE:
|
||||
|
||||
if (_mode != (IOX_MODE)arg) {
|
||||
|
||||
switch ((IOX_MODE)arg) {
|
||||
case IOX_MODE_OFF:
|
||||
_values_out = 0xFF;
|
||||
break;
|
||||
|
||||
case IOX_MODE_ON:
|
||||
_values_out = 0;
|
||||
break;
|
||||
|
||||
case IOX_MODE_TEST_OUT:
|
||||
break;
|
||||
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
_mode = (IOX_MODE)arg;
|
||||
send_led_values();
|
||||
}
|
||||
|
||||
return OK;
|
||||
|
||||
default:
|
||||
// see if the parent class can make any use of it
|
||||
ret = CDev::ioctl(filp, cmd, arg);
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PCA8574::led_trampoline(void *arg)
|
||||
{
|
||||
PCA8574 *rgbl = reinterpret_cast<PCA8574 *>(arg);
|
||||
|
||||
rgbl->led();
|
||||
}
|
||||
|
||||
/**
|
||||
* Main loop function
|
||||
*/
|
||||
void
|
||||
PCA8574::led()
|
||||
{
|
||||
if (_mode == IOX_MODE_TEST_OUT) {
|
||||
|
||||
// we count only seven states
|
||||
_counter &= 0xF;
|
||||
_counter++;
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
if (i < _counter) {
|
||||
_values_out |= (1 << i);
|
||||
|
||||
} else {
|
||||
_values_out &= ~(1 << i);
|
||||
}
|
||||
}
|
||||
|
||||
_update_out = true;
|
||||
_should_run = true;
|
||||
} else if (_mode == IOX_MODE_OFF) {
|
||||
_update_out = true;
|
||||
_should_run = false;
|
||||
} else {
|
||||
|
||||
// Any of the normal modes
|
||||
if (_blinking > 0) {
|
||||
/* we need to be running to blink */
|
||||
_should_run = true;
|
||||
} else {
|
||||
_should_run = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (_update_out) {
|
||||
uint8_t msg;
|
||||
|
||||
if (_blinking) {
|
||||
msg = (_values_out & _blinking & _blink_phase);
|
||||
|
||||
// wipe out all positions that are marked as blinking
|
||||
msg &= ~(_blinking);
|
||||
|
||||
// fill blink positions
|
||||
msg |= ((_blink_phase) ? _blinking : 0);
|
||||
|
||||
_blink_phase = !_blink_phase;
|
||||
} else {
|
||||
msg = _values_out;
|
||||
}
|
||||
|
||||
int ret = transfer(&msg, sizeof(msg), nullptr, 0);
|
||||
|
||||
if (!ret) {
|
||||
_update_out = false;
|
||||
}
|
||||
}
|
||||
|
||||
// check if any activity remains, else stp
|
||||
if (!_should_run) {
|
||||
_running = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// re-queue ourselves to run again later
|
||||
_running = true;
|
||||
work_queue(LPWORK, &_work, (worker_t)&PCA8574::led_trampoline, this, _led_interval);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sent ENABLE flag to LED driver
|
||||
*/
|
||||
int
|
||||
PCA8574::send_led_enable(uint8_t arg)
|
||||
{
|
||||
|
||||
int ret = transfer(&arg, sizeof(arg), nullptr, 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send 8 outputs
|
||||
*/
|
||||
int
|
||||
PCA8574::send_led_values()
|
||||
{
|
||||
_update_out = true;
|
||||
|
||||
// if not active, kick it
|
||||
if (!_running) {
|
||||
_running = true;
|
||||
work_queue(LPWORK, &_work, (worker_t)&PCA8574::led_trampoline, this, 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
PCA8574::get(uint8_t &vals)
|
||||
{
|
||||
uint8_t result;
|
||||
int ret;
|
||||
|
||||
ret = transfer(nullptr, 0, &result, 1);
|
||||
|
||||
if (ret == OK) {
|
||||
_values_in = result;
|
||||
vals = result;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
pca8574_usage()
|
||||
{
|
||||
warnx("missing command: try 'start', 'test', 'info', 'off', 'stop', 'val 0 1'");
|
||||
warnx("options:");
|
||||
warnx(" -b i2cbus (%d)", PX4_I2C_BUS_LED);
|
||||
warnx(" -a addr (0x%x)", ADDR);
|
||||
}
|
||||
|
||||
int
|
||||
pca8574_main(int argc, char *argv[])
|
||||
{
|
||||
int i2cdevice = -1;
|
||||
int pca8574adr = ADDR; // 7bit
|
||||
|
||||
int ch;
|
||||
|
||||
// jump over start/off/etc and look at options first
|
||||
while ((ch = getopt(argc, argv, "a:b:")) != EOF) {
|
||||
switch (ch) {
|
||||
case 'a':
|
||||
pca8574adr = strtol(optarg, NULL, 0);
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
i2cdevice = strtol(optarg, NULL, 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
pca8574_usage();
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
if (optind >= argc) {
|
||||
pca8574_usage();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
const char *verb = argv[optind];
|
||||
|
||||
int fd;
|
||||
int ret;
|
||||
|
||||
if (!strcmp(verb, "start")) {
|
||||
if (g_pca8574 != nullptr) {
|
||||
errx(1, "already started");
|
||||
}
|
||||
|
||||
if (i2cdevice == -1) {
|
||||
// try the external bus first
|
||||
i2cdevice = PX4_I2C_BUS_EXPANSION;
|
||||
g_pca8574 = new PCA8574(PX4_I2C_BUS_EXPANSION, pca8574adr);
|
||||
|
||||
if (g_pca8574 != nullptr && OK != g_pca8574->init()) {
|
||||
delete g_pca8574;
|
||||
g_pca8574 = nullptr;
|
||||
}
|
||||
|
||||
if (g_pca8574 == nullptr) {
|
||||
// fall back to default bus
|
||||
if (PX4_I2C_BUS_LED == PX4_I2C_BUS_EXPANSION) {
|
||||
errx(1, "init failed");
|
||||
}
|
||||
|
||||
i2cdevice = PX4_I2C_BUS_LED;
|
||||
}
|
||||
}
|
||||
|
||||
if (g_pca8574 == nullptr) {
|
||||
g_pca8574 = new PCA8574(i2cdevice, pca8574adr);
|
||||
|
||||
if (g_pca8574 == nullptr) {
|
||||
errx(1, "new failed");
|
||||
}
|
||||
|
||||
if (OK != g_pca8574->init()) {
|
||||
delete g_pca8574;
|
||||
g_pca8574 = nullptr;
|
||||
errx(1, "init failed");
|
||||
}
|
||||
}
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
// need the driver past this point
|
||||
if (g_pca8574 == nullptr) {
|
||||
warnx("not started, run pca8574 start");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!strcmp(verb, "test")) {
|
||||
fd = open(PCA8574_DEVICE_PATH, 0);
|
||||
|
||||
if (fd == -1) {
|
||||
errx(1, "Unable to open " PCA8574_DEVICE_PATH);
|
||||
}
|
||||
|
||||
ret = ioctl(fd, IOX_SET_MODE, (unsigned long)IOX_MODE_TEST_OUT);
|
||||
|
||||
close(fd);
|
||||
exit(ret);
|
||||
}
|
||||
|
||||
if (!strcmp(verb, "info")) {
|
||||
g_pca8574->info();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (!strcmp(verb, "off")) {
|
||||
fd = open(PCA8574_DEVICE_PATH, 0);
|
||||
|
||||
if (fd < 0) {
|
||||
errx(1, "Unable to open " PCA8574_DEVICE_PATH);
|
||||
}
|
||||
|
||||
ret = ioctl(fd, IOX_SET_MODE, (unsigned long)IOX_MODE_OFF);
|
||||
close(fd);
|
||||
exit(ret);
|
||||
}
|
||||
|
||||
if (!strcmp(verb, "stop")) {
|
||||
fd = open(PCA8574_DEVICE_PATH, 0);
|
||||
|
||||
if (fd == -1) {
|
||||
errx(1, "Unable to open " PCA8574_DEVICE_PATH);
|
||||
}
|
||||
|
||||
ret = ioctl(fd, IOX_SET_MODE, (unsigned long)IOX_MODE_OFF);
|
||||
close(fd);
|
||||
|
||||
// wait until we're not running any more
|
||||
for (unsigned i = 0; i < 15; i++) {
|
||||
if (!g_pca8574->is_running()) {
|
||||
break;
|
||||
}
|
||||
|
||||
usleep(50000);
|
||||
printf(".");
|
||||
fflush(stdout);
|
||||
}
|
||||
printf("\n");
|
||||
fflush(stdout);
|
||||
|
||||
if (!g_pca8574->is_running()) {
|
||||
delete g_pca8574;
|
||||
g_pca8574 = nullptr;
|
||||
exit(0);
|
||||
} else {
|
||||
warnx("stop failed.");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (!strcmp(verb, "val")) {
|
||||
if (argc < 4) {
|
||||
errx(1, "Usage: pca8574 val <channel> <0 or 1>");
|
||||
}
|
||||
|
||||
fd = open(PCA8574_DEVICE_PATH, 0);
|
||||
|
||||
if (fd == -1) {
|
||||
errx(1, "Unable to open " PCA8574_DEVICE_PATH);
|
||||
}
|
||||
|
||||
unsigned channel = strtol(argv[2], NULL, 0);
|
||||
unsigned val = strtol(argv[3], NULL, 0);
|
||||
|
||||
if (channel < 8) {
|
||||
ret = ioctl(fd, (IOX_SET_VALUE + channel), val);
|
||||
} else {
|
||||
ret = -1;
|
||||
}
|
||||
close(fd);
|
||||
exit(ret);
|
||||
}
|
||||
|
||||
pca8574_usage();
|
||||
exit(0);
|
||||
}
|
||||
@@ -1344,7 +1344,7 @@ int commander_thread_main(int argc, char *argv[])
|
||||
home.z = local_position.z;
|
||||
|
||||
warnx("home: lat = %.7f, lon = %.7f, alt = %.2f ", home.lat, home.lon, (double)home.alt);
|
||||
mavlink_log_info(mavlink_fd, "#audio: home: %.7f, %.7f, %.2f", home.lat, home.lon, (double)home.alt);
|
||||
mavlink_log_info(mavlink_fd, "home: %.7f, %.7f, %.2f", home.lat, home.lon, (double)home.alt);
|
||||
|
||||
/* announce new home position */
|
||||
if (home_pub > 0) {
|
||||
|
||||
@@ -105,7 +105,8 @@ static struct file_operations fops;
|
||||
*/
|
||||
extern "C" __EXPORT int mavlink_main(int argc, char *argv[]);
|
||||
|
||||
static uint64_t last_write_times[6] = {0};
|
||||
static uint64_t last_write_success_times[6] = {0};
|
||||
static uint64_t last_write_try_times[6] = {0};
|
||||
|
||||
/*
|
||||
* Internal function to send the bytes through the right serial port
|
||||
@@ -166,38 +167,40 @@ mavlink_send_uart_bytes(mavlink_channel_t channel, const uint8_t *ch, int length
|
||||
if (instance->get_flow_control_enabled()
|
||||
&& ioctl(uart, FIONWRITE, (unsigned long)&buf_free) == 0) {
|
||||
|
||||
if (buf_free == 0) {
|
||||
|
||||
if (last_write_times[(unsigned)channel] != 0 &&
|
||||
hrt_elapsed_time(&last_write_times[(unsigned)channel]) > 500 * 1000UL) {
|
||||
|
||||
warnx("DISABLING HARDWARE FLOW CONTROL");
|
||||
instance->enable_flow_control(false);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
/* apparently there is space left, although we might be
|
||||
* partially overflooding the buffer already */
|
||||
last_write_times[(unsigned)channel] = hrt_absolute_time();
|
||||
/* Disable hardware flow control:
|
||||
* if no successful write since a defined time
|
||||
* and if the last try was not the last successful write
|
||||
*/
|
||||
if (last_write_try_times[(unsigned)channel] != 0 &&
|
||||
hrt_elapsed_time(&last_write_success_times[(unsigned)channel]) > 500 * 1000UL &&
|
||||
last_write_success_times[(unsigned)channel] !=
|
||||
last_write_try_times[(unsigned)channel])
|
||||
{
|
||||
warnx("DISABLING HARDWARE FLOW CONTROL");
|
||||
instance->enable_flow_control(false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* If the wait until transmit flag is on, only transmit after we've received messages.
|
||||
Otherwise, transmit all the time. */
|
||||
if (instance->should_transmit()) {
|
||||
last_write_try_times[(unsigned)channel] = hrt_absolute_time();
|
||||
|
||||
/* check if there is space in the buffer, let it overflow else */
|
||||
if (!ioctl(uart, FIONWRITE, (unsigned long)&buf_free)) {
|
||||
|
||||
if (desired > buf_free) {
|
||||
desired = buf_free;
|
||||
if (buf_free < desired) {
|
||||
/* we don't want to send anything just in half, so return */
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ssize_t ret = write(uart, ch, desired);
|
||||
if (ret != desired) {
|
||||
warnx("TX FAIL");
|
||||
} else {
|
||||
last_write_success_times[(unsigned)channel] = last_write_try_times[(unsigned)channel];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -222,6 +225,8 @@ Mavlink::Mavlink() :
|
||||
_subscriptions(nullptr),
|
||||
_streams(nullptr),
|
||||
_mission_pub(-1),
|
||||
_mode(MAVLINK_MODE_NORMAL),
|
||||
_total_counter(0),
|
||||
_verbose(false),
|
||||
_forwarding_on(false),
|
||||
_passing_on(false),
|
||||
@@ -886,7 +891,7 @@ int Mavlink::map_mavlink_mission_item_to_mission_item(const mavlink_mission_item
|
||||
|
||||
switch (mavlink_mission_item->command) {
|
||||
case MAV_CMD_NAV_TAKEOFF:
|
||||
mission_item->pitch_min = mavlink_mission_item->param2;
|
||||
mission_item->pitch_min = mavlink_mission_item->param1;
|
||||
break;
|
||||
case MAV_CMD_DO_JUMP:
|
||||
mission_item->do_jump_mission_index = mavlink_mission_item->param1;
|
||||
@@ -894,6 +899,7 @@ int Mavlink::map_mavlink_mission_item_to_mission_item(const mavlink_mission_item
|
||||
break;
|
||||
default:
|
||||
mission_item->acceptance_radius = mavlink_mission_item->param2;
|
||||
mission_item->time_inside = mavlink_mission_item->param1;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -902,7 +908,6 @@ int Mavlink::map_mavlink_mission_item_to_mission_item(const mavlink_mission_item
|
||||
mission_item->loiter_direction = (mavlink_mission_item->param3 > 0) ? 1 : -1; /* 1 if positive CW, -1 if negative CCW */
|
||||
mission_item->nav_cmd = (NAV_CMD)mavlink_mission_item->command;
|
||||
|
||||
mission_item->time_inside = mavlink_mission_item->param1;
|
||||
mission_item->autocontinue = mavlink_mission_item->autocontinue;
|
||||
// mission_item->index = mavlink_mission_item->seq;
|
||||
mission_item->origin = ORIGIN_MAVLINK;
|
||||
@@ -924,7 +929,7 @@ int Mavlink::map_mission_item_to_mavlink_mission_item(const struct mission_item_
|
||||
|
||||
switch (mission_item->nav_cmd) {
|
||||
case NAV_CMD_TAKEOFF:
|
||||
mavlink_mission_item->param2 = mission_item->pitch_min;
|
||||
mavlink_mission_item->param1 = mission_item->pitch_min;
|
||||
break;
|
||||
|
||||
case NAV_CMD_DO_JUMP:
|
||||
@@ -934,6 +939,7 @@ int Mavlink::map_mission_item_to_mavlink_mission_item(const struct mission_item_
|
||||
|
||||
default:
|
||||
mavlink_mission_item->param2 = mission_item->acceptance_radius;
|
||||
mavlink_mission_item->param1 = mission_item->time_inside;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -944,7 +950,6 @@ int Mavlink::map_mission_item_to_mavlink_mission_item(const struct mission_item_
|
||||
mavlink_mission_item->param4 = mission_item->yaw * M_RAD_TO_DEG_F;
|
||||
mavlink_mission_item->param3 = mission_item->loiter_radius * (float)mission_item->loiter_direction;
|
||||
mavlink_mission_item->command = mission_item->nav_cmd;
|
||||
mavlink_mission_item->param1 = mission_item->time_inside;
|
||||
mavlink_mission_item->autocontinue = mission_item->autocontinue;
|
||||
// mavlink_mission_item->seq = mission_item->index;
|
||||
|
||||
|
||||
@@ -295,7 +295,7 @@ protected:
|
||||
status->onboard_control_sensors_health,
|
||||
status->load * 1000.0f,
|
||||
status->battery_voltage * 1000.0f,
|
||||
status->battery_current * 1000.0f,
|
||||
status->battery_current * 100.0f,
|
||||
status->battery_remaining * 100.0f,
|
||||
status->drop_rate_comm,
|
||||
status->errors_comm,
|
||||
|
||||
@@ -63,7 +63,7 @@ MissionFeasibilityChecker::MissionFeasibilityChecker() : _mavlink_fd(-1), _capab
|
||||
}
|
||||
|
||||
|
||||
bool MissionFeasibilityChecker::checkMissionFeasible(bool isRotarywing, dm_item_t dm_current, size_t nMissionItems, Geofence &geofence)
|
||||
bool MissionFeasibilityChecker::checkMissionFeasible(bool isRotarywing, dm_item_t dm_current, size_t nMissionItems, Geofence &geofence, float home_alt)
|
||||
{
|
||||
/* Init if not done yet */
|
||||
init();
|
||||
@@ -76,24 +76,24 @@ bool MissionFeasibilityChecker::checkMissionFeasible(bool isRotarywing, dm_item_
|
||||
|
||||
|
||||
if (isRotarywing)
|
||||
return checkMissionFeasibleRotarywing(dm_current, nMissionItems, geofence);
|
||||
return checkMissionFeasibleRotarywing(dm_current, nMissionItems, geofence, home_alt);
|
||||
else
|
||||
return checkMissionFeasibleFixedwing(dm_current, nMissionItems, geofence);
|
||||
return checkMissionFeasibleFixedwing(dm_current, nMissionItems, geofence, home_alt);
|
||||
}
|
||||
|
||||
bool MissionFeasibilityChecker::checkMissionFeasibleRotarywing(dm_item_t dm_current, size_t nMissionItems, Geofence &geofence)
|
||||
bool MissionFeasibilityChecker::checkMissionFeasibleRotarywing(dm_item_t dm_current, size_t nMissionItems, Geofence &geofence, float home_alt)
|
||||
{
|
||||
|
||||
return checkGeofence(dm_current, nMissionItems, geofence);
|
||||
return (checkGeofence(dm_current, nMissionItems, geofence) && checkHomePositionAltitude(dm_current, nMissionItems, home_alt));
|
||||
}
|
||||
|
||||
bool MissionFeasibilityChecker::checkMissionFeasibleFixedwing(dm_item_t dm_current, size_t nMissionItems, Geofence &geofence)
|
||||
bool MissionFeasibilityChecker::checkMissionFeasibleFixedwing(dm_item_t dm_current, size_t nMissionItems, Geofence &geofence, float home_alt)
|
||||
{
|
||||
/* Update fixed wing navigation capabilites */
|
||||
updateNavigationCapabilities();
|
||||
// warnx("_nav_caps.landing_slope_angle_rad %.4f, _nav_caps.landing_horizontal_slope_displacement %.4f", _nav_caps.landing_slope_angle_rad, _nav_caps.landing_horizontal_slope_displacement);
|
||||
|
||||
return (checkFixedWingLanding(dm_current, nMissionItems) && checkGeofence(dm_current, nMissionItems, geofence));
|
||||
return (checkFixedWingLanding(dm_current, nMissionItems) && checkGeofence(dm_current, nMissionItems, geofence) && checkHomePositionAltitude(dm_current, nMissionItems, home_alt));
|
||||
}
|
||||
|
||||
bool MissionFeasibilityChecker::checkGeofence(dm_item_t dm_current, size_t nMissionItems, Geofence &geofence)
|
||||
@@ -109,7 +109,7 @@ bool MissionFeasibilityChecker::checkGeofence(dm_item_t dm_current, size_t nMiss
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!geofence.inside(missionitem.lat, missionitem.lon, missionitem.altitude)) { //xxx: handle relative altitude
|
||||
if (!geofence.inside(missionitem.lat, missionitem.lon, missionitem.altitude)) {
|
||||
mavlink_log_info(_mavlink_fd, "#audio: Geofence violation waypoint %d", i);
|
||||
return false;
|
||||
}
|
||||
@@ -119,6 +119,36 @@ bool MissionFeasibilityChecker::checkGeofence(dm_item_t dm_current, size_t nMiss
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MissionFeasibilityChecker::checkHomePositionAltitude(dm_item_t dm_current, size_t nMissionItems, float home_alt, bool throw_error)
|
||||
{
|
||||
/* Check if all all waypoints are above the home altitude, only return false if bool throw_error = true */
|
||||
for (size_t i = 0; i < nMissionItems; i++) {
|
||||
static struct mission_item_s missionitem;
|
||||
const ssize_t len = sizeof(struct mission_item_s);
|
||||
|
||||
if (dm_read(dm_current, i, &missionitem, len) != len) {
|
||||
/* not supposed to happen unless the datamanager can't access the SD card, etc. */
|
||||
if (throw_error) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (home_alt > missionitem.altitude) {
|
||||
if (throw_error) {
|
||||
mavlink_log_info(_mavlink_fd, "Waypoint %d below home", i);
|
||||
return false;
|
||||
} else {
|
||||
mavlink_log_info(_mavlink_fd, "#audio: warning waypoint %d below home", i);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MissionFeasibilityChecker::checkFixedWingLanding(dm_item_t dm_current, size_t nMissionItems)
|
||||
{
|
||||
/* Go through all mission items and search for a landing waypoint
|
||||
|
||||
@@ -61,14 +61,15 @@ private:
|
||||
|
||||
/* Checks for all airframes */
|
||||
bool checkGeofence(dm_item_t dm_current, size_t nMissionItems, Geofence &geofence);
|
||||
bool checkHomePositionAltitude(dm_item_t dm_current, size_t nMissionItems, float home_alt, bool throw_error = false);
|
||||
|
||||
/* Checks specific to fixedwing airframes */
|
||||
bool checkMissionFeasibleFixedwing(dm_item_t dm_current, size_t nMissionItems, Geofence &geofence);
|
||||
bool checkMissionFeasibleFixedwing(dm_item_t dm_current, size_t nMissionItems, Geofence &geofence, float home_alt);
|
||||
bool checkFixedWingLanding(dm_item_t dm_current, size_t nMissionItems);
|
||||
void updateNavigationCapabilities();
|
||||
|
||||
/* Checks specific to rotarywing airframes */
|
||||
bool checkMissionFeasibleRotarywing(dm_item_t dm_current, size_t nMissionItems, Geofence &geofence);
|
||||
bool checkMissionFeasibleRotarywing(dm_item_t dm_current, size_t nMissionItems, Geofence &geofence, float home_alt);
|
||||
public:
|
||||
|
||||
MissionFeasibilityChecker();
|
||||
@@ -77,7 +78,7 @@ public:
|
||||
/*
|
||||
* Returns true if mission is feasible and false otherwise
|
||||
*/
|
||||
bool checkMissionFeasible(bool isRotarywing, dm_item_t dm_current, size_t nMissionItems, Geofence &geofence);
|
||||
bool checkMissionFeasible(bool isRotarywing, dm_item_t dm_current, size_t nMissionItems, Geofence &geofence, float home_alt);
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -674,11 +674,10 @@ Navigator::check_mission_item_reached()
|
||||
return _vstatus.condition_landed;
|
||||
}
|
||||
|
||||
/* TODO: count turns */
|
||||
// if ((_mission_item.nav_cmd == NAV_CMD_LOITER_TURN_COUNT ||
|
||||
// _mission_item.nav_cmd == NAV_CMD_LOITER_TIME_LIMIT ||
|
||||
// _mission_item.nav_cmd == NAV_CMD_LOITER_UNLIMITED) &&
|
||||
// _mission_item.loiter_radius > 0.01f) {
|
||||
/* XXX TODO count turns */
|
||||
if ((_mission_item.nav_cmd == NAV_CMD_LOITER_TURN_COUNT ||
|
||||
_mission_item.nav_cmd == NAV_CMD_LOITER_UNLIMITED) &&
|
||||
_mission_item.loiter_radius > 0.01f) {
|
||||
|
||||
// return false;
|
||||
// }
|
||||
@@ -695,24 +694,26 @@ Navigator::check_mission_item_reached()
|
||||
acceptance_radius = _parameters.acceptance_radius;
|
||||
}
|
||||
|
||||
float dist = -1.0f;
|
||||
float dist_xy = -1.0f;
|
||||
float dist_z = -1.0f;
|
||||
|
||||
float altitude_amsl = _mission_item.altitude_is_relative
|
||||
? _mission_item.altitude + _home_pos.alt : _mission_item.altitude;
|
||||
|
||||
dist = get_distance_to_point_global_wgs84(_mission_item.lat, _mission_item.lon, altitude_amsl,
|
||||
_global_pos.lat, _global_pos.lon, _global_pos.alt,
|
||||
&dist_xy, &dist_z);
|
||||
|
||||
if (_mission_item.nav_cmd == NAV_CMD_TAKEOFF) {
|
||||
|
||||
if (_do_takeoff) {
|
||||
/* require only altitude for takeoff */
|
||||
if (_global_pos.alt > altitude_amsl - acceptance_radius) {
|
||||
if (_global_pos.alt > _pos_sp_triplet.current.alt - acceptance_radius) {
|
||||
_waypoint_position_reached = true;
|
||||
}
|
||||
} else {
|
||||
float dist = -1.0f;
|
||||
float dist_xy = -1.0f;
|
||||
float dist_z = -1.0f;
|
||||
|
||||
/* calculate AMSL altitude for this waypoint */
|
||||
float wp_alt_amsl = _mission_item.altitude;
|
||||
|
||||
if (_mission_item.altitude_is_relative)
|
||||
wp_alt_amsl += _home_pos.alt;
|
||||
|
||||
dist = get_distance_to_point_global_wgs84(_mission_item.lat, _mission_item.lon, wp_alt_amsl,
|
||||
(double)_global_pos.lat, (double)_global_pos.lon, _global_pos.alt,
|
||||
&dist_xy, &dist_z);
|
||||
|
||||
if (dist >= 0.0f && dist <= acceptance_radius) {
|
||||
_waypoint_position_reached = true;
|
||||
}
|
||||
@@ -765,7 +766,6 @@ Navigator::reset_reached()
|
||||
_waypoint_yaw_reached = false;
|
||||
|
||||
}
|
||||
#endif
|
||||
void
|
||||
Navigator::publish_position_setpoint_triplet()
|
||||
{
|
||||
|
||||
@@ -9,15 +9,18 @@
|
||||
|
||||
#include "inertial_filter.h"
|
||||
|
||||
void inertial_filter_predict(float dt, float x[3])
|
||||
void inertial_filter_predict(float dt, float x[2], float acc)
|
||||
{
|
||||
if (isfinite(dt)) {
|
||||
x[0] += x[1] * dt + x[2] * dt * dt / 2.0f;
|
||||
x[1] += x[2] * dt;
|
||||
if (!isfinite(acc)) {
|
||||
acc = 0.0f;
|
||||
}
|
||||
x[0] += x[1] * dt + acc * dt * dt / 2.0f;
|
||||
x[1] += acc * dt;
|
||||
}
|
||||
}
|
||||
|
||||
void inertial_filter_correct(float e, float dt, float x[3], int i, float w)
|
||||
void inertial_filter_correct(float e, float dt, float x[2], int i, float w)
|
||||
{
|
||||
if (isfinite(e) && isfinite(w) && isfinite(dt)) {
|
||||
float ewdt = e * w * dt;
|
||||
@@ -25,10 +28,6 @@ void inertial_filter_correct(float e, float dt, float x[3], int i, float w)
|
||||
|
||||
if (i == 0) {
|
||||
x[1] += w * ewdt;
|
||||
x[2] += w * w * ewdt / 3.0;
|
||||
|
||||
} else if (i == 1) {
|
||||
x[2] += w * ewdt;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,6 @@
|
||||
#include <stdbool.h>
|
||||
#include <drivers/drv_hrt.h>
|
||||
|
||||
void inertial_filter_predict(float dt, float x[3]);
|
||||
void inertial_filter_predict(float dt, float x[3], float acc);
|
||||
|
||||
void inertial_filter_correct(float e, float dt, float x[3], int i, float w);
|
||||
|
||||
@@ -168,15 +168,15 @@ int position_estimator_inav_main(int argc, char *argv[])
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void write_debug_log(const char *msg, float dt, float x_est[3], float y_est[3], float z_est[3], float x_est_prev[3], float y_est_prev[3], float z_est_prev[3], float corr_acc[3], float corr_gps[3][2], float w_xy_gps_p, float w_xy_gps_v)
|
||||
void write_debug_log(const char *msg, float dt, float x_est[2], float y_est[2], float z_est[2], float x_est_prev[2], float y_est_prev[2], float z_est_prev[2], float acc[3], float corr_gps[3][2], float w_xy_gps_p, float w_xy_gps_v)
|
||||
{
|
||||
FILE *f = fopen("/fs/microsd/inav.log", "a");
|
||||
|
||||
if (f) {
|
||||
char *s = malloc(256);
|
||||
unsigned n = snprintf(s, 256, "%llu %s\n\tdt=%.5f x_est=[%.5f %.5f %.5f] y_est=[%.5f %.5f %.5f] z_est=[%.5f %.5f %.5f] x_est_prev=[%.5f %.5f %.5f] y_est_prev=[%.5f %.5f %.5f] z_est_prev=[%.5f %.5f %.5f]\n", hrt_absolute_time(), msg, dt, x_est[0], x_est[1], x_est[2], y_est[0], y_est[1], y_est[2], z_est[0], z_est[1], z_est[2], x_est_prev[0], x_est_prev[1], x_est_prev[2], y_est_prev[0], y_est_prev[1], y_est_prev[2], z_est_prev[0], z_est_prev[1], z_est_prev[2]);
|
||||
unsigned n = snprintf(s, 256, "%llu %s\n\tdt=%.5f x_est=[%.5f %.5f] y_est=[%.5f %.5f] z_est=[%.5f %.5f] x_est_prev=[%.5f %.5f] y_est_prev=[%.5f %.5f] z_est_prev=[%.5f %.5f]\n", hrt_absolute_time(), msg, dt, x_est[0], x_est[1], y_est[0], y_est[1], z_est[0], z_est[1], x_est_prev[0], x_est_prev[1], y_est_prev[0], y_est_prev[1], z_est_prev[0], z_est_prev[1]);
|
||||
fwrite(s, 1, n, f);
|
||||
n = snprintf(s, 256, "\tacc_corr=[%.5f %.5f %.5f] gps_pos_corr=[%.5f %.5f %.5f] gps_vel_corr=[%.5f %.5f %.5f] w_xy_gps_p=%.5f w_xy_gps_v=%.5f\n", corr_acc[0], corr_acc[1], corr_acc[2], corr_gps[0][0], corr_gps[1][0], corr_gps[2][0], corr_gps[0][1], corr_gps[1][1], corr_gps[2][1], w_xy_gps_p, w_xy_gps_v);
|
||||
n = snprintf(s, 256, "\tacc=[%.5f %.5f %.5f] gps_pos_corr=[%.5f %.5f %.5f] gps_vel_corr=[%.5f %.5f %.5f] w_xy_gps_p=%.5f w_xy_gps_v=%.5f\n", acc[0], acc[1], acc[2], corr_gps[0][0], corr_gps[1][0], corr_gps[2][0], corr_gps[0][1], corr_gps[1][1], corr_gps[2][1], w_xy_gps_p, w_xy_gps_v);
|
||||
fwrite(s, 1, n, f);
|
||||
free(s);
|
||||
}
|
||||
@@ -195,14 +195,14 @@ int position_estimator_inav_thread_main(int argc, char *argv[])
|
||||
mavlink_fd = open(MAVLINK_LOG_DEVICE, 0);
|
||||
mavlink_log_info(mavlink_fd, "[inav] started");
|
||||
|
||||
float x_est[3] = { 0.0f, 0.0f, 0.0f };
|
||||
float y_est[3] = { 0.0f, 0.0f, 0.0f };
|
||||
float z_est[3] = { 0.0f, 0.0f, 0.0f };
|
||||
float x_est[2] = { 0.0f, 0.0f }; // pos, vel
|
||||
float y_est[2] = { 0.0f, 0.0f }; // pos, vel
|
||||
float z_est[2] = { 0.0f, 0.0f }; // pos, vel
|
||||
|
||||
float eph = 1.0;
|
||||
float epv = 1.0;
|
||||
|
||||
float x_est_prev[3], y_est_prev[3], z_est_prev[3];
|
||||
float x_est_prev[2], y_est_prev[2], z_est_prev[2];
|
||||
memset(x_est_prev, 0, sizeof(x_est_prev));
|
||||
memset(y_est_prev, 0, sizeof(y_est_prev));
|
||||
memset(z_est_prev, 0, sizeof(z_est_prev));
|
||||
@@ -241,7 +241,7 @@ int position_estimator_inav_thread_main(int argc, char *argv[])
|
||||
float accel_NED[3] = { 0.0f, 0.0f, -CONSTANTS_ONE_G };
|
||||
|
||||
/* store error when sensor updates, but correct on each time step to avoid jumps in estimated value */
|
||||
float corr_acc[] = { 0.0f, 0.0f, 0.0f }; // N E D
|
||||
float acc[] = { 0.0f, 0.0f, 0.0f }; // N E D
|
||||
float acc_bias[] = { 0.0f, 0.0f, 0.0f }; // body frame
|
||||
float corr_baro = 0.0f; // D
|
||||
float corr_gps[3][2] = {
|
||||
@@ -341,8 +341,10 @@ int position_estimator_inav_thread_main(int argc, char *argv[])
|
||||
|
||||
/* mean calculation over several measurements */
|
||||
if (baro_init_cnt < baro_init_num) {
|
||||
baro_offset += sensor.baro_alt_meter;
|
||||
baro_init_cnt++;
|
||||
if (isfinite(sensor.baro_alt_meter)) {
|
||||
baro_offset += sensor.baro_alt_meter;
|
||||
baro_init_cnt++;
|
||||
}
|
||||
|
||||
} else {
|
||||
wait_baro = false;
|
||||
@@ -418,19 +420,17 @@ int position_estimator_inav_thread_main(int argc, char *argv[])
|
||||
|
||||
/* transform acceleration vector from body frame to NED frame */
|
||||
for (int i = 0; i < 3; i++) {
|
||||
accel_NED[i] = 0.0f;
|
||||
acc[i] = 0.0f;
|
||||
|
||||
for (int j = 0; j < 3; j++) {
|
||||
accel_NED[i] += att.R[i][j] * sensor.accelerometer_m_s2[j];
|
||||
acc[i] += att.R[i][j] * sensor.accelerometer_m_s2[j];
|
||||
}
|
||||
}
|
||||
|
||||
corr_acc[0] = accel_NED[0] - x_est[2];
|
||||
corr_acc[1] = accel_NED[1] - y_est[2];
|
||||
corr_acc[2] = accel_NED[2] + CONSTANTS_ONE_G - z_est[2];
|
||||
acc[2] += CONSTANTS_ONE_G;
|
||||
|
||||
} else {
|
||||
memset(corr_acc, 0, sizeof(corr_acc));
|
||||
memset(acc, 0, sizeof(acc));
|
||||
}
|
||||
|
||||
accel_timestamp = sensor.accelerometer_timestamp;
|
||||
@@ -628,11 +628,9 @@ int position_estimator_inav_thread_main(int argc, char *argv[])
|
||||
/* set position estimate to (0, 0, 0), use GPS velocity for XY */
|
||||
x_est[0] = 0.0f;
|
||||
x_est[1] = gps.vel_n_m_s;
|
||||
x_est[2] = accel_NED[0];
|
||||
y_est[0] = 0.0f;
|
||||
y_est[1] = gps.vel_e_m_s;
|
||||
z_est[0] = 0.0f;
|
||||
y_est[2] = accel_NED[1];
|
||||
|
||||
local_pos.ref_lat = lat;
|
||||
local_pos.ref_lon = lon;
|
||||
@@ -655,10 +653,8 @@ int position_estimator_inav_thread_main(int argc, char *argv[])
|
||||
if (reset_est) {
|
||||
x_est[0] = gps_proj[0];
|
||||
x_est[1] = gps.vel_n_m_s;
|
||||
x_est[2] = accel_NED[0];
|
||||
y_est[0] = gps_proj[1];
|
||||
y_est[1] = gps.vel_e_m_s;
|
||||
y_est[2] = accel_NED[1];
|
||||
}
|
||||
|
||||
/* calculate correction for position */
|
||||
@@ -796,26 +792,26 @@ int position_estimator_inav_thread_main(int argc, char *argv[])
|
||||
c += att.R[j][i] * accel_bias_corr[j];
|
||||
}
|
||||
|
||||
acc_bias[i] += c * params.w_acc_bias * dt;
|
||||
if (isfinite(c)) {
|
||||
acc_bias[i] += c * params.w_acc_bias * dt;
|
||||
}
|
||||
}
|
||||
|
||||
/* inertial filter prediction for altitude */
|
||||
inertial_filter_predict(dt, z_est);
|
||||
inertial_filter_predict(dt, z_est, acc[2]);
|
||||
|
||||
if (!(isfinite(z_est[0]) && isfinite(z_est[1]) && isfinite(z_est[2]))) {
|
||||
write_debug_log("BAD ESTIMATE AFTER Z PREDICTION", dt, x_est, y_est, z_est, x_est_prev, y_est_prev, z_est_prev, corr_acc, corr_gps, w_xy_gps_p, w_xy_gps_v);
|
||||
if (!(isfinite(z_est[0]) && isfinite(z_est[1]))) {
|
||||
write_debug_log("BAD ESTIMATE AFTER Z PREDICTION", dt, x_est, y_est, z_est, x_est_prev, y_est_prev, z_est_prev, acc, corr_gps, w_xy_gps_p, w_xy_gps_v);
|
||||
memcpy(z_est, z_est_prev, sizeof(z_est));
|
||||
}
|
||||
|
||||
/* inertial filter correction for altitude */
|
||||
inertial_filter_correct(corr_baro, dt, z_est, 0, params.w_z_baro);
|
||||
inertial_filter_correct(corr_gps[2][0], dt, z_est, 0, w_z_gps_p);
|
||||
inertial_filter_correct(corr_acc[2], dt, z_est, 2, params.w_z_acc);
|
||||
|
||||
if (!(isfinite(z_est[0]) && isfinite(z_est[1]) && isfinite(z_est[2]))) {
|
||||
write_debug_log("BAD ESTIMATE AFTER Z CORRECTION", dt, x_est, y_est, z_est, x_est_prev, y_est_prev, z_est_prev, corr_acc, corr_gps, w_xy_gps_p, w_xy_gps_v);
|
||||
if (!(isfinite(z_est[0]) && isfinite(z_est[1]))) {
|
||||
write_debug_log("BAD ESTIMATE AFTER Z CORRECTION", dt, x_est, y_est, z_est, x_est_prev, y_est_prev, z_est_prev, acc, corr_gps, w_xy_gps_p, w_xy_gps_v);
|
||||
memcpy(z_est, z_est_prev, sizeof(z_est));
|
||||
memset(corr_acc, 0, sizeof(corr_acc));
|
||||
memset(corr_gps, 0, sizeof(corr_gps));
|
||||
corr_baro = 0;
|
||||
|
||||
@@ -825,19 +821,16 @@ int position_estimator_inav_thread_main(int argc, char *argv[])
|
||||
|
||||
if (can_estimate_xy) {
|
||||
/* inertial filter prediction for position */
|
||||
inertial_filter_predict(dt, x_est);
|
||||
inertial_filter_predict(dt, y_est);
|
||||
inertial_filter_predict(dt, x_est, acc[0]);
|
||||
inertial_filter_predict(dt, y_est, acc[1]);
|
||||
|
||||
if (!(isfinite(x_est[0]) && isfinite(x_est[1]) && isfinite(x_est[2]) && isfinite(y_est[0]) && isfinite(y_est[1]) && isfinite(y_est[2]))) {
|
||||
write_debug_log("BAD ESTIMATE AFTER PREDICTION", dt, x_est, y_est, z_est, x_est_prev, y_est_prev, z_est_prev, corr_acc, corr_gps, w_xy_gps_p, w_xy_gps_v);
|
||||
if (!(isfinite(x_est[0]) && isfinite(x_est[1]) && isfinite(y_est[0]) && isfinite(y_est[1]))) {
|
||||
write_debug_log("BAD ESTIMATE AFTER PREDICTION", dt, x_est, y_est, z_est, x_est_prev, y_est_prev, z_est_prev, acc, corr_gps, w_xy_gps_p, w_xy_gps_v);
|
||||
memcpy(x_est, x_est_prev, sizeof(x_est));
|
||||
memcpy(y_est, y_est_prev, sizeof(y_est));
|
||||
}
|
||||
|
||||
/* inertial filter correction for position */
|
||||
inertial_filter_correct(corr_acc[0], dt, x_est, 2, params.w_xy_acc);
|
||||
inertial_filter_correct(corr_acc[1], dt, y_est, 2, params.w_xy_acc);
|
||||
|
||||
if (use_flow) {
|
||||
inertial_filter_correct(corr_flow[0], dt, x_est, 1, params.w_xy_flow * w_flow);
|
||||
inertial_filter_correct(corr_flow[1], dt, y_est, 1, params.w_xy_flow * w_flow);
|
||||
@@ -853,11 +846,10 @@ int position_estimator_inav_thread_main(int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
|
||||
if (!(isfinite(x_est[0]) && isfinite(x_est[1]) && isfinite(x_est[2]) && isfinite(y_est[0]) && isfinite(y_est[1]) && isfinite(y_est[2]))) {
|
||||
write_debug_log("BAD ESTIMATE AFTER CORRECTION", dt, x_est, y_est, z_est, x_est_prev, y_est_prev, z_est_prev, corr_acc, corr_gps, w_xy_gps_p, w_xy_gps_v);
|
||||
if (!(isfinite(x_est[0]) && isfinite(x_est[1]) && isfinite(y_est[0]) && isfinite(y_est[1]))) {
|
||||
write_debug_log("BAD ESTIMATE AFTER CORRECTION", dt, x_est, y_est, z_est, x_est_prev, y_est_prev, z_est_prev, acc, corr_gps, w_xy_gps_p, w_xy_gps_v);
|
||||
memcpy(x_est, x_est_prev, sizeof(x_est));
|
||||
memcpy(y_est, y_est_prev, sizeof(y_est));
|
||||
memset(corr_acc, 0, sizeof(corr_acc));
|
||||
memset(corr_gps, 0, sizeof(corr_gps));
|
||||
memset(corr_flow, 0, sizeof(corr_flow));
|
||||
|
||||
|
||||
@@ -42,11 +42,9 @@
|
||||
|
||||
PARAM_DEFINE_FLOAT(INAV_W_Z_BARO, 0.5f);
|
||||
PARAM_DEFINE_FLOAT(INAV_W_Z_GPS_P, 0.005f);
|
||||
PARAM_DEFINE_FLOAT(INAV_W_Z_ACC, 20.0f);
|
||||
PARAM_DEFINE_FLOAT(INAV_W_Z_SONAR, 3.0f);
|
||||
PARAM_DEFINE_FLOAT(INAV_W_XY_GPS_P, 1.0f);
|
||||
PARAM_DEFINE_FLOAT(INAV_W_XY_GPS_V, 2.0f);
|
||||
PARAM_DEFINE_FLOAT(INAV_W_XY_ACC, 20.0f);
|
||||
PARAM_DEFINE_FLOAT(INAV_W_XY_FLOW, 5.0f);
|
||||
PARAM_DEFINE_FLOAT(INAV_W_GPS_FLOW, 0.1f);
|
||||
PARAM_DEFINE_FLOAT(INAV_W_ACC_BIAS, 0.05f);
|
||||
@@ -62,11 +60,9 @@ int parameters_init(struct position_estimator_inav_param_handles *h)
|
||||
{
|
||||
h->w_z_baro = param_find("INAV_W_Z_BARO");
|
||||
h->w_z_gps_p = param_find("INAV_W_Z_GPS_P");
|
||||
h->w_z_acc = param_find("INAV_W_Z_ACC");
|
||||
h->w_z_sonar = param_find("INAV_W_Z_SONAR");
|
||||
h->w_xy_gps_p = param_find("INAV_W_XY_GPS_P");
|
||||
h->w_xy_gps_v = param_find("INAV_W_XY_GPS_V");
|
||||
h->w_xy_acc = param_find("INAV_W_XY_ACC");
|
||||
h->w_xy_flow = param_find("INAV_W_XY_FLOW");
|
||||
h->w_gps_flow = param_find("INAV_W_GPS_FLOW");
|
||||
h->w_acc_bias = param_find("INAV_W_ACC_BIAS");
|
||||
@@ -85,11 +81,9 @@ int parameters_update(const struct position_estimator_inav_param_handles *h, str
|
||||
{
|
||||
param_get(h->w_z_baro, &(p->w_z_baro));
|
||||
param_get(h->w_z_gps_p, &(p->w_z_gps_p));
|
||||
param_get(h->w_z_acc, &(p->w_z_acc));
|
||||
param_get(h->w_z_sonar, &(p->w_z_sonar));
|
||||
param_get(h->w_xy_gps_p, &(p->w_xy_gps_p));
|
||||
param_get(h->w_xy_gps_v, &(p->w_xy_gps_v));
|
||||
param_get(h->w_xy_acc, &(p->w_xy_acc));
|
||||
param_get(h->w_xy_flow, &(p->w_xy_flow));
|
||||
param_get(h->w_gps_flow, &(p->w_gps_flow));
|
||||
param_get(h->w_acc_bias, &(p->w_acc_bias));
|
||||
|
||||
@@ -43,11 +43,9 @@
|
||||
struct position_estimator_inav_params {
|
||||
float w_z_baro;
|
||||
float w_z_gps_p;
|
||||
float w_z_acc;
|
||||
float w_z_sonar;
|
||||
float w_xy_gps_p;
|
||||
float w_xy_gps_v;
|
||||
float w_xy_acc;
|
||||
float w_xy_flow;
|
||||
float w_gps_flow;
|
||||
float w_acc_bias;
|
||||
@@ -63,11 +61,9 @@ struct position_estimator_inav_params {
|
||||
struct position_estimator_inav_param_handles {
|
||||
param_t w_z_baro;
|
||||
param_t w_z_gps_p;
|
||||
param_t w_z_acc;
|
||||
param_t w_z_sonar;
|
||||
param_t w_xy_gps_p;
|
||||
param_t w_xy_gps_v;
|
||||
param_t w_xy_acc;
|
||||
param_t w_xy_flow;
|
||||
param_t w_gps_flow;
|
||||
param_t w_acc_bias;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* Copyright (C) 2013 PX4 Development Team. All rights reserved.
|
||||
* Copyright (c) 2013 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
|
||||
@@ -44,15 +44,25 @@
|
||||
#include <stdint.h>
|
||||
#include "../uORB.h"
|
||||
|
||||
/**
|
||||
* @addtogroup topics
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** global 'actuator output is live' control. */
|
||||
struct actuator_armed_s {
|
||||
|
||||
uint64_t timestamp;
|
||||
bool armed; /**< Set to true if system is armed */
|
||||
bool ready_to_arm; /**< Set to true if system is ready to be armed */
|
||||
bool lockdown; /**< Set to true if actuators are forced to being disabled (due to emergency or HIL) */
|
||||
uint64_t timestamp; /**< Microseconds since system boot */
|
||||
bool armed; /**< Set to true if system is armed */
|
||||
bool ready_to_arm; /**< Set to true if system is ready to be armed */
|
||||
bool lockdown; /**< Set to true if actuators are forced to being disabled (due to emergency or HIL) */
|
||||
};
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* register this as object request broker structure */
|
||||
ORB_DECLARE(actuator_armed);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user