aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoman Bapst <romanbapst@yahoo.de>2015-04-30 13:50:40 +0200
committerRoman Bapst <romanbapst@yahoo.de>2015-04-30 13:50:40 +0200
commitaa5e69984e43489db06768a92b27c38f3bcca94a (patch)
tree140c1d93f06d38a024dfaf88b9a7a778481c00ef
parenteb8617ade3b41011686493d838f8c2a2acbb6ea7 (diff)
parent2a46e0f0b6a9521015e05b87209de7f9604b9205 (diff)
downloadpx4-firmware-aa5e69984e43489db06768a92b27c38f3bcca94a.tar.gz
px4-firmware-aa5e69984e43489db06768a92b27c38f3bcca94a.tar.bz2
px4-firmware-aa5e69984e43489db06768a92b27c38f3bcca94a.zip
Merge branch 'master' into quad_vtol
-rw-r--r--.travis.yml55
-rw-r--r--Documentation/rc_mode_switch.odgbin33043 -> 35502 bytes
-rw-r--r--Documentation/rc_mode_switch.pdfbin26949 -> 31998 bytes
-rw-r--r--Images/px4-stm32f4discovery.prototype12
m---------NuttX0
-rw-r--r--ROMFS/px4fmu_common/init.d/13002_firefly611
-rw-r--r--ROMFS/px4fmu_common/init.d/rc.interface17
-rw-r--r--ROMFS/px4fmu_common/init.d/rc.io7
-rw-r--r--ROMFS/px4fmu_common/init.d/rc.logging10
-rw-r--r--ROMFS/px4fmu_common/init.d/rc.sensors8
-rw-r--r--ROMFS/px4fmu_common/init.d/rc.usb2
-rw-r--r--ROMFS/px4fmu_common/init.d/rcS32
-rw-r--r--ROMFS/px4fmu_common/mixers/firefly6.aux.mix18
-rw-r--r--Tools/px4params/dokuwikiout.py4
-rw-r--r--Tools/px4params/srcparser.py62
-rw-r--r--Tools/px4params/xmlout.py66
-rwxr-xr-xTools/px_mkfw.py1
-rw-r--r--Tools/px_process_params.py7
-rw-r--r--makefiles/board_px4-stm32f4discovery.mk11
-rw-r--r--makefiles/config_aerocore_default.mk1
-rw-r--r--makefiles/config_px4-stm32f4discovery_default.mk92
-rw-r--r--makefiles/config_px4fmu-v1_default.mk1
-rw-r--r--makefiles/config_px4fmu-v2_default.mk1
-rw-r--r--makefiles/config_px4fmu-v2_multiplatform.mk1
-rw-r--r--makefiles/config_px4fmu-v2_test.mk1
-rw-r--r--makefiles/firmware.mk7
-rw-r--r--makefiles/upload.mk3
m---------mavlink/include/mavlink/v1.00
-rw-r--r--msg/mc_att_ctrl_status.msg5
-rw-r--r--msg/vehicle_status.msg6
-rw-r--r--nuttx-configs/aerocore/nsh/defconfig2
-rw-r--r--nuttx-configs/px4-stm32f4discovery/include/board.h273
-rw-r--r--nuttx-configs/px4-stm32f4discovery/include/nsh_romfsimg.h42
-rw-r--r--nuttx-configs/px4-stm32f4discovery/nsh/Make.defs179
-rw-r--r--nuttx-configs/px4-stm32f4discovery/nsh/appconfig (renamed from src/systemcmds/preflight_check/module.mk)24
-rw-r--r--nuttx-configs/px4-stm32f4discovery/nsh/defconfig897
-rwxr-xr-xnuttx-configs/px4-stm32f4discovery/nsh/setenv.sh67
-rw-r--r--nuttx-configs/px4-stm32f4discovery/scripts/ld.script149
-rw-r--r--nuttx-configs/px4-stm32f4discovery/src/Makefile84
-rw-r--r--nuttx-configs/px4-stm32f4discovery/src/empty.c4
-rw-r--r--nuttx-configs/px4fmu-v1/nsh/defconfig2
-rw-r--r--src/drivers/ardrone_interface/ardrone_interface.c3
-rw-r--r--src/drivers/blinkm/blinkm.cpp3
-rw-r--r--src/drivers/boards/px4-stm32f4discovery/board_config.h136
-rw-r--r--src/drivers/boards/px4-stm32f4discovery/module.mk7
-rw-r--r--src/drivers/boards/px4-stm32f4discovery/px4discovery_init.c173
-rw-r--r--src/drivers/boards/px4-stm32f4discovery/px4discovery_led.c97
-rw-r--r--src/drivers/boards/px4-stm32f4discovery/px4discovery_usb.c108
-rw-r--r--src/drivers/boards/px4fmu-v1/px4fmu_init.c7
-rw-r--r--src/drivers/boards/px4fmu-v2/px4fmu2_init.c7
-rw-r--r--src/drivers/drv_gpio.h6
-rw-r--r--src/drivers/drv_rc_input.h2
-rw-r--r--src/drivers/hmc5883/hmc5883.cpp5
-rw-r--r--src/drivers/hott/hott_sensors/hott_sensors.cpp2
-rw-r--r--src/drivers/hott/hott_telemetry/hott_telemetry.cpp2
-rw-r--r--src/drivers/md25/md25_main.cpp3
-rw-r--r--src/drivers/px4flow/px4flow.cpp2
-rw-r--r--src/drivers/px4io/px4io.cpp26
-rw-r--r--src/drivers/rgbled/rgbled.cpp4
-rw-r--r--src/drivers/roboclaw/roboclaw_main.cpp3
-rw-r--r--src/drivers/sf0x/sf0x.cpp10
-rw-r--r--src/drivers/stm32/tone_alarm/tone_alarm.cpp5
-rw-r--r--src/examples/fixedwing_control/main.c2
-rw-r--r--src/examples/flow_position_estimator/flow_position_estimator_main.c2
-rw-r--r--src/examples/matlab_csv_serial/matlab_csv_serial.c2
-rw-r--r--src/examples/publisher/publisher_start_nuttx.cpp2
-rw-r--r--src/examples/px4_daemon_app/px4_daemon_app.c2
-rw-r--r--src/examples/rover_steering_control/main.cpp2
-rw-r--r--src/examples/subscriber/subscriber_start_nuttx.cpp2
-rw-r--r--src/lib/rc/sumd.c2
-rw-r--r--src/lib/version/version.h12
-rwxr-xr-xsrc/modules/attitude_estimator_ekf/attitude_estimator_ekf_main.cpp47
-rwxr-xr-xsrc/modules/attitude_estimator_ekf/attitude_estimator_ekf_params.c22
-rwxr-xr-xsrc/modules/attitude_estimator_so3/attitude_estimator_so3_main.cpp3
-rw-r--r--src/modules/commander/PreflightCheck.cpp343
-rw-r--r--src/modules/commander/PreflightCheck.h80
-rw-r--r--src/modules/commander/accelerometer_calibration.cpp87
-rw-r--r--src/modules/commander/airspeed_calibration.cpp106
-rw-r--r--src/modules/commander/calibration_messages.h30
-rw-r--r--src/modules/commander/calibration_routines.cpp145
-rw-r--r--src/modules/commander/calibration_routines.h71
-rw-r--r--src/modules/commander/commander.cpp224
-rw-r--r--src/modules/commander/commander_helper.cpp7
-rw-r--r--src/modules/commander/commander_helper.h1
-rw-r--r--src/modules/commander/commander_params.c28
-rw-r--r--src/modules/commander/commander_tests/module.mk3
-rw-r--r--src/modules/commander/commander_tests/state_machine_helper_test.cpp4
-rw-r--r--src/modules/commander/gyro_calibration.cpp342
-rw-r--r--src/modules/commander/mag_calibration.cpp194
-rw-r--r--src/modules/commander/module.mk3
-rw-r--r--src/modules/commander/state_machine_helper.cpp116
-rw-r--r--src/modules/dataman/dataman.c11
-rw-r--r--src/modules/ekf_att_pos_estimator/ekf_att_pos_estimator_main.cpp33
-rw-r--r--src/modules/fixedwing_backside/fixedwing_backside_main.cpp3
-rw-r--r--src/modules/fw_att_control/fw_att_control_main.cpp3
-rw-r--r--src/modules/fw_att_control/fw_att_control_params.c3
-rw-r--r--src/modules/fw_pos_control_l1/fw_pos_control_l1_main.cpp3
-rw-r--r--src/modules/fw_pos_control_l1/mtecs/mTecs_params.c88
-rw-r--r--src/modules/land_detector/land_detector_main.cpp2
-rw-r--r--src/modules/mavlink/mavlink.c4
-rw-r--r--src/modules/mavlink/mavlink_main.cpp2
-rw-r--r--src/modules/mavlink/mavlink_messages.cpp78
-rw-r--r--src/modules/mavlink/mavlink_messages.h2
-rw-r--r--src/modules/mavlink/mavlink_parameters.cpp6
-rw-r--r--src/modules/mavlink/mavlink_receiver.cpp26
-rw-r--r--src/modules/mavlink/mavlink_receiver.h7
-rw-r--r--src/modules/mc_att_control/mc_att_control_main.cpp49
-rw-r--r--src/modules/mc_att_control_multiplatform/mc_att_control_start_nuttx.cpp2
-rw-r--r--src/modules/mc_pos_control/mc_pos_control_main.cpp4
-rw-r--r--src/modules/mc_pos_control_multiplatform/mc_pos_control_start_nuttx.cpp2
-rw-r--r--src/modules/navigator/datalinkloss.cpp10
-rw-r--r--src/modules/navigator/datalinkloss_params.c18
-rw-r--r--src/modules/navigator/enginefailure.cpp2
-rw-r--r--src/modules/navigator/geofence.cpp68
-rw-r--r--src/modules/navigator/geofence.h16
-rw-r--r--src/modules/navigator/geofence_params.c27
-rw-r--r--src/modules/navigator/gpsfailure.cpp4
-rw-r--r--src/modules/navigator/gpsfailure_params.c8
-rw-r--r--src/modules/navigator/mission.cpp2
-rw-r--r--src/modules/navigator/mission_block.cpp2
-rw-r--r--src/modules/navigator/mission_feasibility_checker.cpp14
-rw-r--r--src/modules/navigator/navigator.h2
-rw-r--r--src/modules/navigator/navigator_main.cpp15
-rw-r--r--src/modules/navigator/navigator_params.c10
-rw-r--r--src/modules/navigator/rcloss.cpp6
-rw-r--r--src/modules/navigator/rcloss_params.c2
-rw-r--r--src/modules/navigator/rtl.cpp16
-rw-r--r--src/modules/navigator/rtl_params.c18
-rw-r--r--src/modules/position_estimator_inav/position_estimator_inav_main.c2
-rw-r--r--src/modules/position_estimator_inav/position_estimator_inav_params.c9
-rw-r--r--src/modules/px4iofirmware/controls.c29
-rw-r--r--src/modules/px4iofirmware/registers.c8
-rw-r--r--src/modules/sdlog2/module.mk1
-rw-r--r--src/modules/sdlog2/sdlog2.c206
-rw-r--r--src/modules/sdlog2/sdlog2_messages.h18
-rw-r--r--src/modules/segway/segway_main.cpp3
-rw-r--r--src/modules/sensors/sensor_params.c110
-rw-r--r--src/modules/sensors/sensors.cpp75
-rw-r--r--src/modules/systemlib/circuit_breaker_params.c13
-rw-r--r--src/modules/systemlib/circuit_breaker_params.h7
-rw-r--r--src/modules/systemlib/param/param.c47
-rw-r--r--src/modules/systemlib/param/param.h8
-rw-r--r--src/modules/uORB/objects_common.cpp6
-rw-r--r--src/modules/uORB/topics/time_offset.h67
-rw-r--r--src/modules/uORB/uORB.cpp20
-rw-r--r--src/modules/uORB/uORB.h9
-rw-r--r--src/modules/uavcan/module.mk9
-rw-r--r--src/modules/uavcan/uavcan_main.cpp8
-rw-r--r--src/modules/vtol_att_control/vtol_att_control_main.cpp8
-rw-r--r--src/modules/vtol_att_control/vtol_att_control_params.c6
-rw-r--r--src/systemcmds/param/param.c4
-rw-r--r--src/systemcmds/preflight_check/preflight_check.c286
-rw-r--r--src/systemcmds/tests/test_gpio.c9
-rw-r--r--src/systemcmds/ver/module.mk2
-rw-r--r--src/systemcmds/ver/ver.c2
155 files changed, 4688 insertions, 1511 deletions
diff --git a/.travis.yml b/.travis.yml
index 3e97545e1..0405ba560 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -3,16 +3,36 @@
language: cpp
+# use travis-ci docker based infrastructure
+sudo: false
+
+cache:
+ directories:
+ - $HOME/.ccache
+
+addons:
+ apt:
+ sources:
+ - ubuntu-toolchain-r-test
+ packages:
+ - build-essential
+ - ccache
+ - cmake
+ - g++-4.8
+ - gcc-4.8
+ - genromfs
+ - libc6-i386
+ - libncurses5-dev
+ - python-argparse
+ - python-empy
+ - python-serial
+ - s3cmd
+ - texinfo
+ - zlib1g-dev
+
before_script:
- - sudo add-apt-repository --yes ppa:ubuntu-toolchain-r/test
- - sudo apt-get update -qq
- - if [ "$CXX" = "g++" ]; then sudo apt-get install -qq g++-4.8 gcc-4.8 libstdc++-4.8-dev; fi
- if [ "$CXX" = "g++" ]; then export CXX="g++-4.8" CC="gcc-4.8"; fi
-# Travis specific tools
- - sudo apt-get install -qq s3cmd grep zip
# General toolchain dependencies
- - sudo apt-get install -qq libc6-i386 gcc-4.7-base:i386 python-serial python-argparse python-empy
- - sudo apt-get install -qq flex bison libncurses5-dev autoconf texinfo build-essential libtool zlib1g-dev genromfs git wget cmake
- pushd .
- cd ~
- wget https://launchpadlibrarian.net/186124160/gcc-arm-none-eabi-4_8-2014q3-20140805-linux.tar.bz2
@@ -21,9 +41,13 @@ before_script:
- if grep -Fxq "$exportline" ~/.profile; then echo nothing to do ; else echo $exportline >> ~/.profile; fi
- . ~/.profile
- popd
-
-git:
- depth: 500
+# setup ccache
+ - mkdir -p ~/bin
+ - ln -s /usr/bin/ccache ~/bin/arm-none-eabi-g++
+ - ln -s /usr/bin/ccache ~/bin/arm-none-eabi-gcc
+ - ln -s /usr/bin/ccache ~/bin/g++-4.8
+ - ln -s /usr/bin/ccache ~/bin/gcc-4.8
+ - export PATH=~/bin:$PATH
env:
global:
@@ -32,13 +56,9 @@ env:
# AWS SECRET: $PX4_AWS_SECRET
- secure: "h6oajlW68dWIr+wZhO58Dv6e68dZHrBLVA6lPXZmheFQBW6Xam1HuLGA0LOW6cL9TnrAsOZ8g4goB58eMQnMEijFZKi3mhRwZhd/Xjq/ZGJOWBUrLoQHZUw2dQk5ja5vmUlKEoQnFZjDuMjx8KfX5ZMNy8A3yssWZtJYHD8c+bk="
- PX4_AWS_BUCKET=px4-travis
- - PX4_EMAIL_SUBJECT="Travis CI result"
-# Email address: $PX4_EMAIL
- - secure: "ei3hKAw6Pk+vEkQBI5Y2Ak74BRAaXcK2UHVnVadviBHI4EVPwn1YGP6A4Y0wnLe4U7ETTl0UiijRoVxyDW0Mq896Pv0siw02amNpjSZZYu+RfN1+//MChB48OxsLDirUdHVrULhl/bOARM02h2Bg28jDE2g7IqmJwg3em3oMbjU="
- - PX4_REPORT=report.txt
- - BUILD_URI=https://px4-travis.s3.amazonaws.com/archives/Firmware/$TRAVIS_BRANCH/$TRAVIS_BUILD_ID/Firmware.zip
script:
+ - ccache -z
- arm-none-eabi-gcc --version
- echo 'Running Tests..' && echo -en 'travis_fold:start:script.1\\r'
- make tests
@@ -46,9 +66,11 @@ script:
- echo -en 'travis_fold:end:script.1\\r'
- echo 'Building NuttX..' && echo -en 'travis_fold:start:script.2\\r'
- make archives
+ - ccache -s
- echo -en 'travis_fold:end:script.2\\r'
- echo 'Building Firmware..' && echo -en 'travis_fold:start:script.3\\r'
- - make -j6
+ - make -j4
+ - ccache -s
- echo -en 'travis_fold:end:script.3\\r'
- zip Firmware.zip Images/*.px4
@@ -84,4 +106,3 @@ notifications:
- https://webhooks.gitter.im/e/2b9c4a4cb2211f8befba
on_success: always # options: [always|never|change] default: always
on_failure: always # options: [always|never|change] default: always
- on_start: false # default: false
diff --git a/Documentation/rc_mode_switch.odg b/Documentation/rc_mode_switch.odg
index 682c63e47..0a4f532eb 100644
--- a/Documentation/rc_mode_switch.odg
+++ b/Documentation/rc_mode_switch.odg
Binary files differ
diff --git a/Documentation/rc_mode_switch.pdf b/Documentation/rc_mode_switch.pdf
index e795f4870..cbcc59f72 100644
--- a/Documentation/rc_mode_switch.pdf
+++ b/Documentation/rc_mode_switch.pdf
Binary files differ
diff --git a/Images/px4-stm32f4discovery.prototype b/Images/px4-stm32f4discovery.prototype
new file mode 100644
index 000000000..9250691f7
--- /dev/null
+++ b/Images/px4-stm32f4discovery.prototype
@@ -0,0 +1,12 @@
+{
+ "board_id": 99,
+ "magic": "PX4FWv1",
+ "description": "Firmware for the STM32F4Discovery board",
+ "image": "",
+ "build_time": 0,
+ "summary": "PX4/STM32F4Discovery",
+ "version": "0.1",
+ "image_size": 0,
+ "git_identity": "",
+ "board_revision": 0
+}
diff --git a/NuttX b/NuttX
-Subproject 94818ce16f63c4728a1d9316628a3651287f16d
+Subproject 678eea3d2c157c686439597abb0367b0f1e643f
diff --git a/ROMFS/px4fmu_common/init.d/13002_firefly6 b/ROMFS/px4fmu_common/init.d/13002_firefly6
index 551a19928..191c58da4 100644
--- a/ROMFS/px4fmu_common/init.d/13002_firefly6
+++ b/ROMFS/px4fmu_common/init.d/13002_firefly6
@@ -8,7 +8,16 @@
sh /etc/init.d/rc.vtol_defaults
set MIXER firefly6
-
set PWM_OUT 12345678
+
+set MIXER_AUX firefly6
+set PWM_AUX_RATE 50
+set PWM_AUX_OUT 1234
+set PWM_AUX_DISARMED 1000
+set PWM_AUX_MIN 1000
+set PWM_AUX_MAX 2000
+
+set MAV_TYPE 21
+
param set VT_MOT_COUNT 6
param set VT_IDLE_PWM_MC 1080
diff --git a/ROMFS/px4fmu_common/init.d/rc.interface b/ROMFS/px4fmu_common/init.d/rc.interface
index 5101acc07..7a424970f 100644
--- a/ROMFS/px4fmu_common/init.d/rc.interface
+++ b/ROMFS/px4fmu_common/init.d/rc.interface
@@ -45,7 +45,7 @@ then
if mixer load $OUTPUT_DEV $MIXER_FILE
then
- echo "[i] Mixer: $MIXER_FILE"
+ echo "[i] Mixer: $MIXER_FILE on $OUTPUT_DEV"
else
echo "[i] Error loading mixer: $MIXER_FILE"
tone_alarm $TUNE_ERR
@@ -105,14 +105,14 @@ then
set MIXER_AUX_FILE none
set OUTPUT_AUX_DEV /dev/pwm_output1
- if [ -f $SDCARD_MIXERS_PATH/$MIXER_AUX.mix ]
+ if [ -f $SDCARD_MIXERS_PATH/$MIXER_AUX.aux.mix ]
then
- set MIXER_AUX_FILE $SDCARD_MIXERS_PATH/$MIXER_AUX.mix
+ set MIXER_AUX_FILE $SDCARD_MIXERS_PATH/$MIXER_AUX.aux.mix
else
- if [ -f /etc/mixers/$MIXER_AUX.mix ]
+ if [ -f /etc/mixers/$MIXER_AUX.aux.mix ]
then
- set MIXER_AUX_FILE /etc/mixers/$MIXER_AUX.mix
+ set MIXER_AUX_FILE /etc/mixers/$MIXER_AUX.aux.mix
fi
fi
@@ -120,7 +120,12 @@ then
then
if fmu mode_pwm
then
- mixer load $OUTPUT_AUX_DEV $MIXER_AUX_FILE
+ if mixer load $OUTPUT_AUX_DEV $MIXER_AUX_FILE
+ then
+ echo "[i] Mixer: $MIXER_AUX_FILE on $OUTPUT_AUX_DEV"
+ else
+ echo "[i] Error loading mixer: $MIXER_AUX_FILE"
+ fi
else
tone_alarm $TUNE_ERR
fi
diff --git a/ROMFS/px4fmu_common/init.d/rc.io b/ROMFS/px4fmu_common/init.d/rc.io
index e957626ce..86042220e 100644
--- a/ROMFS/px4fmu_common/init.d/rc.io
+++ b/ROMFS/px4fmu_common/init.d/rc.io
@@ -16,5 +16,8 @@ then
set PX4IO_LIMIT 200
fi
-echo "[i] Set PX4IO update rate limit: $PX4IO_LIMIT Hz"
-px4io limit $PX4IO_LIMIT
+if px4io limit $PX4IO_LIMIT
+then
+else
+ echo "[i] Set PX4IO update rate to $PX4IO_LIMIT Hz failed!"
+fi
diff --git a/ROMFS/px4fmu_common/init.d/rc.logging b/ROMFS/px4fmu_common/init.d/rc.logging
index a14eb5247..454af8da7 100644
--- a/ROMFS/px4fmu_common/init.d/rc.logging
+++ b/ROMFS/px4fmu_common/init.d/rc.logging
@@ -7,10 +7,12 @@ if [ -d /fs/microsd ]
then
if ver hwcmp PX4FMU_V1
then
- echo "Start sdlog2 at 50Hz"
- sdlog2 start -r 40 -a -b 3 -t
+ if sdlog2 start -r 40 -a -b 3 -t
+ then
+ fi
else
- echo "Start sdlog2 at 200Hz"
- sdlog2 start -r 200 -a -b 22 -t
+ if sdlog2 start -r 200 -a -b 22 -t
+ then
+ fi
fi
fi
diff --git a/ROMFS/px4fmu_common/init.d/rc.sensors b/ROMFS/px4fmu_common/init.d/rc.sensors
index ffded7d6b..b8a704b90 100644
--- a/ROMFS/px4fmu_common/init.d/rc.sensors
+++ b/ROMFS/px4fmu_common/init.d/rc.sensors
@@ -115,9 +115,7 @@ then
fi
#
-# Start sensors -> preflight_check
+# Start sensors
#
-if sensors start
-then
- preflight_check &
-fi
+sensors start
+
diff --git a/ROMFS/px4fmu_common/init.d/rc.usb b/ROMFS/px4fmu_common/init.d/rc.usb
index fddcf5b3e..e456eff7f 100644
--- a/ROMFS/px4fmu_common/init.d/rc.usb
+++ b/ROMFS/px4fmu_common/init.d/rc.usb
@@ -3,7 +3,7 @@
# USB MAVLink start
#
-mavlink start -r 20000 -d /dev/ttyACM0 -x
+mavlink start -r 30000 -d /dev/ttyACM0 -x
# Enable a number of interesting streams we want via USB
mavlink stream -d /dev/ttyACM0 -s PARAM_VALUE -r 200
mavlink stream -d /dev/ttyACM0 -s MISSION_ITEM -r 50
diff --git a/ROMFS/px4fmu_common/init.d/rcS b/ROMFS/px4fmu_common/init.d/rcS
index 0a8774b30..1237d9bb1 100644
--- a/ROMFS/px4fmu_common/init.d/rcS
+++ b/ROMFS/px4fmu_common/init.d/rcS
@@ -24,7 +24,6 @@ set LOG_FILE /fs/microsd/bootlog.txt
# Try to mount the microSD card.
#
# REBOOTWORK this needs to start after the flight control loop
-echo "[i] Looking for microSD..."
if mount -t vfat /dev/mmcsd0 /fs/microsd
then
echo "[i] microSD mounted: /fs/microsd"
@@ -42,6 +41,8 @@ else
tone_alarm MNBG
set LOG_FILE /dev/null
fi
+ else
+ set LOG_FILE /dev/null
fi
fi
@@ -51,11 +52,9 @@ fi
#
if [ -f $FRC ]
then
- echo "[i] Executing init script: $FRC"
+ echo "[i] Executing script: $FRC"
sh $FRC
set MODE custom
-else
- echo "[i] Init script not found: $FRC"
fi
unset FRC
@@ -124,6 +123,7 @@ then
set PWM_AUX_DISARMED none
set PWM_AUX_MIN none
set PWM_AUX_MAX none
+ set FAILSAFE_AUX none
set MK_MODE none
set FMU_MODE pwm
set MAVLINK_F default
@@ -172,10 +172,8 @@ then
#
if [ -f $FCONFIG ]
then
- echo "[i] Config: $FCONFIG"
+ echo "[i] Custom config: $FCONFIG"
sh $FCONFIG
- else
- echo "[i] Config not found: $FCONFIG"
fi
unset FCONFIG
@@ -299,6 +297,11 @@ then
then
fi
+ #
+ # Sensors System (start before Commander so Preflight checks are properly run)
+ #
+ sh /etc/init.d/rc.sensors
+
# Needs to be this early for in-air-restarts
commander start
@@ -323,10 +326,8 @@ then
then
if px4io start
then
- echo "[i] PX4IO started"
sh /etc/init.d/rc.io
else
- echo "[i] ERROR: PX4IO start failed"
tone_alarm $TUNE_ERR
fi
fi
@@ -454,10 +455,16 @@ then
#
if ver hwcmp PX4FMU_V2
then
+ # XXX We need a better way for runtime eval of shell variables,
+ # but this works for now
if param compare SYS_COMPANION 921600
then
mavlink start -d /dev/ttyS2 -b 921600 -m onboard -r 20000
fi
+ if param compare SYS_COMPANION 57600
+ then
+ mavlink start -d /dev/ttyS2 -b 57600 -m onboard -r 1000
+ fi
fi
# UAVCAN
@@ -465,9 +472,8 @@ then
sh /etc/init.d/rc.uavcan
#
- # Sensors, Logging, GPS
+ # Logging, GPS
#
- sh /etc/init.d/rc.sensors
sh /etc/init.d/rc.logging
if [ $GPS == yes ]
@@ -603,7 +609,7 @@ then
then
set MAV_TYPE 19
fi
- if [ $MIXER == firefly6_rotors ]
+ if [ $MIXER == firefly6 ]
then
set MAV_TYPE 21
fi
@@ -669,8 +675,6 @@ then
then
echo "[i] Addons script: $FEXTRAS"
sh $FEXTRAS
- else
- echo "[i] No addons script: $FEXTRAS"
fi
unset FEXTRAS
diff --git a/ROMFS/px4fmu_common/mixers/firefly6.aux.mix b/ROMFS/px4fmu_common/mixers/firefly6.aux.mix
index 9ed6eeed9..fda841640 100644
--- a/ROMFS/px4fmu_common/mixers/firefly6.aux.mix
+++ b/ROMFS/px4fmu_common/mixers/firefly6.aux.mix
@@ -1,4 +1,14 @@
-# mixer for the FireFly6 elevons
+# mixer for the FireFly6 tilt mechansim servo, elevons and landing gear
+=======================================================================
+
+Tilt mechanism servo mixer
+---------------------------
+M: 1
+O: 10000 10000 0 -10000 10000
+S: 1 4 10000 10000 0 -10000 10000
+
+Elevon mixers
+-------------
M: 2
O: 10000 10000 0 -10000 10000
S: 1 0 7500 7500 0 -10000 10000
@@ -8,3 +18,9 @@ M: 2
O: 10000 10000 0 -10000 10000
S: 1 0 7500 7500 0 -10000 10000
S: 1 1 -8000 -8000 0 -10000 10000
+
+Landing gear mixer
+------------------
+M: 1
+O: 10000 10000 0 -10000 10000
+S: 3 6 10000 10000 0 -10000 10000
diff --git a/Tools/px4params/dokuwikiout.py b/Tools/px4params/dokuwikiout.py
index 77e0ef53d..28e487ea6 100644
--- a/Tools/px4params/dokuwikiout.py
+++ b/Tools/px4params/dokuwikiout.py
@@ -12,11 +12,11 @@ class DokuWikiTablesOutput():
result += "^ Name ^ Description ^ Min ^ Max ^ Default ^\n"
result += "^ ::: ^ Comment ^^^^\n"
for param in group.GetParams():
- code = param.GetFieldValue("code")
+ code = param.GetName()
+ def_val = param.GetDefault()
name = param.GetFieldValue("short_desc")
min_val = param.GetFieldValue("min")
max_val = param.GetFieldValue("max")
- def_val = param.GetFieldValue("default")
long_desc = param.GetFieldValue("long_desc")
if name == code:
diff --git a/Tools/px4params/srcparser.py b/Tools/px4params/srcparser.py
index 8e6092195..0d2413a75 100644
--- a/Tools/px4params/srcparser.py
+++ b/Tools/px4params/srcparser.py
@@ -37,20 +37,30 @@ class Parameter(object):
# Define sorting order of the fields
priority = {
- "code": 10,
- "type": 9,
+ "board": 9,
"short_desc": 8,
"long_desc": 7,
- "default": 6,
"min": 5,
"max": 4,
"unit": 3,
# all others == 0 (sorted alphabetically)
}
- def __init__(self):
+ def __init__(self, name, type, default = ""):
self.fields = {}
+ self.name = name
+ self.type = type
+ self.default = default
+ def GetName(self):
+ return self.name
+
+ def GetType(self):
+ return self.type
+
+ def GetDefault(self):
+ return self.default
+
def SetField(self, code, value):
"""
Set named field value
@@ -83,11 +93,12 @@ class SourceParser(object):
re_comment_tag = re.compile(r'@([a-zA-Z][a-zA-Z0-9_]*)\s*(.*)')
re_comment_end = re.compile(r'(.*?)\s*\*\/')
re_parameter_definition = re.compile(r'PARAM_DEFINE_([A-Z_][A-Z0-9_]*)\s*\(([A-Z_][A-Z0-9_]*)\s*,\s*([^ ,\)]+)\s*\)\s*;')
+ re_px4_parameter_definition = re.compile(r'PX4_PARAM_DEFINE_([A-Z_][A-Z0-9_]*)\s*\(([A-Z_][A-Z0-9_]*)\s*\)\s*;')
re_cut_type_specifier = re.compile(r'[a-z]+$')
re_is_a_number = re.compile(r'^-?[0-9\.]')
re_remove_dots = re.compile(r'\.+$')
- valid_tags = set(["group", "min", "max", "unit"])
+ valid_tags = set(["group", "board", "min", "max", "unit"])
# Order of parameter groups
priority = {
@@ -176,15 +187,12 @@ class SourceParser(object):
# Non-empty line outside the comment
m = self.re_parameter_definition.match(line)
if m:
- tp, code, defval = m.group(1, 2, 3)
+ tp, name, defval = m.group(1, 2, 3)
# Remove trailing type specifier from numbers: 0.1f => 0.1
if self.re_is_a_number.match(defval):
defval = self.re_cut_type_specifier.sub('', defval)
- param = Parameter()
- param.SetField("code", code)
- param.SetField("short_desc", code)
- param.SetField("type", tp)
- param.SetField("default", defval)
+ param = Parameter(name, tp, defval)
+ param.SetField("short_desc", name)
# If comment was found before the parameter declaration,
# inject its data into the newly created parameter.
group = "Miscellaneous"
@@ -206,8 +214,36 @@ class SourceParser(object):
if group not in self.param_groups:
self.param_groups[group] = ParameterGroup(group)
self.param_groups[group].AddParameter(param)
- # Reset parsed comment.
- state = None
+ else:
+ # Nasty code dup, but this will all go away soon, so quick and dirty (DonLakeFlyer)
+ m = self.re_px4_parameter_definition.match(line)
+ if m:
+ tp, name = m.group(1, 2)
+ param = Parameter(name, tp)
+ param.SetField("short_desc", name)
+ # If comment was found before the parameter declaration,
+ # inject its data into the newly created parameter.
+ group = "Miscellaneous"
+ if state == "comment-processed":
+ if short_desc is not None:
+ param.SetField("short_desc",
+ self.re_remove_dots.sub('', short_desc))
+ if long_desc is not None:
+ param.SetField("long_desc", long_desc)
+ for tag in tags:
+ if tag == "group":
+ group = tags[tag]
+ elif tag not in self.valid_tags:
+ sys.stderr.write("Skipping invalid "
+ "documentation tag: '%s'\n" % tag)
+ else:
+ param.SetField(tag, tags[tag])
+ # Store the parameter
+ if group not in self.param_groups:
+ self.param_groups[group] = ParameterGroup(group)
+ self.param_groups[group].AddParameter(param)
+ # Reset parsed comment.
+ state = None
def GetParamGroups(self):
"""
diff --git a/Tools/px4params/xmlout.py b/Tools/px4params/xmlout.py
index e845cd1b1..07cced478 100644
--- a/Tools/px4params/xmlout.py
+++ b/Tools/px4params/xmlout.py
@@ -1,26 +1,56 @@
-from xml.dom.minidom import getDOMImplementation
+import xml.etree.ElementTree as ET
import codecs
+def indent(elem, level=0):
+ i = "\n" + level*" "
+ if len(elem):
+ if not elem.text or not elem.text.strip():
+ elem.text = i + " "
+ if not elem.tail or not elem.tail.strip():
+ elem.tail = i
+ for elem in elem:
+ indent(elem, level+1)
+ if not elem.tail or not elem.tail.strip():
+ elem.tail = i
+ else:
+ if level and (not elem.tail or not elem.tail.strip()):
+ elem.tail = i
+
class XMLOutput():
- def __init__(self, groups):
- impl = getDOMImplementation()
- xml_document = impl.createDocument(None, "parameters", None)
- xml_parameters = xml_document.documentElement
+
+ def __init__(self, groups, board):
+ xml_parameters = ET.Element("parameters")
+ xml_version = ET.SubElement(xml_parameters, "version")
+ xml_version.text = "3"
+ last_param_name = ""
+ board_specific_param_set = False
for group in groups:
- xml_group = xml_document.createElement("group")
- xml_group.setAttribute("name", group.GetName())
- xml_parameters.appendChild(xml_group)
+ xml_group = ET.SubElement(xml_parameters, "group")
+ xml_group.attrib["name"] = group.GetName()
for param in group.GetParams():
- xml_param = xml_document.createElement("parameter")
- xml_group.appendChild(xml_param)
- for code in param.GetFieldCodes():
- value = param.GetFieldValue(code)
- xml_field = xml_document.createElement(code)
- xml_param.appendChild(xml_field)
- xml_value = xml_document.createTextNode(value)
- xml_field.appendChild(xml_value)
- self.xml_document = xml_document
+ if (last_param_name == param.GetName() and not board_specific_param_set) or last_param_name != param.GetName():
+ xml_param = ET.SubElement(xml_group, "parameter")
+ xml_param.attrib["name"] = param.GetName()
+ xml_param.attrib["default"] = param.GetDefault()
+ xml_param.attrib["type"] = param.GetType()
+ last_param_name = param.GetName()
+ for code in param.GetFieldCodes():
+ value = param.GetFieldValue(code)
+ if code == "board":
+ if value == board:
+ board_specific_param_set = True
+ xml_field = ET.SubElement(xml_param, code)
+ xml_field.text = value
+ else:
+ xml_group.remove(xml_param)
+ else:
+ xml_field = ET.SubElement(xml_param, code)
+ xml_field.text = value
+ if last_param_name != param.GetName():
+ board_specific_param_set = False
+ indent(xml_parameters)
+ self.xml_document = ET.ElementTree(xml_parameters)
def Save(self, filename):
with codecs.open(filename, 'w', 'utf-8') as f:
- self.xml_document.writexml(f, indent=" ", addindent=" ", newl="\n")
+ self.xml_document.write(f)
diff --git a/Tools/px_mkfw.py b/Tools/px_mkfw.py
index c2da8a203..152444f84 100755
--- a/Tools/px_mkfw.py
+++ b/Tools/px_mkfw.py
@@ -105,6 +105,7 @@ if args.git_identity != None:
if args.parameter_xml != None:
f = open(args.parameter_xml, "rb")
bytes = f.read()
+ desc['parameter_xml_size'] = len(bytes)
desc['parameter_xml'] = base64.b64encode(zlib.compress(bytes,9)).decode('utf-8')
if args.image != None:
f = open(args.image, "rb")
diff --git a/Tools/px_process_params.py b/Tools/px_process_params.py
index 12128a997..cb2202d52 100644
--- a/Tools/px_process_params.py
+++ b/Tools/px_process_params.py
@@ -65,6 +65,11 @@ def main():
metavar="FILENAME",
help="Create XML file"
" (default FILENAME: parameters.xml)")
+ parser.add_argument("-b", "--board",
+ nargs='?',
+ const="",
+ metavar="BOARD",
+ help="Board to create xml parameter xml for")
parser.add_argument("-w", "--wiki",
nargs='?',
const="parameters.wiki",
@@ -116,7 +121,7 @@ def main():
# Output to XML file
if args.xml:
print("Creating XML file " + args.xml)
- out = xmlout.XMLOutput(param_groups)
+ out = xmlout.XMLOutput(param_groups, args.board)
out.Save(args.xml)
# Output to DokuWiki tables
diff --git a/makefiles/board_px4-stm32f4discovery.mk b/makefiles/board_px4-stm32f4discovery.mk
new file mode 100644
index 000000000..fe761ba44
--- /dev/null
+++ b/makefiles/board_px4-stm32f4discovery.mk
@@ -0,0 +1,11 @@
+#
+# Board-specific definitions for the PX4_STM32F4DISCOVERY
+#
+
+#
+# Configure the toolchain
+#
+CONFIG_ARCH = CORTEXM4F
+CONFIG_BOARD = PX4_STM32F4DISCOVERY
+
+include $(PX4_MK_DIR)/toolchain_gnu-arm-eabi.mk
diff --git a/makefiles/config_aerocore_default.mk b/makefiles/config_aerocore_default.mk
index 9ab63a973..c906d5418 100644
--- a/makefiles/config_aerocore_default.mk
+++ b/makefiles/config_aerocore_default.mk
@@ -31,7 +31,6 @@ MODULES += systemcmds/ver
MODULES += systemcmds/mixer
MODULES += systemcmds/param
MODULES += systemcmds/perf
-MODULES += systemcmds/preflight_check
MODULES += systemcmds/pwm
MODULES += systemcmds/esc_calib
MODULES += systemcmds/reboot
diff --git a/makefiles/config_px4-stm32f4discovery_default.mk b/makefiles/config_px4-stm32f4discovery_default.mk
new file mode 100644
index 000000000..8f73a7f04
--- /dev/null
+++ b/makefiles/config_px4-stm32f4discovery_default.mk
@@ -0,0 +1,92 @@
+#
+# Makefile for the px4fmu_default configuration
+#
+
+#
+# Use the configuration's ROMFS, copy the PX4_STM32F4DISCOVERY firmware into
+# the ROMFS if it's available
+#
+ROMFS_ROOT = $(PX4_BASE)/ROMFS/px4fmu_common
+ROMFS_OPTIONAL_FILES =
+
+#
+# Board support modules
+#
+MODULES += drivers/device
+MODULES += drivers/stm32
+MODULES += drivers/led
+MODULES += drivers/boards/px4-stm32f4discovery
+
+#
+# System commands
+#
+MODULES += systemcmds/bl_update
+MODULES += systemcmds/mixer
+MODULES += systemcmds/param
+MODULES += systemcmds/perf
+MODULES += systemcmds/reboot
+MODULES += systemcmds/top
+MODULES += systemcmds/tests
+MODULES += systemcmds/config
+MODULES += systemcmds/nshterm
+MODULES += systemcmds/ver
+
+#
+# Library modules
+#
+MODULES += modules/systemlib
+MODULES += modules/systemlib/mixer
+MODULES += modules/controllib
+MODULES += modules/uORB
+
+#
+# Libraries
+#
+LIBRARIES += lib/mathlib/CMSIS
+MODULES += lib/mathlib
+MODULES += lib/mathlib/math/filter
+MODULES += lib/ecl
+MODULES += lib/external_lgpl
+MODULES += lib/geo
+MODULES += lib/conversion
+MODULES += platforms/nuttx
+
+#
+# Demo apps
+#
+#MODULES += examples/math_demo
+# Tutorial code from
+# https://pixhawk.ethz.ch/px4/dev/hello_sky
+MODULES += examples/px4_simple_app
+
+# Tutorial code from
+# https://pixhawk.ethz.ch/px4/dev/daemon
+#MODULES += examples/px4_daemon_app
+
+# Tutorial code from
+# https://pixhawk.ethz.ch/px4/dev/debug_values
+#MODULES += examples/px4_mavlink_debug
+
+# Tutorial code from
+# https://pixhawk.ethz.ch/px4/dev/example_fixedwing_control
+#MODULES += examples/fixedwing_control
+
+# Hardware test
+#MODULES += examples/hwtest
+
+#
+# Transitional support - add commands from the NuttX export archive.
+#
+# In general, these should move to modules over time.
+#
+# Each entry here is <command>.<priority>.<stacksize>.<entrypoint> but we use a helper macro
+# to make the table a bit more readable.
+#
+define _B
+ $(strip $1).$(or $(strip $2),SCHED_PRIORITY_DEFAULT).$(or $(strip $3),CONFIG_PTHREAD_STACK_DEFAULT).$(strip $4)
+endef
+
+# command priority stack entrypoint
+BUILTIN_COMMANDS := \
+ $(call _B, sercon, , 2048, sercon_main ) \
+ $(call _B, serdis, , 2048, serdis_main )
diff --git a/makefiles/config_px4fmu-v1_default.mk b/makefiles/config_px4fmu-v1_default.mk
index e3515a927..55b73ffde 100644
--- a/makefiles/config_px4fmu-v1_default.mk
+++ b/makefiles/config_px4fmu-v1_default.mk
@@ -45,7 +45,6 @@ MODULES += systemcmds/mtd
MODULES += systemcmds/mixer
MODULES += systemcmds/param
MODULES += systemcmds/perf
-MODULES += systemcmds/preflight_check
MODULES += systemcmds/pwm
MODULES += systemcmds/esc_calib
MODULES += systemcmds/reboot
diff --git a/makefiles/config_px4fmu-v2_default.mk b/makefiles/config_px4fmu-v2_default.mk
index 324e12696..cbfda9735 100644
--- a/makefiles/config_px4fmu-v2_default.mk
+++ b/makefiles/config_px4fmu-v2_default.mk
@@ -53,7 +53,6 @@ MODULES += systemcmds/bl_update
MODULES += systemcmds/mixer
MODULES += systemcmds/param
MODULES += systemcmds/perf
-MODULES += systemcmds/preflight_check
MODULES += systemcmds/pwm
MODULES += systemcmds/esc_calib
MODULES += systemcmds/reboot
diff --git a/makefiles/config_px4fmu-v2_multiplatform.mk b/makefiles/config_px4fmu-v2_multiplatform.mk
index 568f940ee..b98532f71 100644
--- a/makefiles/config_px4fmu-v2_multiplatform.mk
+++ b/makefiles/config_px4fmu-v2_multiplatform.mk
@@ -51,7 +51,6 @@ MODULES += systemcmds/bl_update
MODULES += systemcmds/mixer
MODULES += systemcmds/param
MODULES += systemcmds/perf
-MODULES += systemcmds/preflight_check
MODULES += systemcmds/pwm
MODULES += systemcmds/esc_calib
MODULES += systemcmds/reboot
diff --git a/makefiles/config_px4fmu-v2_test.mk b/makefiles/config_px4fmu-v2_test.mk
index 0d04a1f19..154f7e5ba 100644
--- a/makefiles/config_px4fmu-v2_test.mk
+++ b/makefiles/config_px4fmu-v2_test.mk
@@ -45,7 +45,6 @@ MODULES += systemcmds/bl_update
MODULES += systemcmds/mixer
MODULES += systemcmds/param
MODULES += systemcmds/perf
-MODULES += systemcmds/preflight_check
MODULES += systemcmds/pwm
MODULES += systemcmds/esc_calib
MODULES += systemcmds/reboot
diff --git a/makefiles/firmware.mk b/makefiles/firmware.mk
index 21e8739aa..af3ca249e 100644
--- a/makefiles/firmware.mk
+++ b/makefiles/firmware.mk
@@ -181,11 +181,6 @@ EXTRA_CLEANS =
#
-# Extra defines for compilation
-#
-export EXTRADEFINES := -DGIT_VERSION=$(GIT_DESC)
-
-#
# Append the per-board driver directory to the header search path.
#
INCLUDE_DIRS += $(PX4_MODULE_SRC)drivers/boards/$(BOARD)
@@ -499,7 +494,7 @@ $(filter %.S.o,$(OBJS)): $(WORK_DIR)%.S.o: %.S $(GLOBAL_DEPS)
$(PRODUCT_BUNDLE): $(PRODUCT_BIN)
@$(ECHO) %% Generating $@
ifdef GEN_PARAM_XML
- python $(PX4_BASE)/Tools/px_process_params.py --src-path $(PX4_BASE)/src --xml
+ python $(PX4_BASE)/Tools/px_process_params.py --src-path $(PX4_BASE)/src --board CONFIG_ARCH_BOARD_$(CONFIG_BOARD) --xml
$(Q) $(MKFW) --prototype $(IMAGE_DIR)/$(BOARD).prototype \
--git_identity $(PX4_BASE) \
--parameter_xml $(PRODUCT_PARAMXML) \
diff --git a/makefiles/upload.mk b/makefiles/upload.mk
index 29b415688..dd7710bf7 100644
--- a/makefiles/upload.mk
+++ b/makefiles/upload.mk
@@ -33,7 +33,8 @@ upload-serial-px4fmu-v2: $(BUNDLE) $(UPLOADER)
upload-serial-aerocore:
openocd -f $(PX4_BASE)/makefiles/gumstix-aerocore.cfg -c 'init; reset halt; flash write_image erase $(PX4_BASE)/../Bootloader/px4aerocore_bl.bin 0x08000000; flash write_image erase $(PX4_BASE)/Build/aerocore_default.build/firmware.bin 0x08004000; reset run; exit'
-
+upload-serial-px4-stm32f4discovery: $(BUNDLE) $(UPLOADER)
+ $(Q) $(PYTHON) -u $(UPLOADER) --port $(SERIAL_PORTS) $(BUNDLE)
#
# JTAG firmware uploading with OpenOCD
diff --git a/mavlink/include/mavlink/v1.0 b/mavlink/include/mavlink/v1.0
-Subproject 7ae438b86ea983e95af5f092e45a5d0f9d093c7
+Subproject 475e7cc4348b207ac3efed45eb61160d23ac7a2
diff --git a/msg/mc_att_ctrl_status.msg b/msg/mc_att_ctrl_status.msg
new file mode 100644
index 000000000..114e843b0
--- /dev/null
+++ b/msg/mc_att_ctrl_status.msg
@@ -0,0 +1,5 @@
+uint64 timestamp # in microseconds since system start
+
+float32 roll_rate_integ # roll rate inegrator
+float32 pitch_rate_integ # pitch rate integrator
+float32 yaw_rate_integ # yaw rate integrator
diff --git a/msg/vehicle_status.msg b/msg/vehicle_status.msg
index 2e001cac7..2a7e493a3 100644
--- a/msg/vehicle_status.msg
+++ b/msg/vehicle_status.msg
@@ -72,8 +72,10 @@ uint8 VEHICLE_TYPE_FLAPPING_WING = 16 # Flapping wing
uint8 VEHICLE_TYPE_KITE = 17 # Kite
uint8 VEHICLE_TYPE_ONBOARD_CONTROLLER=18 # Onboard companion controller
uint8 VEHICLE_TYPE_VTOL_DUOROTOR = 19 # Vtol with two engines
-uint8 VEHICLE_TYPE_VTOL_QUADROTOR = 20 # Vtol with four engines*/
-uint8 VEHICLE_TYPE_ENUM_END = 21
+uint8 VEHICLE_TYPE_VTOL_QUADROTOR = 20 # Vtol with four engines
+uint8 VEHICLE_TYPE_VTOL_HEXAROTOR = 21 # Vtol with six engines
+uint8 VEHICLE_TYPE_VTOL_OCTOROTOR = 22 # Vtol with eight engines
+uint8 VEHICLE_TYPE_ENUM_END = 23
uint8 VEHICLE_BATTERY_WARNING_NONE = 0 # no battery low voltage warning active
uint8 VEHICLE_BATTERY_WARNING_LOW = 1 # warning of low voltage
diff --git a/nuttx-configs/aerocore/nsh/defconfig b/nuttx-configs/aerocore/nsh/defconfig
index 08ff4a988..e314bf1d8 100644
--- a/nuttx-configs/aerocore/nsh/defconfig
+++ b/nuttx-configs/aerocore/nsh/defconfig
@@ -403,7 +403,7 @@ CONFIG_SIG_SIGWORK=4
CONFIG_MAX_TASKS=32
CONFIG_MAX_TASK_ARGS=10
CONFIG_NPTHREAD_KEYS=4
-CONFIG_NFILE_DESCRIPTORS=36
+CONFIG_NFILE_DESCRIPTORS=42
CONFIG_NFILE_STREAMS=8
CONFIG_NAME_MAX=32
CONFIG_PREALLOC_MQ_MSGS=4
diff --git a/nuttx-configs/px4-stm32f4discovery/include/board.h b/nuttx-configs/px4-stm32f4discovery/include/board.h
new file mode 100644
index 000000000..0412c3aa6
--- /dev/null
+++ b/nuttx-configs/px4-stm32f4discovery/include/board.h
@@ -0,0 +1,273 @@
+/************************************************************************************
+ * configs/stm32f4discovery/include/board.h
+ * include/arch/board/board.h
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * 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 NuttX 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.
+ *
+ ************************************************************************************/
+
+#ifndef __CONFIG_PX4FMU_V1_INCLUDE_BOARD_H
+#define __CONFIG_PX4FMU_V1_INCLUDE_BOARD_H
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+#include <nuttx/config.h>
+
+#ifndef __ASSEMBLY__
+# include <stdint.h>
+#endif
+
+#include "stm32_rcc.h"
+#include "stm32_sdio.h"
+#include "stm32.h"
+
+/************************************************************************************
+ * Definitions
+ ************************************************************************************/
+
+/* Clocking *************************************************************************/
+/* The STM32F4 Discovery board features a single 8MHz crystal. Space is provided
+ * for a 32kHz RTC backup crystal, but it is not stuffed.
+ *
+ * This is the canonical configuration:
+ * System Clock source : PLL (HSE)
+ * SYSCLK(Hz) : 168000000 Determined by PLL configuration
+ * HCLK(Hz) : 168000000 (STM32_RCC_CFGR_HPRE)
+ * AHB Prescaler : 1 (STM32_RCC_CFGR_HPRE)
+ * APB1 Prescaler : 4 (STM32_RCC_CFGR_PPRE1)
+ * APB2 Prescaler : 2 (STM32_RCC_CFGR_PPRE2)
+ * HSE Frequency(Hz) : 8000000 (STM32_BOARD_XTAL)
+ * PLLM : 8 (STM32_PLLCFG_PLLM)
+ * PLLN : 336 (STM32_PLLCFG_PLLN)
+ * PLLP : 2 (STM32_PLLCFG_PLLP)
+ * PLLQ : 7 (STM32_PLLCFG_PLLQ)
+ * Main regulator output voltage : Scale1 mode Needed for high speed SYSCLK
+ * Flash Latency(WS) : 5
+ * Prefetch Buffer : OFF
+ * Instruction cache : ON
+ * Data cache : ON
+ * Require 48MHz for USB OTG FS, : Enabled
+ * SDIO and RNG clock
+ */
+
+/* HSI - 16 MHz RC factory-trimmed
+ * LSI - 32 KHz RC
+ * HSE - On-board crystal frequency is 8MHz
+ * LSE - 32.768 kHz
+ */
+
+#define STM32_BOARD_XTAL 8000000ul
+
+#define STM32_HSI_FREQUENCY 16000000ul
+#define STM32_LSI_FREQUENCY 32000
+#define STM32_HSE_FREQUENCY STM32_BOARD_XTAL
+#define STM32_LSE_FREQUENCY 32768
+
+/* Main PLL Configuration.
+ *
+ * PLL source is HSE
+ * PLL_VCO = (STM32_HSE_FREQUENCY / PLLM) * PLLN
+ * = (8,000,000 / 8) * 336
+ * = 336,000,000
+ * SYSCLK = PLL_VCO / PLLP
+ * = 336,000,000 / 2 = 168,000,000
+ * USB OTG FS, SDIO and RNG Clock
+ * = PLL_VCO / PLLQ
+ * = 48,000,000
+ */
+
+#define STM32_PLLCFG_PLLM RCC_PLLCFG_PLLM(8)
+#define STM32_PLLCFG_PLLN RCC_PLLCFG_PLLN(336)
+#define STM32_PLLCFG_PLLP RCC_PLLCFG_PLLP_2
+#define STM32_PLLCFG_PLLQ RCC_PLLCFG_PLLQ(7)
+
+#define STM32_SYSCLK_FREQUENCY 168000000ul
+
+/* AHB clock (HCLK) is SYSCLK (168MHz) */
+
+#define STM32_RCC_CFGR_HPRE RCC_CFGR_HPRE_SYSCLK /* HCLK = SYSCLK / 1 */
+#define STM32_HCLK_FREQUENCY STM32_SYSCLK_FREQUENCY
+#define STM32_BOARD_HCLK STM32_HCLK_FREQUENCY /* same as above, to satisfy compiler */
+
+/* APB1 clock (PCLK1) is HCLK/4 (42MHz) */
+
+#define STM32_RCC_CFGR_PPRE1 RCC_CFGR_PPRE1_HCLKd4 /* PCLK1 = HCLK / 4 */
+#define STM32_PCLK1_FREQUENCY (STM32_HCLK_FREQUENCY/4)
+
+/* Timers driven from APB1 will be twice PCLK1 */
+
+#define STM32_APB1_TIM2_CLKIN (2*STM32_PCLK1_FREQUENCY)
+#define STM32_APB1_TIM3_CLKIN (2*STM32_PCLK1_FREQUENCY)
+#define STM32_APB1_TIM4_CLKIN (2*STM32_PCLK1_FREQUENCY)
+#define STM32_APB1_TIM5_CLKIN (2*STM32_PCLK1_FREQUENCY)
+#define STM32_APB1_TIM6_CLKIN (2*STM32_PCLK1_FREQUENCY)
+#define STM32_APB1_TIM7_CLKIN (2*STM32_PCLK1_FREQUENCY)
+#define STM32_APB1_TIM12_CLKIN (2*STM32_PCLK1_FREQUENCY)
+#define STM32_APB1_TIM13_CLKIN (2*STM32_PCLK1_FREQUENCY)
+#define STM32_APB1_TIM14_CLKIN (2*STM32_PCLK1_FREQUENCY)
+
+/* APB2 clock (PCLK2) is HCLK/2 (84MHz) */
+
+#define STM32_RCC_CFGR_PPRE2 RCC_CFGR_PPRE2_HCLKd2 /* PCLK2 = HCLK / 2 */
+#define STM32_PCLK2_FREQUENCY (STM32_HCLK_FREQUENCY/2)
+
+/* Timers driven from APB2 will be twice PCLK2 */
+
+#define STM32_APB2_TIM1_CLKIN (2*STM32_PCLK2_FREQUENCY)
+#define STM32_APB2_TIM8_CLKIN (2*STM32_PCLK2_FREQUENCY)
+#define STM32_APB2_TIM9_CLKIN (2*STM32_PCLK2_FREQUENCY)
+#define STM32_APB2_TIM10_CLKIN (2*STM32_PCLK2_FREQUENCY)
+#define STM32_APB2_TIM11_CLKIN (2*STM32_PCLK2_FREQUENCY)
+
+/* Timer Frequencies, if APBx is set to 1, frequency is same to APBx
+ * otherwise frequency is 2xAPBx.
+ * Note: TIM1,8 are on APB2, others on APB1
+ */
+
+#define STM32_TIM18_FREQUENCY (2*STM32_PCLK2_FREQUENCY)
+#define STM32_TIM27_FREQUENCY (2*STM32_PCLK1_FREQUENCY)
+
+/* LED definitions ******************************************************************/
+/* If CONFIG_ARCH_LEDS is not defined, then the user can control the LEDs in any
+ * way. The following definitions are used to access individual LEDs.
+ */
+
+/* LED index values for use with stm32_setled() */
+
+#define BOARD_LED1 0
+#define BOARD_LED2 1
+#define BOARD_NLEDS 2
+
+#define BOARD_LED_BLUE BOARD_LED1
+#define BOARD_LED_RED BOARD_LED2
+
+/* LED bits for use with stm32_setleds() */
+
+#define BOARD_LED1_BIT (1 << BOARD_LED1)
+#define BOARD_LED2_BIT (1 << BOARD_LED2)
+
+/* If CONFIG_ARCH_LEDs is defined, then NuttX will control the 2 LEDs on board the
+ * px4fmu-v1. The following definitions describe how NuttX controls the LEDs:
+ */
+
+#define LED_STARTED 0 /* LED1 */
+#define LED_HEAPALLOCATE 1 /* LED2 */
+#define LED_IRQSENABLED 2 /* LED1 */
+#define LED_STACKCREATED 3 /* LED1 + LED2 */
+#define LED_INIRQ 4 /* LED1 */
+#define LED_SIGNAL 5 /* LED2 */
+#define LED_ASSERTION 6 /* LED1 + LED2 */
+#define LED_PANIC 7 /* LED1 + LED2 */
+
+/* Alternate function pin selections ************************************************/
+
+/* UART2:
+ *
+ * The STM32F4 Discovery has no on-board serial devices, but the console is
+ * brought out to PA2 (TX) and PA3 (RX) for connection to an external serial device.
+ * (See the README.txt file for other options)
+ */
+
+#define GPIO_USART2_RX GPIO_USART2_RX_1
+#define GPIO_USART2_TX GPIO_USART2_TX_1
+
+/* SPI - There is a MEMS device on SPI1 using these pins: */
+
+#define GPIO_SPI1_MISO GPIO_SPI1_MISO_1
+#define GPIO_SPI1_MOSI GPIO_SPI1_MOSI_1
+#define GPIO_SPI1_SCK GPIO_SPI1_SCK_1
+
+/*
+ * I2C
+ *
+ * The optional _GPIO configurations allow the I2C driver to manually
+ * reset the bus to clear stuck slaves. They match the pin configuration,
+ * but are normally-high GPIOs.
+ */
+#define GPIO_I2C1_SCL GPIO_I2C1_SCL_1
+#define GPIO_I2C1_SDA GPIO_I2C1_SDA_2
+#define GPIO_I2C1_SCL_GPIO (GPIO_OUTPUT|GPIO_OPENDRAIN|GPIO_SPEED_50MHz|GPIO_OUTPUT_SET|GPIO_PORTB|GPIO_PIN6)
+#define GPIO_I2C1_SDA_GPIO (GPIO_OUTPUT|GPIO_OPENDRAIN|GPIO_SPEED_50MHz|GPIO_OUTPUT_SET|GPIO_PORTB|GPIO_PIN9)
+
+/************************************************************************************
+ * Public Data
+ ************************************************************************************/
+
+#ifndef __ASSEMBLY__
+
+#undef EXTERN
+#if defined(__cplusplus)
+#define EXTERN extern "C"
+extern "C" {
+#else
+#define EXTERN extern
+#endif
+
+/************************************************************************************
+ * Public Function Prototypes
+ ************************************************************************************/
+/************************************************************************************
+ * Name: stm32_boardinitialize
+ *
+ * Description:
+ * All STM32 architectures must provide the following entry point. This entry point
+ * is called early in the intitialization -- after all memory has been configured
+ * and mapped but before any devices have been initialized.
+ *
+ ************************************************************************************/
+
+EXTERN void stm32_boardinitialize(void);
+
+/************************************************************************************
+ * Name: stm32_ledinit, stm32_setled, and stm32_setleds
+ *
+ * Description:
+ * If CONFIG_ARCH_LEDS is defined, then NuttX will control the on-board LEDs. If
+ * CONFIG_ARCH_LEDS is not defined, then the following interfacesare available to
+ * control the LEDs from user applications.
+ *
+ ************************************************************************************/
+
+#ifndef CONFIG_ARCH_LEDS
+EXTERN void stm32_ledinit(void);
+EXTERN void stm32_setled(int led, bool ledon);
+EXTERN void stm32_setleds(uint8_t ledset);
+#endif
+
+#undef EXTERN
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* __ASSEMBLY__ */
+#endif /* __CONFIG_PX4FMU_V1_INCLUDE_BOARD_H */
diff --git a/nuttx-configs/px4-stm32f4discovery/include/nsh_romfsimg.h b/nuttx-configs/px4-stm32f4discovery/include/nsh_romfsimg.h
new file mode 100644
index 000000000..15e4e7a8d
--- /dev/null
+++ b/nuttx-configs/px4-stm32f4discovery/include/nsh_romfsimg.h
@@ -0,0 +1,42 @@
+/****************************************************************************
+ *
+ * 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
+ * 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.
+ *
+ ****************************************************************************/
+
+/**
+ * nsh_romfsetc.h
+ *
+ * This file is a stub for 'make export' purposes; the actual ROMFS
+ * must be supplied by the library client.
+ */
+
+extern unsigned char romfs_img[];
+extern unsigned int romfs_img_len;
diff --git a/nuttx-configs/px4-stm32f4discovery/nsh/Make.defs b/nuttx-configs/px4-stm32f4discovery/nsh/Make.defs
new file mode 100644
index 000000000..e70320aaa
--- /dev/null
+++ b/nuttx-configs/px4-stm32f4discovery/nsh/Make.defs
@@ -0,0 +1,179 @@
+############################################################################
+# configs/px4fmu-v2/nsh/Make.defs
+#
+# Copyright (C) 2011 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# 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 NuttX 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 ${TOPDIR}/.config
+include ${TOPDIR}/tools/Config.mk
+
+#
+# We only support building with the ARM bare-metal toolchain from
+# https://launchpad.net/gcc-arm-embedded on Windows, Linux or Mac OS.
+#
+CONFIG_ARMV7M_TOOLCHAIN := GNU_EABI
+
+include ${TOPDIR}/arch/arm/src/armv7-m/Toolchain.defs
+
+CC = $(CROSSDEV)gcc
+CXX = $(CROSSDEV)g++
+CPP = $(CROSSDEV)gcc -E
+LD = $(CROSSDEV)ld
+AR = $(CROSSDEV)ar rcs
+NM = $(CROSSDEV)nm
+OBJCOPY = $(CROSSDEV)objcopy
+OBJDUMP = $(CROSSDEV)objdump
+
+MAXOPTIMIZATION = -O3
+ARCHCPUFLAGS = -mcpu=cortex-m4 \
+ -mthumb \
+ -march=armv7e-m \
+ -mfpu=fpv4-sp-d16 \
+ -mfloat-abi=hard
+
+
+# enable precise stack overflow tracking
+INSTRUMENTATIONDEFINES = -finstrument-functions \
+ -ffixed-r10
+
+# pull in *just* libm from the toolchain ... this is grody
+LIBM = "${shell $(CC) $(ARCHCPUFLAGS) -print-file-name=libm.a}"
+EXTRA_LIBS += $(LIBM)
+
+# use our linker script
+LDSCRIPT = ld.script
+
+ifeq ($(WINTOOL),y)
+ # Windows-native toolchains
+ DIRLINK = $(TOPDIR)/tools/copydir.sh
+ DIRUNLINK = $(TOPDIR)/tools/unlink.sh
+ MKDEP = $(TOPDIR)/tools/mknulldeps.sh
+ ARCHINCLUDES = -I. -isystem "${shell cygpath -w $(TOPDIR)/include}"
+ ARCHXXINCLUDES = -I. -isystem "${shell cygpath -w $(TOPDIR)/include}" -isystem "${shell cygpath -w $(TOPDIR)/include/cxx}"
+ ARCHSCRIPT = -T "${shell cygpath -w $(TOPDIR)/configs/$(CONFIG_ARCH_BOARD)/scripts/$(LDSCRIPT)}"
+else
+ ifeq ($(PX4_WINTOOL),y)
+ # Windows-native toolchains (MSYS)
+ DIRLINK = $(TOPDIR)/tools/copydir.sh
+ DIRUNLINK = $(TOPDIR)/tools/unlink.sh
+ MKDEP = $(TOPDIR)/tools/mknulldeps.sh
+ ARCHINCLUDES = -I. -isystem $(TOPDIR)/include
+ ARCHXXINCLUDES = -I. -isystem $(TOPDIR)/include -isystem $(TOPDIR)/include/cxx
+ ARCHSCRIPT = -T$(TOPDIR)/configs/$(CONFIG_ARCH_BOARD)/scripts/$(LDSCRIPT)
+ else
+ # Linux/Cygwin-native toolchain
+ MKDEP = $(TOPDIR)/tools/mkdeps.sh
+ ARCHINCLUDES = -I. -isystem $(TOPDIR)/include
+ ARCHXXINCLUDES = -I. -isystem $(TOPDIR)/include -isystem $(TOPDIR)/include/cxx
+ ARCHSCRIPT = -T$(TOPDIR)/configs/$(CONFIG_ARCH_BOARD)/scripts/$(LDSCRIPT)
+ endif
+endif
+
+# tool versions
+ARCHCCVERSION = ${shell $(CC) -v 2>&1 | sed -n '/^gcc version/p' | sed -e 's/^gcc version \([0-9\.]\)/\1/g' -e 's/[-\ ].*//g' -e '1q'}
+ARCHCCMAJOR = ${shell echo $(ARCHCCVERSION) | cut -d'.' -f1}
+
+# optimisation flags
+ARCHOPTIMIZATION = $(MAXOPTIMIZATION) \
+ -fno-strict-aliasing \
+ -fno-strength-reduce \
+ -fomit-frame-pointer \
+ -funsafe-math-optimizations \
+ -fno-builtin-printf \
+ -ffunction-sections \
+ -fdata-sections
+
+ifeq ("${CONFIG_DEBUG_SYMBOLS}","y")
+ARCHOPTIMIZATION += -g
+endif
+
+ARCHCFLAGS = -std=gnu99
+ARCHCXXFLAGS = -fno-exceptions -fno-rtti -std=gnu++0x
+ARCHWARNINGS = -Wall \
+ -Wextra \
+ -Wdouble-promotion \
+ -Wshadow \
+ -Wfloat-equal \
+ -Wframe-larger-than=1024 \
+ -Wpointer-arith \
+ -Wlogical-op \
+ -Wmissing-declarations \
+ -Wpacked \
+ -Wno-unused-parameter
+# -Wcast-qual - generates spurious noreturn attribute warnings, try again later
+# -Wconversion - would be nice, but too many "risky-but-safe" conversions in the code
+# -Wcast-align - would help catch bad casts in some cases, but generates too many false positives
+
+ARCHCWARNINGS = $(ARCHWARNINGS) \
+ -Wbad-function-cast \
+ -Wstrict-prototypes \
+ -Wold-style-declaration \
+ -Wmissing-parameter-type \
+ -Wmissing-prototypes \
+ -Wnested-externs \
+ -Wunsuffixed-float-constants
+ARCHWARNINGSXX = $(ARCHWARNINGS) \
+ -Wno-psabi
+ARCHDEFINES =
+ARCHPICFLAGS = -fpic -msingle-pic-base -mpic-register=r10
+
+# this seems to be the only way to add linker flags
+EXTRA_LIBS += --warn-common \
+ --gc-sections
+
+CFLAGS = $(ARCHCFLAGS) $(ARCHCWARNINGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHINCLUDES) $(INSTRUMENTATIONDEFINES) $(ARCHDEFINES) $(EXTRADEFINES) -pipe -fno-common
+CPICFLAGS = $(ARCHPICFLAGS) $(CFLAGS)
+CXXFLAGS = $(ARCHCXXFLAGS) $(ARCHWARNINGSXX) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHXXINCLUDES) $(INSTRUMENTATIONDEFINES) $(ARCHDEFINES) $(EXTRADEFINES) -pipe
+CXXPICFLAGS = $(ARCHPICFLAGS) $(CXXFLAGS)
+CPPFLAGS = $(ARCHINCLUDES) $(INSTRUMENTATIONDEFINES) $(ARCHDEFINES) $(EXTRADEFINES)
+AFLAGS = $(CFLAGS) -D__ASSEMBLY__
+
+NXFLATLDFLAGS1 = -r -d -warn-common
+NXFLATLDFLAGS2 = $(NXFLATLDFLAGS1) -T$(TOPDIR)/binfmt/libnxflat/gnu-nxflat.ld -no-check-sections
+LDNXFLATFLAGS = -e main -s 2048
+
+OBJEXT = .o
+LIBEXT = .a
+EXEEXT =
+
+
+# produce partially-linked $1 from files in $2
+define PRELINK
+ @echo "PRELINK: $1"
+ $(Q) $(LD) -Ur -o $1 $2 && $(OBJCOPY) --localize-hidden $1
+endef
+
+HOSTCC = gcc
+HOSTINCLUDES = -I.
+HOSTCFLAGS = -Wall -Wstrict-prototypes -Wshadow -g -pipe
+HOSTLDFLAGS =
+
diff --git a/src/systemcmds/preflight_check/module.mk b/nuttx-configs/px4-stm32f4discovery/nsh/appconfig
index 0cb2a4cd0..f14ab4044 100644
--- a/src/systemcmds/preflight_check/module.mk
+++ b/nuttx-configs/px4-stm32f4discovery/nsh/appconfig
@@ -1,6 +1,8 @@
############################################################################
+# configs/px4fmu/nsh/appconfig
#
-# Copyright (c) 2012, 2013 PX4 Development Team. All rights reserved.
+# Copyright (C) 2011 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
@@ -12,7 +14,7 @@
# 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
+# 3. Neither the name NuttX nor the names of its contributors may be
# used to endorse or promote products derived from this software
# without specific prior written permission.
#
@@ -31,14 +33,16 @@
#
############################################################################
-#
-# Pre-flight check. Locks down system for a few systems with blinking leds
-# and buzzer if the sensors do not report an OK status.
-#
+# Path to example in apps/examples containing the user_start entry point
-MODULE_COMMAND = preflight_check
-SRCS = preflight_check.c
+CONFIGURED_APPS += examples/nsh
-MAXOPTIMIZATION = -Os
+# The NSH application library
+CONFIGURED_APPS += nshlib
+CONFIGURED_APPS += system/readline
-MODULE_STACKSIZE = 1800
+#ifeq ($(CONFIG_USBDEV),y)
+#ifeq ($(CONFIG_CDCACM),y)
+CONFIGURED_APPS += examples/cdcacm
+#endif
+#endif
diff --git a/nuttx-configs/px4-stm32f4discovery/nsh/defconfig b/nuttx-configs/px4-stm32f4discovery/nsh/defconfig
new file mode 100644
index 000000000..6a2470bea
--- /dev/null
+++ b/nuttx-configs/px4-stm32f4discovery/nsh/defconfig
@@ -0,0 +1,897 @@
+#
+# Automatically generated file; DO NOT EDIT.
+# Nuttx/ Configuration
+#
+CONFIG_NUTTX_NEWCONFIG=y
+
+#
+# Build Setup
+#
+# CONFIG_EXPERIMENTAL is not set
+# CONFIG_HOST_LINUX is not set
+CONFIG_HOST_OSX=y
+# CONFIG_HOST_WINDOWS is not set
+# CONFIG_HOST_OTHER is not set
+
+#
+# Build Configuration
+#
+CONFIG_APPS_DIR="../apps"
+# CONFIG_BUILD_2PASS is not set
+
+#
+# Binary Output Formats
+#
+# CONFIG_RRLOAD_BINARY is not set
+# CONFIG_INTELHEX_BINARY is not set
+# CONFIG_MOTOROLA_SREC is not set
+CONFIG_RAW_BINARY=y
+
+#
+# Customize Header Files
+#
+# CONFIG_ARCH_STDBOOL_H is not set
+CONFIG_ARCH_MATH_H=y
+# CONFIG_ARCH_FLOAT_H is not set
+# CONFIG_ARCH_STDARG_H is not set
+
+#
+# Debug Options
+#
+# CONFIG_DEBUG is not set
+CONFIG_DEBUG_SYMBOLS=y
+
+#
+# System Type
+#
+# CONFIG_ARCH_8051 is not set
+CONFIG_ARCH_ARM=y
+# CONFIG_ARCH_AVR is not set
+# CONFIG_ARCH_HC is not set
+# CONFIG_ARCH_MIPS is not set
+# CONFIG_ARCH_RGMP is not set
+# CONFIG_ARCH_SH is not set
+# CONFIG_ARCH_SIM is not set
+# CONFIG_ARCH_X86 is not set
+# CONFIG_ARCH_Z16 is not set
+# CONFIG_ARCH_Z80 is not set
+CONFIG_ARCH="arm"
+
+#
+# ARM Options
+#
+# CONFIG_ARCH_CHIP_C5471 is not set
+# CONFIG_ARCH_CHIP_CALYPSO is not set
+# CONFIG_ARCH_CHIP_DM320 is not set
+# CONFIG_ARCH_CHIP_IMX is not set
+# CONFIG_ARCH_CHIP_KINETIS is not set
+# CONFIG_ARCH_CHIP_KL is not set
+# CONFIG_ARCH_CHIP_LM is not set
+# CONFIG_ARCH_CHIP_LPC17XX is not set
+# CONFIG_ARCH_CHIP_LPC214X is not set
+# CONFIG_ARCH_CHIP_LPC2378 is not set
+# CONFIG_ARCH_CHIP_LPC31XX is not set
+# CONFIG_ARCH_CHIP_LPC43XX is not set
+# CONFIG_ARCH_CHIP_NUC1XX is not set
+# CONFIG_ARCH_CHIP_SAM34 is not set
+CONFIG_ARCH_CHIP_STM32=y
+# CONFIG_ARCH_CHIP_STR71X is not set
+CONFIG_ARCH_CORTEXM4=y
+CONFIG_ARCH_FAMILY="armv7-m"
+CONFIG_ARCH_CHIP="stm32"
+CONFIG_ARMV7M_USEBASEPRI=y
+CONFIG_ARCH_HAVE_CMNVECTOR=y
+CONFIG_ARMV7M_CMNVECTOR=y
+CONFIG_ARCH_HAVE_FPU=y
+CONFIG_ARCH_FPU=y
+CONFIG_ARCH_HAVE_MPU=y
+# CONFIG_ARMV7M_MPU is not set
+
+#
+# ARMV7M Configuration Options
+#
+# CONFIG_ARMV7M_TOOLCHAIN_BUILDROOT is not set
+CONFIG_ARMV7M_TOOLCHAIN_GNU_EABI=y
+CONFIG_ARMV7M_STACKCHECK=y
+CONFIG_SERIAL_TERMIOS=y
+
+#
+# STM32 Configuration Options
+#
+# CONFIG_ARCH_CHIP_STM32L151C6 is not set
+# CONFIG_ARCH_CHIP_STM32L151C8 is not set
+# CONFIG_ARCH_CHIP_STM32L151CB is not set
+# CONFIG_ARCH_CHIP_STM32L151R6 is not set
+# CONFIG_ARCH_CHIP_STM32L151R8 is not set
+# CONFIG_ARCH_CHIP_STM32L151RB is not set
+# CONFIG_ARCH_CHIP_STM32L151V6 is not set
+# CONFIG_ARCH_CHIP_STM32L151V8 is not set
+# CONFIG_ARCH_CHIP_STM32L151VB is not set
+# CONFIG_ARCH_CHIP_STM32L152C6 is not set
+# CONFIG_ARCH_CHIP_STM32L152C8 is not set
+# CONFIG_ARCH_CHIP_STM32L152CB is not set
+# CONFIG_ARCH_CHIP_STM32L152R6 is not set
+# CONFIG_ARCH_CHIP_STM32L152R8 is not set
+# CONFIG_ARCH_CHIP_STM32L152RB is not set
+# CONFIG_ARCH_CHIP_STM32L152V6 is not set
+# CONFIG_ARCH_CHIP_STM32L152V8 is not set
+# CONFIG_ARCH_CHIP_STM32L152VB is not set
+# CONFIG_ARCH_CHIP_STM32F100C8 is not set
+# CONFIG_ARCH_CHIP_STM32F100CB is not set
+# CONFIG_ARCH_CHIP_STM32F100R8 is not set
+# CONFIG_ARCH_CHIP_STM32F100RB is not set
+# CONFIG_ARCH_CHIP_STM32F100RC is not set
+# CONFIG_ARCH_CHIP_STM32F100RD is not set
+# CONFIG_ARCH_CHIP_STM32F100RE is not set
+# CONFIG_ARCH_CHIP_STM32F100V8 is not set
+# CONFIG_ARCH_CHIP_STM32F100VB is not set
+# CONFIG_ARCH_CHIP_STM32F100VC is not set
+# CONFIG_ARCH_CHIP_STM32F100VD is not set
+# CONFIG_ARCH_CHIP_STM32F100VE is not set
+# CONFIG_ARCH_CHIP_STM32F103C4 is not set
+# CONFIG_ARCH_CHIP_STM32F103C8 is not set
+# CONFIG_ARCH_CHIP_STM32F103RET6 is not set
+# CONFIG_ARCH_CHIP_STM32F103VCT6 is not set
+# CONFIG_ARCH_CHIP_STM32F103VET6 is not set
+# CONFIG_ARCH_CHIP_STM32F103ZET6 is not set
+# CONFIG_ARCH_CHIP_STM32F105VBT7 is not set
+# CONFIG_ARCH_CHIP_STM32F107VC is not set
+# CONFIG_ARCH_CHIP_STM32F207IG is not set
+# CONFIG_ARCH_CHIP_STM32F302CB is not set
+# CONFIG_ARCH_CHIP_STM32F302CC is not set
+# CONFIG_ARCH_CHIP_STM32F302RB is not set
+# CONFIG_ARCH_CHIP_STM32F302RC is not set
+# CONFIG_ARCH_CHIP_STM32F302VB is not set
+# CONFIG_ARCH_CHIP_STM32F302VC is not set
+# CONFIG_ARCH_CHIP_STM32F303CB is not set
+# CONFIG_ARCH_CHIP_STM32F303CC is not set
+# CONFIG_ARCH_CHIP_STM32F303RB is not set
+# CONFIG_ARCH_CHIP_STM32F303RC is not set
+# CONFIG_ARCH_CHIP_STM32F303VB is not set
+# CONFIG_ARCH_CHIP_STM32F303VC is not set
+# CONFIG_ARCH_CHIP_STM32F405RG is not set
+# CONFIG_ARCH_CHIP_STM32F405VG is not set
+# CONFIG_ARCH_CHIP_STM32F405ZG is not set
+# CONFIG_ARCH_CHIP_STM32F407VE is not set
+CONFIG_ARCH_CHIP_STM32F407VG=y
+# CONFIG_ARCH_CHIP_STM32F407ZE is not set
+# CONFIG_ARCH_CHIP_STM32F407ZG is not set
+# CONFIG_ARCH_CHIP_STM32F407IE is not set
+# CONFIG_ARCH_CHIP_STM32F407IG is not set
+# CONFIG_ARCH_CHIP_STM32F427V is not set
+# CONFIG_ARCH_CHIP_STM32F427Z is not set
+# CONFIG_ARCH_CHIP_STM32F427I is not set
+# CONFIG_STM32_STM32L15XX is not set
+# CONFIG_STM32_ENERGYLITE is not set
+# CONFIG_STM32_STM32F10XX is not set
+# CONFIG_STM32_VALUELINE is not set
+# CONFIG_STM32_CONNECTIVITYLINE is not set
+# CONFIG_STM32_PERFORMANCELINE is not set
+# CONFIG_STM32_HIGHDENSITY is not set
+# CONFIG_STM32_MEDIUMDENSITY is not set
+# CONFIG_STM32_LOWDENSITY is not set
+# CONFIG_STM32_STM32F20XX is not set
+# CONFIG_STM32_STM32F30XX is not set
+CONFIG_STM32_STM32F40XX=y
+# CONFIG_STM32_STM32F427 is not set
+# CONFIG_STM32_DFU is not set
+
+#
+# STM32 Peripheral Support
+#
+CONFIG_STM32_ADC1=y
+# CONFIG_STM32_ADC2 is not set
+# CONFIG_STM32_ADC3 is not set
+CONFIG_STM32_BKPSRAM=y
+# CONFIG_STM32_CAN1 is not set
+# CONFIG_STM32_CAN2 is not set
+CONFIG_STM32_CCMDATARAM=y
+# CONFIG_STM32_CRC is not set
+# CONFIG_STM32_CRYP is not set
+CONFIG_STM32_DMA1=y
+CONFIG_STM32_DMA2=y
+# CONFIG_STM32_DAC1 is not set
+# CONFIG_STM32_DAC2 is not set
+# CONFIG_STM32_DCMI is not set
+# CONFIG_STM32_ETHMAC is not set
+# CONFIG_STM32_FSMC is not set
+# CONFIG_STM32_HASH is not set
+CONFIG_STM32_I2C1=y
+# CONFIG_STM32_I2C2 is not set
+# CONFIG_STM32_I2C3 is not set
+CONFIG_STM32_OTGFS=y
+# CONFIG_STM32_OTGHS is not set
+CONFIG_STM32_PWR=y
+# CONFIG_STM32_RNG is not set
+# CONFIG_STM32_SDIO is not set
+CONFIG_STM32_SPI1=y
+# CONFIG_STM32_SPI2 is not set
+# CONFIG_STM32_SPI3 is not set
+# CONFIG_STM32_SPI4 is not set
+# CONFIG_STM32_SPI5 is not set
+# CONFIG_STM32_SPI6 is not set
+CONFIG_STM32_SYSCFG=y
+CONFIG_STM32_TIM1=y
+# CONFIG_STM32_TIM2 is not set
+CONFIG_STM32_TIM3=y
+CONFIG_STM32_TIM4=y
+# CONFIG_STM32_TIM5 is not set
+# CONFIG_STM32_TIM6 is not set
+# CONFIG_STM32_TIM7 is not set
+# CONFIG_STM32_TIM8 is not set
+CONFIG_STM32_TIM9=y
+CONFIG_STM32_TIM10=y
+CONFIG_STM32_TIM11=y
+# CONFIG_STM32_TIM12 is not set
+# CONFIG_STM32_TIM13 is not set
+# CONFIG_STM32_TIM14 is not set
+# CONFIG_STM32_USART1 is not set
+CONFIG_STM32_USART2=y
+# CONFIG_STM32_USART3 is not set
+# CONFIG_STM32_UART4 is not set
+# CONFIG_STM32_UART5 is not set
+# CONFIG_STM32_USART6 is not set
+# CONFIG_STM32_UART7 is not set
+# CONFIG_STM32_UART8 is not set
+# CONFIG_STM32_IWDG is not set
+# CONFIG_STM32_WWDG is not set
+CONFIG_STM32_ADC=y
+CONFIG_STM32_SPI=y
+CONFIG_STM32_I2C=y
+
+#
+# Alternate Pin Mapping
+#
+CONFIG_STM32_FLASH_PREFETCH=y
+# CONFIG_STM32_JTAG_DISABLE is not set
+# CONFIG_STM32_JTAG_FULL_ENABLE is not set
+# CONFIG_STM32_JTAG_NOJNTRST_ENABLE is not set
+CONFIG_STM32_JTAG_SW_ENABLE=y
+CONFIG_STM32_DISABLE_IDLE_SLEEP_DURING_DEBUG=y
+# CONFIG_STM32_FORCEPOWER is not set
+# CONFIG_ARCH_BOARD_STM32_CUSTOM_CLOCKCONFIG is not set
+# CONFIG_STM32_CCMEXCLUDE is not set
+CONFIG_STM32_DMACAPABLE=y
+# CONFIG_STM32_TIM1_PWM is not set
+# CONFIG_STM32_TIM3_PWM is not set
+# CONFIG_STM32_TIM4_PWM is not set
+# CONFIG_STM32_TIM9_PWM is not set
+# CONFIG_STM32_TIM10_PWM is not set
+# CONFIG_STM32_TIM11_PWM is not set
+# CONFIG_STM32_TIM1_ADC is not set
+# CONFIG_STM32_TIM3_ADC is not set
+# CONFIG_STM32_TIM4_ADC is not set
+CONFIG_STM32_USART=y
+
+#
+# U[S]ART Configuration
+#
+# CONFIG_USART2_RS485 is not set
+CONFIG_USART2_RXDMA=y
+CONFIG_SERIAL_DISABLE_REORDERING=y
+CONFIG_STM32_USART_SINGLEWIRE=y
+
+#
+# SPI Configuration
+#
+# CONFIG_STM32_SPI_INTERRUPTS is not set
+# CONFIG_STM32_SPI_DMA is not set
+
+#
+# I2C Configuration
+#
+# CONFIG_STM32_I2C_DYNTIMEO is not set
+CONFIG_STM32_I2CTIMEOSEC=0
+CONFIG_STM32_I2CTIMEOMS=500
+CONFIG_STM32_I2CTIMEOTICKS=500
+# CONFIG_STM32_I2C_DUTY16_9 is not set
+
+#
+# USB Host Configuration
+#
+
+#
+# USB Device Configuration
+#
+
+#
+# External Memory Configuration
+#
+
+#
+# Architecture Options
+#
+# CONFIG_ARCH_NOINTC is not set
+# CONFIG_ARCH_VECNOTIRQ is not set
+CONFIG_ARCH_DMA=y
+CONFIG_ARCH_IRQPRIO=y
+# CONFIG_CUSTOM_STACK is not set
+# CONFIG_ADDRENV is not set
+CONFIG_ARCH_HAVE_VFORK=y
+CONFIG_ARCH_STACKDUMP=y
+# CONFIG_ENDIAN_BIG is not set
+# CONFIG_ARCH_HAVE_RAMFUNCS is not set
+CONFIG_ARCH_HAVE_RAMVECTORS=y
+# CONFIG_ARCH_RAMVECTORS is not set
+
+#
+# Board Settings
+#
+CONFIG_BOARD_LOOPSPERMSEC=16717
+# CONFIG_ARCH_CALIBRATION is not set
+CONFIG_DRAM_START=0x20000000
+CONFIG_DRAM_SIZE=196608
+CONFIG_ARCH_HAVE_INTERRUPTSTACK=y
+CONFIG_ARCH_INTERRUPTSTACK=4096
+
+#
+# Boot options
+#
+# CONFIG_BOOT_RUNFROMEXTSRAM is not set
+CONFIG_BOOT_RUNFROMFLASH=y
+# CONFIG_BOOT_RUNFROMISRAM is not set
+# CONFIG_BOOT_RUNFROMSDRAM is not set
+# CONFIG_BOOT_COPYTORAM is not set
+
+#
+# Board Selection
+#
+CONFIG_ARCH_BOARD_CUSTOM=y
+CONFIG_ARCH_BOARD=""
+
+#
+# Common Board Options
+#
+CONFIG_NSH_MMCSDMINOR=0
+
+#
+# Board-Specific Options
+#
+
+#
+# RTOS Features
+#
+# CONFIG_BOARD_INITIALIZE is not set
+CONFIG_MSEC_PER_TICK=1
+CONFIG_RR_INTERVAL=0
+CONFIG_SCHED_INSTRUMENTATION=y
+CONFIG_TASK_NAME_SIZE=24
+# CONFIG_SCHED_HAVE_PARENT is not set
+# CONFIG_JULIAN_TIME is not set
+CONFIG_START_YEAR=1970
+CONFIG_START_MONTH=1
+CONFIG_START_DAY=1
+CONFIG_DEV_CONSOLE=y
+# CONFIG_MUTEX_TYPES is not set
+CONFIG_PRIORITY_INHERITANCE=y
+CONFIG_SEM_PREALLOCHOLDERS=0
+CONFIG_SEM_NNESTPRIO=8
+# CONFIG_FDCLONE_DISABLE is not set
+CONFIG_FDCLONE_STDIO=y
+CONFIG_SDCLONE_DISABLE=y
+CONFIG_SCHED_WAITPID=y
+# CONFIG_SCHED_STARTHOOK is not set
+CONFIG_SCHED_ATEXIT=y
+CONFIG_SCHED_ATEXIT_MAX=1
+# CONFIG_SCHED_ONEXIT is not set
+CONFIG_USER_ENTRYPOINT="nsh_main"
+# CONFIG_DISABLE_OS_API is not set
+
+#
+# Signal Numbers
+#
+CONFIG_SIG_SIGUSR1=1
+CONFIG_SIG_SIGUSR2=2
+CONFIG_SIG_SIGALARM=3
+CONFIG_SIG_SIGCONDTIMEDOUT=16
+CONFIG_SIG_SIGWORK=4
+
+#
+# Sizes of configurable things (0 disables)
+#
+CONFIG_MAX_TASKS=32
+CONFIG_MAX_TASK_ARGS=10
+CONFIG_NPTHREAD_KEYS=4
+CONFIG_NFILE_DESCRIPTORS=44
+CONFIG_NFILE_STREAMS=8
+CONFIG_NAME_MAX=32
+CONFIG_PREALLOC_MQ_MSGS=4
+CONFIG_MQ_MAXMSGSIZE=32
+CONFIG_MAX_WDOGPARMS=2
+CONFIG_PREALLOC_WDOGS=50
+CONFIG_PREALLOC_TIMERS=50
+
+#
+# Stack and heap information
+#
+CONFIG_IDLETHREAD_STACKSIZE=6000
+CONFIG_USERMAIN_STACKSIZE=4096
+CONFIG_PTHREAD_STACK_MIN=512
+CONFIG_PTHREAD_STACK_DEFAULT=2048
+
+#
+# Device Drivers
+#
+# CONFIG_DISABLE_POLL is not set
+CONFIG_DEV_NULL=y
+# CONFIG_DEV_ZERO is not set
+# CONFIG_LOOP is not set
+# CONFIG_RAMDISK is not set
+# CONFIG_CAN is not set
+# CONFIG_PWM is not set
+CONFIG_I2C=y
+# CONFIG_I2C_SLAVE is not set
+CONFIG_I2C_TRANSFER=y
+# CONFIG_I2C_WRITEREAD is not set
+# CONFIG_I2C_POLLED is not set
+# CONFIG_I2C_TRACE is not set
+CONFIG_ARCH_HAVE_I2CRESET=y
+CONFIG_I2C_RESET=y
+CONFIG_SPI=y
+# CONFIG_SPI_OWNBUS is not set
+CONFIG_SPI_EXCHANGE=y
+# CONFIG_SPI_CMDDATA is not set
+# CONFIG_RTC is not set
+CONFIG_WATCHDOG=y
+# CONFIG_ANALOG is not set
+# CONFIG_AUDIO_DEVICES is not set
+# CONFIG_BCH is not set
+# CONFIG_INPUT is not set
+# CONFIG_LCD is not set
+# CONFIG_MMCSD is not set
+# CONFIG_MTD is not set
+CONFIG_PIPES=y
+# CONFIG_PM is not set
+# CONFIG_POWER is not set
+# CONFIG_SENSORS is not set
+CONFIG_SERIAL=y
+# CONFIG_DEV_LOWCONSOLE is not set
+CONFIG_SERIAL_REMOVABLE=y
+# CONFIG_16550_UART is not set
+CONFIG_ARCH_HAVE_USART2=y
+CONFIG_MCU_SERIAL=y
+CONFIG_STANDARD_SERIAL=y
+CONFIG_SERIAL_NPOLLWAITERS=2
+CONFIG_USART2_SERIAL_CONSOLE=y
+# CONFIG_NO_SERIAL_CONSOLE is not set
+
+#
+# USART2 Configuration
+#
+CONFIG_USART2_RXBUFSIZE=512
+CONFIG_USART2_TXBUFSIZE=512
+CONFIG_USART2_BAUD=57600
+CONFIG_USART2_BITS=8
+CONFIG_USART2_PARITY=0
+CONFIG_USART2_2STOP=0
+# CONFIG_USART2_IFLOWCONTROL is not set
+# CONFIG_USART2_OFLOWCONTROL is not set
+# CONFIG_SERIAL_IFLOWCONTROL is not set
+# CONFIG_SERIAL_OFLOWCONTROL is not set
+CONFIG_USBDEV=y
+
+#
+# USB Device Controller Driver Options
+#
+# CONFIG_USBDEV_ISOCHRONOUS is not set
+# CONFIG_USBDEV_DUALSPEED is not set
+# CONFIG_USBDEV_SELFPOWERED is not set
+CONFIG_USBDEV_BUSPOWERED=y
+CONFIG_USBDEV_MAXPOWER=500
+# CONFIG_USBDEV_DMA is not set
+# CONFIG_USBDEV_TRACE is not set
+
+#
+# USB Device Class Driver Options
+#
+# CONFIG_USBDEV_COMPOSITE is not set
+# CONFIG_PL2303 is not set
+CONFIG_CDCACM=y
+# CONFIG_CDCACM_CONSOLE is not set
+CONFIG_CDCACM_EP0MAXPACKET=64
+CONFIG_CDCACM_EPINTIN=1
+CONFIG_CDCACM_EPINTIN_FSSIZE=64
+CONFIG_CDCACM_EPINTIN_HSSIZE=64
+CONFIG_CDCACM_EPBULKOUT=3
+CONFIG_CDCACM_EPBULKOUT_FSSIZE=64
+CONFIG_CDCACM_EPBULKOUT_HSSIZE=512
+CONFIG_CDCACM_EPBULKIN=2
+CONFIG_CDCACM_EPBULKIN_FSSIZE=64
+CONFIG_CDCACM_EPBULKIN_HSSIZE=512
+CONFIG_CDCACM_NWRREQS=4
+CONFIG_CDCACM_NRDREQS=4
+CONFIG_CDCACM_BULKIN_REQLEN=96
+CONFIG_CDCACM_RXBUFSIZE=512
+CONFIG_CDCACM_TXBUFSIZE=2048
+CONFIG_CDCACM_VENDORID=0x26ac
+CONFIG_CDCACM_PRODUCTID=0x0011
+CONFIG_CDCACM_VENDORSTR="3D Robotics"
+CONFIG_CDCACM_PRODUCTSTR="PX4 FMU v2.x"
+# CONFIG_USBMSC is not set
+# CONFIG_USBHOST is not set
+# CONFIG_WIRELESS is not set
+
+#
+# System Logging Device Options
+#
+
+#
+# System Logging
+#
+# CONFIG_RAMLOG is not set
+
+#
+# Networking Support
+#
+# CONFIG_NET is not set
+
+#
+# File Systems
+#
+
+#
+# File system configuration
+#
+# CONFIG_DISABLE_MOUNTPOINT is not set
+# CONFIG_FS_RAMMAP is not set
+CONFIG_FS_FAT=y
+# CONFIG_FAT_LCNAMES is not set
+# CONFIG_FAT_LFN is not set
+# CONFIG_FS_FATTIME is not set
+# CONFIG_FAT_DMAMEMORY is not set
+CONFIG_FS_NXFFS=y
+CONFIG_NXFFS_PREALLOCATED=y
+CONFIG_NXFFS_ERASEDSTATE=0xff
+CONFIG_NXFFS_PACKTHRESHOLD=32
+CONFIG_NXFFS_MAXNAMLEN=32
+CONFIG_NXFFS_TAILTHRESHOLD=2048
+CONFIG_FS_ROMFS=y
+# CONFIG_FS_SMARTFS is not set
+CONFIG_FS_BINFS=y
+
+#
+# System Logging
+#
+# CONFIG_SYSLOG_ENABLE is not set
+# CONFIG_SYSLOG is not set
+
+#
+# Graphics Support
+#
+# CONFIG_NX is not set
+
+#
+# Memory Management
+#
+# CONFIG_MM_MULTIHEAP is not set
+# CONFIG_MM_SMALL is not set
+CONFIG_MM_REGIONS=2
+CONFIG_GRAN=y
+# CONFIG_GRAN_SINGLE is not set
+# CONFIG_GRAN_INTR is not set
+
+#
+# Audio Support
+#
+# CONFIG_AUDIO is not set
+
+#
+# Binary Formats
+#
+# CONFIG_BINFMT_DISABLE is not set
+# CONFIG_BINFMT_EXEPATH is not set
+# CONFIG_NXFLAT is not set
+# CONFIG_ELF is not set
+CONFIG_BUILTIN=y
+# CONFIG_PIC is not set
+# CONFIG_SYMTAB_ORDEREDBYNAME is not set
+
+#
+# Library Routines
+#
+
+#
+# Standard C Library Options
+#
+CONFIG_STDIO_BUFFER_SIZE=32
+CONFIG_STDIO_LINEBUFFER=y
+CONFIG_NUNGET_CHARS=2
+CONFIG_LIB_HOMEDIR="/"
+# CONFIG_NOPRINTF_FIELDWIDTH is not set
+CONFIG_LIBC_FLOATINGPOINT=y
+CONFIG_LIB_RAND_ORDER=1
+# CONFIG_EOL_IS_CR is not set
+# CONFIG_EOL_IS_LF is not set
+# CONFIG_EOL_IS_BOTH_CRLF is not set
+CONFIG_EOL_IS_EITHER_CRLF=y
+# CONFIG_LIBC_EXECFUNCS is not set
+CONFIG_POSIX_SPAWN_PROXY_STACKSIZE=1024
+CONFIG_TASK_SPAWN_DEFAULT_STACKSIZE=2048
+CONFIG_LIBC_STRERROR=y
+# CONFIG_LIBC_STRERROR_SHORT is not set
+# CONFIG_LIBC_PERROR_STDOUT is not set
+CONFIG_ARCH_LOWPUTC=y
+CONFIG_LIB_SENDFILE_BUFSIZE=512
+# CONFIG_ARCH_ROMGETC is not set
+CONFIG_ARCH_OPTIMIZED_FUNCTIONS=y
+CONFIG_ARCH_MEMCPY=y
+# CONFIG_ARCH_MEMCMP is not set
+# CONFIG_ARCH_MEMMOVE is not set
+# CONFIG_ARCH_MEMSET is not set
+# CONFIG_MEMSET_OPTSPEED is not set
+# CONFIG_ARCH_STRCHR is not set
+# CONFIG_ARCH_STRCMP is not set
+# CONFIG_ARCH_STRCPY is not set
+# CONFIG_ARCH_STRNCPY is not set
+# CONFIG_ARCH_STRLEN is not set
+# CONFIG_ARCH_STRNLEN is not set
+# CONFIG_ARCH_BZERO is not set
+
+#
+# Non-standard Library Support
+#
+CONFIG_SCHED_WORKQUEUE=y
+CONFIG_SCHED_HPWORK=y
+CONFIG_SCHED_WORKPRIORITY=192
+CONFIG_SCHED_WORKPERIOD=5000
+CONFIG_SCHED_WORKSTACKSIZE=4000
+CONFIG_SCHED_LPWORK=y
+CONFIG_SCHED_LPWORKPRIORITY=50
+CONFIG_SCHED_LPWORKPERIOD=50000
+CONFIG_SCHED_LPWORKSTACKSIZE=4000
+# CONFIG_LIB_KBDCODEC is not set
+# CONFIG_LIB_SLCDCODEC is not set
+
+#
+# Basic CXX Support
+#
+CONFIG_C99_BOOL8=y
+CONFIG_HAVE_CXX=y
+CONFIG_HAVE_CXXINITIALIZE=y
+# CONFIG_CXX_NEWLONG is not set
+
+#
+# uClibc++ Standard C++ Library
+#
+# CONFIG_UCLIBCXX is not set
+
+#
+# Application Configuration
+#
+
+#
+# Built-In Applications
+#
+CONFIG_BUILTIN_PROXY_STACKSIZE=1024
+
+#
+# Examples
+#
+# CONFIG_EXAMPLES_BUTTONS is not set
+# CONFIG_EXAMPLES_CAN is not set
+CONFIG_EXAMPLES_CDCACM=y
+# CONFIG_EXAMPLES_COMPOSITE is not set
+# CONFIG_EXAMPLES_CXXTEST is not set
+# CONFIG_EXAMPLES_DHCPD is not set
+# CONFIG_EXAMPLES_ELF is not set
+# CONFIG_EXAMPLES_FTPC is not set
+# CONFIG_EXAMPLES_FTPD is not set
+# CONFIG_EXAMPLES_HELLO is not set
+# CONFIG_EXAMPLES_HELLOXX is not set
+# CONFIG_EXAMPLES_JSON is not set
+# CONFIG_EXAMPLES_HIDKBD is not set
+# CONFIG_EXAMPLES_KEYPADTEST is not set
+# CONFIG_EXAMPLES_IGMP is not set
+# CONFIG_EXAMPLES_LCDRW is not set
+# CONFIG_EXAMPLES_MM is not set
+# CONFIG_EXAMPLES_MODBUS is not set
+CONFIG_EXAMPLES_MOUNT=y
+# CONFIG_EXAMPLES_NRF24L01TERM is not set
+CONFIG_EXAMPLES_NSH=y
+# CONFIG_EXAMPLES_NULL is not set
+# CONFIG_EXAMPLES_NX is not set
+# CONFIG_EXAMPLES_NXCONSOLE is not set
+# CONFIG_EXAMPLES_NXFFS is not set
+# CONFIG_EXAMPLES_NXFLAT is not set
+# CONFIG_EXAMPLES_NXHELLO is not set
+# CONFIG_EXAMPLES_NXIMAGE is not set
+# CONFIG_EXAMPLES_NXLINES is not set
+# CONFIG_EXAMPLES_NXTEXT is not set
+# CONFIG_EXAMPLES_OSTEST is not set
+# CONFIG_EXAMPLES_PASHELLO is not set
+# CONFIG_EXAMPLES_PIPE is not set
+# CONFIG_EXAMPLES_POSIXSPAWN is not set
+# CONFIG_EXAMPLES_QENCODER is not set
+# CONFIG_EXAMPLES_RGMP is not set
+# CONFIG_EXAMPLES_ROMFS is not set
+# CONFIG_EXAMPLES_SENDMAIL is not set
+# CONFIG_EXAMPLES_SERLOOP is not set
+# CONFIG_EXAMPLES_SLCD is not set
+# CONFIG_EXAMPLES_SMART_TEST is not set
+# CONFIG_EXAMPLES_SMART is not set
+# CONFIG_EXAMPLES_TCPECHO is not set
+# CONFIG_EXAMPLES_TELNETD is not set
+# CONFIG_EXAMPLES_THTTPD is not set
+# CONFIG_EXAMPLES_TIFF is not set
+# CONFIG_EXAMPLES_TOUCHSCREEN is not set
+# CONFIG_EXAMPLES_UDP is not set
+# CONFIG_EXAMPLES_UIP is not set
+# CONFIG_EXAMPLES_USBSERIAL is not set
+# CONFIG_EXAMPLES_USBMSC is not set
+# CONFIG_EXAMPLES_USBTERM is not set
+# CONFIG_EXAMPLES_WATCHDOG is not set
+
+#
+# Graphics Support
+#
+# CONFIG_TIFF is not set
+
+#
+# Interpreters
+#
+# CONFIG_INTERPRETERS_FICL is not set
+# CONFIG_INTERPRETERS_PCODE is not set
+
+#
+# Network Utilities
+#
+
+#
+# Networking Utilities
+#
+# CONFIG_NETUTILS_CODECS is not set
+# CONFIG_NETUTILS_DHCPC is not set
+# CONFIG_NETUTILS_DHCPD is not set
+# CONFIG_NETUTILS_FTPC is not set
+# CONFIG_NETUTILS_FTPD is not set
+# CONFIG_NETUTILS_JSON is not set
+# CONFIG_NETUTILS_RESOLV is not set
+# CONFIG_NETUTILS_SMTP is not set
+# CONFIG_NETUTILS_TELNETD is not set
+# CONFIG_NETUTILS_TFTPC is not set
+# CONFIG_NETUTILS_THTTPD is not set
+# CONFIG_NETUTILS_UIPLIB is not set
+# CONFIG_NETUTILS_WEBCLIENT is not set
+
+#
+# FreeModBus
+#
+# CONFIG_MODBUS is not set
+
+#
+# NSH Library
+#
+CONFIG_NSH_LIBRARY=y
+CONFIG_NSH_BUILTIN_APPS=y
+
+#
+# Disable Individual commands
+#
+# CONFIG_NSH_DISABLE_CAT is not set
+# CONFIG_NSH_DISABLE_CD is not set
+# CONFIG_NSH_DISABLE_CP is not set
+# CONFIG_NSH_DISABLE_DD is not set
+# CONFIG_NSH_DISABLE_ECHO is not set
+# CONFIG_NSH_DISABLE_EXEC is not set
+# CONFIG_NSH_DISABLE_EXIT is not set
+# CONFIG_NSH_DISABLE_FREE is not set
+# CONFIG_NSH_DISABLE_GET is not set
+# CONFIG_NSH_DISABLE_HELP is not set
+# CONFIG_NSH_DISABLE_HEXDUMP is not set
+# CONFIG_NSH_DISABLE_IFCONFIG is not set
+# CONFIG_NSH_DISABLE_KILL is not set
+# CONFIG_NSH_DISABLE_LOSETUP is not set
+# CONFIG_NSH_DISABLE_LS is not set
+# CONFIG_NSH_DISABLE_MB is not set
+# CONFIG_NSH_DISABLE_MKDIR is not set
+# CONFIG_NSH_DISABLE_MKFATFS is not set
+# CONFIG_NSH_DISABLE_MKFIFO is not set
+# CONFIG_NSH_DISABLE_MKRD is not set
+# CONFIG_NSH_DISABLE_MH is not set
+# CONFIG_NSH_DISABLE_MOUNT is not set
+# CONFIG_NSH_DISABLE_MW is not set
+# CONFIG_NSH_DISABLE_NSFMOUNT is not set
+# CONFIG_NSH_DISABLE_PS is not set
+# CONFIG_NSH_DISABLE_PING is not set
+# CONFIG_NSH_DISABLE_PUT is not set
+# CONFIG_NSH_DISABLE_PWD is not set
+# CONFIG_NSH_DISABLE_RM is not set
+# CONFIG_NSH_DISABLE_RMDIR is not set
+# CONFIG_NSH_DISABLE_SET is not set
+# CONFIG_NSH_DISABLE_SH is not set
+# CONFIG_NSH_DISABLE_SLEEP is not set
+# CONFIG_NSH_DISABLE_TEST is not set
+# CONFIG_NSH_DISABLE_UMOUNT is not set
+# CONFIG_NSH_DISABLE_UNSET is not set
+# CONFIG_NSH_DISABLE_USLEEP is not set
+# CONFIG_NSH_DISABLE_WGET is not set
+# CONFIG_NSH_DISABLE_XD is not set
+
+#
+# Configure Command Options
+#
+# CONFIG_NSH_CMDOPT_DF_H is not set
+CONFIG_NSH_CODECS_BUFSIZE=128
+CONFIG_NSH_FILEIOSIZE=512
+CONFIG_NSH_STRERROR=y
+CONFIG_NSH_LINELEN=128
+CONFIG_NSH_MAXARGUMENTS=12
+CONFIG_NSH_NESTDEPTH=8
+# CONFIG_NSH_DISABLESCRIPT is not set
+# CONFIG_NSH_DISABLEBG is not set
+CONFIG_NSH_ROMFSETC=y
+# CONFIG_NSH_ROMFSRC is not set
+CONFIG_NSH_ROMFSMOUNTPT="/etc"
+CONFIG_NSH_INITSCRIPT="init.d/rcS"
+CONFIG_NSH_ROMFSDEVNO=0
+CONFIG_NSH_ROMFSSECTSIZE=128
+CONFIG_NSH_ARCHROMFS=y
+CONFIG_NSH_FATDEVNO=0
+CONFIG_NSH_FATSECTSIZE=512
+CONFIG_NSH_FATNSECTORS=1024
+CONFIG_NSH_FATMOUNTPT="/tmp"
+CONFIG_NSH_CONSOLE=y
+# CONFIG_NSH_USBCONSOLE is not set
+
+#
+# USB Trace Support
+#
+# CONFIG_NSH_CONDEV is not set
+CONFIG_NSH_ARCHINIT=y
+
+#
+# NxWidgets/NxWM
+#
+
+#
+# System NSH Add-Ons
+#
+
+#
+# Custom Free Memory Command
+#
+# CONFIG_SYSTEM_FREE is not set
+
+#
+# I2C tool
+#
+# CONFIG_SYSTEM_I2CTOOL is not set
+
+#
+# FLASH Program Installation
+#
+# CONFIG_SYSTEM_INSTALL is not set
+
+#
+# FLASH Erase-all Command
+#
+
+#
+# readline()
+#
+CONFIG_SYSTEM_READLINE=y
+CONFIG_READLINE_ECHO=y
+
+#
+# Power Off
+#
+# CONFIG_SYSTEM_POWEROFF is not set
+
+#
+# RAMTRON
+#
+# CONFIG_SYSTEM_RAMTRON is not set
+
+#
+# SD Card
+#
+# CONFIG_SYSTEM_SDCARD is not set
+
+#
+# Sysinfo
+#
+CONFIG_SYSTEM_SYSINFO=y
+
+#
+# USB Monitor
+#
diff --git a/nuttx-configs/px4-stm32f4discovery/nsh/setenv.sh b/nuttx-configs/px4-stm32f4discovery/nsh/setenv.sh
new file mode 100755
index 000000000..265520997
--- /dev/null
+++ b/nuttx-configs/px4-stm32f4discovery/nsh/setenv.sh
@@ -0,0 +1,67 @@
+#!/bin/bash
+# configs/stm3240g-eval/nsh/setenv.sh
+#
+# Copyright (C) 2011 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# 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 NuttX 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.
+#
+
+if [ "$_" = "$0" ] ; then
+ echo "You must source this script, not run it!" 1>&2
+ exit 1
+fi
+
+WD=`pwd`
+if [ ! -x "setenv.sh" ]; then
+ echo "This script must be executed from the top-level NuttX build directory"
+ exit 1
+fi
+
+if [ -z "${PATH_ORIG}" ]; then
+ export PATH_ORIG="${PATH}"
+fi
+
+# This the Cygwin path to the location where I installed the RIDE
+# toolchain under windows. You will also have to edit this if you install
+# the RIDE toolchain in any other location
+#export TOOLCHAIN_BIN="/cygdrive/c/Program Files (x86)/Raisonance/Ride/arm-gcc/bin"
+
+# This the Cygwin path to the location where I installed the CodeSourcery
+# toolchain under windows. You will also have to edit this if you install
+# the CodeSourcery toolchain in any other location
+export TOOLCHAIN_BIN="/cygdrive/c/Program Files (x86)/CodeSourcery/Sourcery G++ Lite/bin"
+
+# This the Cygwin path to the location where I build the buildroot
+# toolchain.
+#export TOOLCHAIN_BIN="${WD}/../misc/buildroot/build_arm_nofpu/staging_dir/bin"
+
+# Add the path to the toolchain to the PATH varialble
+export PATH="${TOOLCHAIN_BIN}:/sbin:/usr/sbin:${PATH_ORIG}"
+
+echo "PATH : ${PATH}"
diff --git a/nuttx-configs/px4-stm32f4discovery/scripts/ld.script b/nuttx-configs/px4-stm32f4discovery/scripts/ld.script
new file mode 100644
index 000000000..f39a95c45
--- /dev/null
+++ b/nuttx-configs/px4-stm32f4discovery/scripts/ld.script
@@ -0,0 +1,149 @@
+/****************************************************************************
+ * configs/px4fmu-v1/scripts/ld.script
+ *
+ * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * 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 NuttX 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.
+ *
+ ****************************************************************************/
+
+/* The STM32F40VGG has 1024Kb of FLASH beginning at address 0x0800:0000 and
+ * 192Kb of SRAM. SRAM is split up into three blocks:
+ *
+ * 1) 112Kb of SRAM beginning at address 0x2000:0000
+ * 2) 16Kb of SRAM beginning at address 0x2001:c000
+ * 3) 64Kb of CCM SRAM beginning at address 0x1000:0000
+ *
+ * When booting from FLASH, FLASH memory is aliased to address 0x0000:0000
+ * where the code expects to begin execution by jumping to the entry point in
+ * the 0x0800:0000 address range.
+ *
+ * The first 0x4000 of flash is reserved for the bootloader.
+ */
+
+MEMORY
+{
+ flash (rx) : ORIGIN = 0x08004000, LENGTH = 1008K
+ sram (rwx) : ORIGIN = 0x20000000, LENGTH = 128K
+ ccsram (rwx) : ORIGIN = 0x10000000, LENGTH = 64K
+}
+
+OUTPUT_ARCH(arm)
+
+ENTRY(__start) /* treat __start as the anchor for dead code stripping */
+EXTERN(_vectors) /* force the vectors to be included in the output */
+
+/*
+ * Ensure that abort() is present in the final object. The exception handling
+ * code pulled in by libgcc.a requires it (and that code cannot be easily avoided).
+ */
+EXTERN(abort)
+
+SECTIONS
+{
+ .text : {
+ _stext = ABSOLUTE(.);
+ *(.vectors)
+ *(.text .text.*)
+ *(.fixup)
+ *(.gnu.warning)
+ *(.rodata .rodata.*)
+ *(.gnu.linkonce.t.*)
+ *(.got)
+ *(.gcc_except_table)
+ *(.gnu.linkonce.r.*)
+ _etext = ABSOLUTE(.);
+
+ /*
+ * This is a hack to make the newlib libm __errno() call
+ * use the NuttX get_errno_ptr() function.
+ */
+ __errno = get_errno_ptr;
+ } > flash
+
+ /*
+ * Init functions (static constructors and the like)
+ */
+ .init_section : {
+ _sinit = ABSOLUTE(.);
+ KEEP(*(.init_array .init_array.*))
+ _einit = ABSOLUTE(.);
+ } > flash
+
+ /*
+ * Construction data for parameters.
+ */
+ __param ALIGN(4): {
+ __param_start = ABSOLUTE(.);
+ KEEP(*(__param*))
+ __param_end = ABSOLUTE(.);
+ } > flash
+
+ .ARM.extab : {
+ *(.ARM.extab*)
+ } > flash
+
+ __exidx_start = ABSOLUTE(.);
+ .ARM.exidx : {
+ *(.ARM.exidx*)
+ } > flash
+ __exidx_end = ABSOLUTE(.);
+
+ _eronly = ABSOLUTE(.);
+
+ .data : {
+ _sdata = ABSOLUTE(.);
+ *(.data .data.*)
+ *(.gnu.linkonce.d.*)
+ CONSTRUCTORS
+ _edata = ABSOLUTE(.);
+ } > sram AT > flash
+
+ .bss : {
+ _sbss = ABSOLUTE(.);
+ *(.bss .bss.*)
+ *(.gnu.linkonce.b.*)
+ *(COMMON)
+ _ebss = ABSOLUTE(.);
+ } > sram
+
+ /* Stabs debugging sections. */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ .comment 0 : { *(.comment) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_info 0 : { *(.debug_info) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ .debug_aranges 0 : { *(.debug_aranges) }
+}
diff --git a/nuttx-configs/px4-stm32f4discovery/src/Makefile b/nuttx-configs/px4-stm32f4discovery/src/Makefile
new file mode 100644
index 000000000..d4276f7fc
--- /dev/null
+++ b/nuttx-configs/px4-stm32f4discovery/src/Makefile
@@ -0,0 +1,84 @@
+############################################################################
+# configs/px4fmu/src/Makefile
+#
+# Copyright (C) 2011 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# 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 NuttX 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 $(TOPDIR)/Make.defs
+
+CFLAGS += -I$(TOPDIR)/sched
+
+ASRCS =
+AOBJS = $(ASRCS:.S=$(OBJEXT))
+
+CSRCS = empty.c
+COBJS = $(CSRCS:.c=$(OBJEXT))
+
+SRCS = $(ASRCS) $(CSRCS)
+OBJS = $(AOBJS) $(COBJS)
+
+ARCH_SRCDIR = $(TOPDIR)/arch/$(CONFIG_ARCH)/src
+ifeq ($(WINTOOL),y)
+ CFLAGS += -I "${shell cygpath -w $(ARCH_SRCDIR)/chip}" \
+ -I "${shell cygpath -w $(ARCH_SRCDIR)/common}" \
+ -I "${shell cygpath -w $(ARCH_SRCDIR)/armv7-m}"
+else
+ CFLAGS += -I$(ARCH_SRCDIR)/chip -I$(ARCH_SRCDIR)/common -I$(ARCH_SRCDIR)/armv7-m
+endif
+
+all: libboard$(LIBEXT)
+
+$(AOBJS): %$(OBJEXT): %.S
+ $(call ASSEMBLE, $<, $@)
+
+$(COBJS) $(LINKOBJS): %$(OBJEXT): %.c
+ $(call COMPILE, $<, $@)
+
+libboard$(LIBEXT): $(OBJS)
+ $(call ARCHIVE, $@, $(OBJS))
+
+.depend: Makefile $(SRCS)
+ $(Q) $(MKDEP) $(CC) -- $(CFLAGS) -- $(SRCS) >Make.dep
+ $(Q) touch $@
+
+depend: .depend
+
+clean:
+ $(call DELFILE, libboard$(LIBEXT))
+ $(call CLEAN)
+
+distclean: clean
+ $(call DELFILE, Make.dep)
+ $(call DELFILE, .depend)
+
+-include Make.dep
+
diff --git a/nuttx-configs/px4-stm32f4discovery/src/empty.c b/nuttx-configs/px4-stm32f4discovery/src/empty.c
new file mode 100644
index 000000000..ace900866
--- /dev/null
+++ b/nuttx-configs/px4-stm32f4discovery/src/empty.c
@@ -0,0 +1,4 @@
+/*
+ * There are no source files here, but libboard.a can't be empty, so
+ * we have this empty source file to keep it company.
+ */
diff --git a/nuttx-configs/px4fmu-v1/nsh/defconfig b/nuttx-configs/px4fmu-v1/nsh/defconfig
index cd410051c..2c9a21f21 100644
--- a/nuttx-configs/px4fmu-v1/nsh/defconfig
+++ b/nuttx-configs/px4fmu-v1/nsh/defconfig
@@ -326,7 +326,7 @@ CONFIG_DRAM_START=0x20000000
CONFIG_DRAM_SIZE=196608
CONFIG_ARCH_HAVE_INTERRUPTSTACK=y
# The actual usage is 420 bytes
-CONFIG_ARCH_INTERRUPTSTACK=1500
+CONFIG_ARCH_INTERRUPTSTACK=750
#
# Boot options
diff --git a/src/drivers/ardrone_interface/ardrone_interface.c b/src/drivers/ardrone_interface/ardrone_interface.c
index 7d4b7d880..53d98ba9a 100644
--- a/src/drivers/ardrone_interface/ardrone_interface.c
+++ b/src/drivers/ardrone_interface/ardrone_interface.c
@@ -108,8 +108,9 @@ usage(const char *reason)
*/
int ardrone_interface_main(int argc, char *argv[])
{
- if (argc < 1)
+ if (argc < 2) {
usage("missing command");
+ }
if (!strcmp(argv[1], "start")) {
diff --git a/src/drivers/blinkm/blinkm.cpp b/src/drivers/blinkm/blinkm.cpp
index d749a0d7b..cfa59eb3a 100644
--- a/src/drivers/blinkm/blinkm.cpp
+++ b/src/drivers/blinkm/blinkm.cpp
@@ -316,7 +316,6 @@ BlinkM::init()
ret = I2C::init();
if (ret != OK) {
- warnx("I2C init failed");
return ret;
}
@@ -970,7 +969,7 @@ blinkm_main(int argc, char *argv[])
if (OK != g_blinkm->init()) {
delete g_blinkm;
g_blinkm = nullptr;
- errx(1, "init failed");
+ errx(1, "no BlinkM found");
}
exit(0);
diff --git a/src/drivers/boards/px4-stm32f4discovery/board_config.h b/src/drivers/boards/px4-stm32f4discovery/board_config.h
new file mode 100644
index 000000000..dd66abc19
--- /dev/null
+++ b/src/drivers/boards/px4-stm32f4discovery/board_config.h
@@ -0,0 +1,136 @@
+/****************************************************************************
+ *
+ * Copyright (c) 2013, 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 board_config.h
+ *
+ * PX4-STM32F4Discovery internal definitions
+ */
+
+#pragma once
+
+/****************************************************************************************************
+ * Included Files
+ ****************************************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/compiler.h>
+#include <stdint.h>
+
+__BEGIN_DECLS
+
+/* these headers are not C++ safe */
+#include <stm32.h>
+#include <arch/board/board.h>
+
+#define UDID_START 0x1FFF7A10
+
+/****************************************************************************************************
+ * Definitions
+ ****************************************************************************************************/
+/* Configuration ************************************************************************************/
+
+/* PX4FMU GPIOs ***********************************************************************************/
+/* LEDs */
+/* LEDs */
+
+#define GPIO_LED1 (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_50MHz|\
+ GPIO_OUTPUT_CLEAR|GPIO_PORTD|GPIO_PIN12)
+#define GPIO_LED2 (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_50MHz|\
+ GPIO_OUTPUT_CLEAR|GPIO_PORTD|GPIO_PIN13)
+#define GPIO_LED3 (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_50MHz|\
+ GPIO_OUTPUT_CLEAR|GPIO_PORTD|GPIO_PIN14)
+#define GPIO_LED4 (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_50MHz|\
+ GPIO_OUTPUT_CLEAR|GPIO_PORTD|GPIO_PIN15)
+
+/* SPI chip selects */
+#define GPIO_SPI_CS_MEMS (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_50MHz|GPIO_OUTPUT_SET|GPIO_PORTE|GPIO_PIN3)
+
+/* USB OTG FS
+ *
+ * PA9 OTG_FS_VBUS VBUS sensing
+ */
+#define GPIO_OTGFS_VBUS (GPIO_INPUT|GPIO_FLOAT|GPIO_SPEED_100MHz|GPIO_OPENDRAIN|GPIO_PORTA|GPIO_PIN9)
+
+/* High-resolution timer */
+#define HRT_TIMER 8 /* use timer8 for the HRT */
+#define HRT_TIMER_CHANNEL 1 /* use capture/compare channel */
+
+/****************************************************************************************************
+ * Public Types
+ ****************************************************************************************************/
+
+/****************************************************************************************************
+ * Public data
+ ****************************************************************************************************/
+
+#ifndef __ASSEMBLY__
+
+/****************************************************************************************************
+ * Public Functions
+ ****************************************************************************************************/
+
+/****************************************************************************************************
+ * Name: stm32_spiinitialize
+ *
+ * Description:
+ * Called to configure SPI chip select GPIO pins for the PX4FMU board.
+ *
+ ****************************************************************************************************/
+
+extern void stm32_spiinitialize(void);
+
+extern void stm32_usbinitialize(void);
+
+/****************************************************************************
+ * Name: nsh_archinitialize
+ *
+ * Description:
+ * Perform architecture specific initialization for NSH.
+ *
+ * CONFIG_NSH_ARCHINIT=y :
+ * Called from the NSH library
+ *
+ * CONFIG_BOARD_INITIALIZE=y, CONFIG_NSH_LIBRARY=y, &&
+ * CONFIG_NSH_ARCHINIT=n :
+ * Called from board_initialize().
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NSH_LIBRARY
+int nsh_archinitialize(void);
+#endif
+
+#endif /* __ASSEMBLY__ */
+
+__END_DECLS
diff --git a/src/drivers/boards/px4-stm32f4discovery/module.mk b/src/drivers/boards/px4-stm32f4discovery/module.mk
new file mode 100644
index 000000000..6b75c08e9
--- /dev/null
+++ b/src/drivers/boards/px4-stm32f4discovery/module.mk
@@ -0,0 +1,7 @@
+#
+# Board-specific startup code for the PX4-STM32F4Discovery
+#
+
+SRCS = px4discovery_init.c \
+ px4discovery_usb.c \
+ px4discovery_led.c
diff --git a/src/drivers/boards/px4-stm32f4discovery/px4discovery_init.c b/src/drivers/boards/px4-stm32f4discovery/px4discovery_init.c
new file mode 100644
index 000000000..fb1b28236
--- /dev/null
+++ b/src/drivers/boards/px4-stm32f4discovery/px4discovery_init.c
@@ -0,0 +1,173 @@
+/****************************************************************************
+ *
+ * Copyright (C) 2012 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 px4discovery_init.c
+ *
+ * PX4-stm32f4discovery specific early startup code. This file implements the
+ * nsh_archinitialize() function that is called early by nsh during startup.
+ *
+ * Code here is run before the rcS script is invoked; it should start required
+ * subsystems and perform board-specific initialisation.
+ */
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <debug.h>
+#include <errno.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/spi.h>
+#include <nuttx/i2c.h>
+#include <nuttx/sdio.h>
+#include <nuttx/mmcsd.h>
+#include <nuttx/analog/adc.h>
+#include <nuttx/gran.h>
+
+#include <stm32.h>
+#include "board_config.h"
+#include <stm32_uart.h>
+
+#include <arch/board/board.h>
+
+#include <drivers/drv_hrt.h>
+#include <drivers/drv_led.h>
+
+#include <systemlib/cpuload.h>
+#include <systemlib/perf_counter.h>
+
+/****************************************************************************
+ * Pre-Processor Definitions
+ ****************************************************************************/
+
+/* Configuration ************************************************************/
+
+/* Debug ********************************************************************/
+
+#ifdef CONFIG_CPP_HAVE_VARARGS
+# ifdef CONFIG_DEBUG
+# define message(...) lowsyslog(__VA_ARGS__)
+# else
+# define message(...) printf(__VA_ARGS__)
+# endif
+#else
+# ifdef CONFIG_DEBUG
+# define message lowsyslog
+# else
+# define message printf
+# endif
+#endif
+
+/****************************************************************************
+ * Protected Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/************************************************************************************
+ * Name: stm32_boardinitialize
+ *
+ * Description:
+ * All STM32 architectures must provide the following entry point. This entry point
+ * is called early in the intitialization -- after all memory has been configured
+ * and mapped but before any devices have been initialized.
+ *
+ ************************************************************************************/
+
+__EXPORT void
+stm32_boardinitialize(void)
+{
+ /* configure LEDs */
+ up_ledinit();
+}
+
+/****************************************************************************
+ * Name: nsh_archinitialize
+ *
+ * Description:
+ * Perform architecture specific initialization
+ *
+ ****************************************************************************/
+
+#include <math.h>
+
+#ifdef __cplusplus
+__EXPORT int matherr(struct __exception *e)
+{
+ return 1;
+}
+#else
+__EXPORT int matherr(struct exception *e)
+{
+ return 1;
+}
+#endif
+
+__EXPORT int nsh_archinitialize(void)
+{
+
+ /* configure the high-resolution time/callout interface */
+ hrt_init();
+
+ /* configure CPU load estimation */
+#ifdef CONFIG_SCHED_INSTRUMENTATION
+ cpuload_initialize_once();
+#endif
+
+ /* set up the serial DMA polling */
+ static struct hrt_call serial_dma_call;
+ struct timespec ts;
+
+ /*
+ * Poll at 1ms intervals for received bytes that have not triggered
+ * a DMA event.
+ */
+ ts.tv_sec = 0;
+ ts.tv_nsec = 1000000;
+
+ hrt_call_every(&serial_dma_call,
+ ts_to_abstime(&ts),
+ ts_to_abstime(&ts),
+ (hrt_callout)stm32_serial_dma_poll,
+ NULL);
+
+ return OK;
+}
diff --git a/src/drivers/boards/px4-stm32f4discovery/px4discovery_led.c b/src/drivers/boards/px4-stm32f4discovery/px4discovery_led.c
new file mode 100644
index 000000000..1f42843ed
--- /dev/null
+++ b/src/drivers/boards/px4-stm32f4discovery/px4discovery_led.c
@@ -0,0 +1,97 @@
+/****************************************************************************
+ *
+ * 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
+ * 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 px4discovery_led.c
+ *
+ * PX4-stm32f4discovery LED backend.
+ */
+
+#include <nuttx/config.h>
+
+#include <stdbool.h>
+
+#include "stm32.h"
+#include "board_config.h"
+
+#include <arch/board/board.h>
+
+/*
+ * Ideally we'd be able to get these from up_internal.h,
+ * but since we want to be able to disable the NuttX use
+ * of leds for system indication at will and there is no
+ * separate switch, we need to build independent of the
+ * CONFIG_ARCH_LEDS configuration switch.
+ */
+__BEGIN_DECLS
+extern void led_init(void);
+extern void led_on(int led);
+extern void led_off(int led);
+extern void led_toggle(int led);
+__END_DECLS
+
+__EXPORT void led_init()
+{
+ /* Configure LED1 GPIO for output */
+
+ stm32_configgpio(GPIO_LED1);
+}
+
+__EXPORT void led_on(int led)
+{
+ if (led == 1)
+ {
+ /* Pull down to switch on */
+ stm32_gpiowrite(GPIO_LED1, false);
+ }
+}
+
+__EXPORT void led_off(int led)
+{
+ if (led == 1)
+ {
+ /* Pull up to switch off */
+ stm32_gpiowrite(GPIO_LED1, true);
+ }
+}
+
+__EXPORT void led_toggle(int led)
+{
+ if (led == 1)
+ {
+ if (stm32_gpioread(GPIO_LED1))
+ stm32_gpiowrite(GPIO_LED1, false);
+ else
+ stm32_gpiowrite(GPIO_LED1, true);
+ }
+}
diff --git a/src/drivers/boards/px4-stm32f4discovery/px4discovery_usb.c b/src/drivers/boards/px4-stm32f4discovery/px4discovery_usb.c
new file mode 100644
index 000000000..887ca67ef
--- /dev/null
+++ b/src/drivers/boards/px4-stm32f4discovery/px4discovery_usb.c
@@ -0,0 +1,108 @@
+/****************************************************************************
+ *
+ * Copyright (C) 2012 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 px4discovery_usb.c
+ *
+ * Board-specific USB functions.
+ */
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <debug.h>
+
+#include <nuttx/usb/usbdev.h>
+#include <nuttx/usb/usbdev_trace.h>
+
+#include <up_arch.h>
+#include <stm32.h>
+#include "board_config.h"
+
+/************************************************************************************
+ * Definitions
+ ************************************************************************************/
+
+/************************************************************************************
+ * Private Functions
+ ************************************************************************************/
+
+/************************************************************************************
+ * Public Functions
+ ************************************************************************************/
+
+/************************************************************************************
+ * Name: stm32_usbinitialize
+ *
+ * Description:
+ * Called to setup USB-related GPIO pins for the PX4-STM32F4Discovery board.
+ *
+ ************************************************************************************/
+
+__EXPORT void stm32_usbinitialize(void)
+{
+ /* The OTG FS has an internal soft pull-up */
+
+ /* Configure the OTG FS VBUS sensing GPIO, Power On, and Overcurrent GPIOs */
+
+#ifdef CONFIG_STM32_OTGFS
+ stm32_configgpio(GPIO_OTGFS_VBUS);
+ /* XXX We only support device mode
+ stm32_configgpio(GPIO_OTGFS_PWRON);
+ stm32_configgpio(GPIO_OTGFS_OVER);
+ */
+#endif
+}
+
+/************************************************************************************
+ * Name: stm32_usbsuspend
+ *
+ * Description:
+ * Board logic must provide the stm32_usbsuspend logic if the USBDEV driver is
+ * used. This function is called whenever the USB enters or leaves suspend mode.
+ * This is an opportunity for the board logic to shutdown clocks, power, etc.
+ * while the USB is suspended.
+ *
+ ************************************************************************************/
+
+__EXPORT void stm32_usbsuspend(FAR struct usbdev_s *dev, bool resume)
+{
+ ulldbg("resume: %d\n", resume);
+}
+
diff --git a/src/drivers/boards/px4fmu-v1/px4fmu_init.c b/src/drivers/boards/px4fmu-v1/px4fmu_init.c
index 293021f8b..c7d4f1ce4 100644
--- a/src/drivers/boards/px4fmu-v1/px4fmu_init.c
+++ b/src/drivers/boards/px4fmu-v1/px4fmu_init.c
@@ -216,8 +216,6 @@ __EXPORT int nsh_archinitialize(void)
SPI_SELECT(spi1, PX4_SPIDEV_MPU, false);
up_udelay(20);
- message("[boot] Successfully initialized SPI port 1\r\n");
-
/*
* If SPI2 is enabled in the defconfig, we loose some ADC pins as chip selects.
* Keep the SPI2 init optional and conditionally initialize the ADC pins
@@ -243,7 +241,6 @@ __EXPORT int nsh_archinitialize(void)
/* Get the SPI port for the microSD slot */
- message("[boot] Initializing SPI port 3\n");
spi3 = up_spiinitialize(3);
if (!spi3) {
@@ -252,8 +249,6 @@ __EXPORT int nsh_archinitialize(void)
return -ENODEV;
}
- message("[boot] Successfully initialized SPI port 3\n");
-
/* Now bind the SPI interface to the MMCSD driver */
result = mmcsd_spislotinitialize(CONFIG_NSH_MMCSDMINOR, CONFIG_NSH_MMCSDSLOTNO, spi3);
@@ -263,7 +258,5 @@ __EXPORT int nsh_archinitialize(void)
return -ENODEV;
}
- message("[boot] Successfully bound SPI port 3 to the MMCSD driver\n");
-
return OK;
}
diff --git a/src/drivers/boards/px4fmu-v2/px4fmu2_init.c b/src/drivers/boards/px4fmu-v2/px4fmu2_init.c
index 9b25c574a..266642cbb 100644
--- a/src/drivers/boards/px4fmu-v2/px4fmu2_init.c
+++ b/src/drivers/boards/px4fmu-v2/px4fmu2_init.c
@@ -296,8 +296,6 @@ __EXPORT int nsh_archinitialize(void)
SPI_SELECT(spi1, PX4_SPIDEV_MPU, false);
up_udelay(20);
- message("[boot] Initialized SPI port 1 (SENSORS)\n");
-
/* Get the SPI port for the FRAM */
spi2 = up_spiinitialize(2);
@@ -317,8 +315,6 @@ __EXPORT int nsh_archinitialize(void)
SPI_SETMODE(spi2, SPIDEV_MODE3);
SPI_SELECT(spi2, SPIDEV_FLASH, false);
- message("[boot] Initialized SPI port 2 (RAMTRON FRAM)\n");
-
spi4 = up_spiinitialize(4);
/* Default SPI4 to 1MHz and de-assert the known chip selects. */
@@ -328,8 +324,6 @@ __EXPORT int nsh_archinitialize(void)
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 */
@@ -350,7 +344,6 @@ __EXPORT int nsh_archinitialize(void)
/* Then let's guess and say that there is a card in the slot. There is no card detect GPIO. */
sdio_mediachange(sdio, true);
- message("[boot] Initialized SDIO\n");
#endif
return OK;
diff --git a/src/drivers/drv_gpio.h b/src/drivers/drv_gpio.h
index be9604b6e..f18c8162d 100644
--- a/src/drivers/drv_gpio.h
+++ b/src/drivers/drv_gpio.h
@@ -110,9 +110,13 @@
/* no GPIO driver on the PX4IOv2 board */
#endif
+#ifdef CONFIG_ARCH_BOARD_PX4_STM32F4DISCOVERY
+/* no GPIO driver on the PX4_STM32F4DISCOVERY board */
+#endif
+
#if !defined(CONFIG_ARCH_BOARD_PX4IO_V1) && !defined(CONFIG_ARCH_BOARD_PX4IO_V2) && \
!defined(CONFIG_ARCH_BOARD_PX4FMU_V1) && !defined(CONFIG_ARCH_BOARD_PX4FMU_V2) && \
- !defined(CONFIG_ARCH_BOARD_AEROCORE)
+ !defined(CONFIG_ARCH_BOARD_AEROCORE) && !defined(CONFIG_ARCH_BOARD_PX4_STM32F4DISCOVERY)
# error No CONFIG_ARCH_BOARD_xxxx set
#endif
/*
diff --git a/src/drivers/drv_rc_input.h b/src/drivers/drv_rc_input.h
index d44728a71..a24d8814f 100644
--- a/src/drivers/drv_rc_input.h
+++ b/src/drivers/drv_rc_input.h
@@ -65,7 +65,7 @@
/**
* Maximum RSSI value
*/
-#define RC_INPUT_RSSI_MAX 255
+#define RC_INPUT_RSSI_MAX 100
/**
* @addtogroup topics
diff --git a/src/drivers/hmc5883/hmc5883.cpp b/src/drivers/hmc5883/hmc5883.cpp
index 3a3848446..5bf88da3d 100644
--- a/src/drivers/hmc5883/hmc5883.cpp
+++ b/src/drivers/hmc5883/hmc5883.cpp
@@ -1490,8 +1490,9 @@ start(enum HMC5883_BUS busid, enum Rotation rotation)
started |= start_bus(bus_options[i], rotation);
}
- if (!started)
- errx(1, "driver start failed");
+ if (!started) {
+ exit(1);
+ }
}
/**
diff --git a/src/drivers/hott/hott_sensors/hott_sensors.cpp b/src/drivers/hott/hott_sensors/hott_sensors.cpp
index 1aade450b..4ac7e4bdf 100644
--- a/src/drivers/hott/hott_sensors/hott_sensors.cpp
+++ b/src/drivers/hott/hott_sensors/hott_sensors.cpp
@@ -197,7 +197,7 @@ hott_sensors_thread_main(int argc, char *argv[])
int
hott_sensors_main(int argc, char *argv[])
{
- if (argc < 1) {
+ if (argc < 2) {
errx(1, "missing command\n%s", commandline_usage);
}
diff --git a/src/drivers/hott/hott_telemetry/hott_telemetry.cpp b/src/drivers/hott/hott_telemetry/hott_telemetry.cpp
index 17a24d104..43df0cb8c 100644
--- a/src/drivers/hott/hott_telemetry/hott_telemetry.cpp
+++ b/src/drivers/hott/hott_telemetry/hott_telemetry.cpp
@@ -223,7 +223,7 @@ hott_telemetry_thread_main(int argc, char *argv[])
int
hott_telemetry_main(int argc, char *argv[])
{
- if (argc < 1) {
+ if (argc < 2) {
errx(1, "missing command\n%s", commandline_usage);
}
diff --git a/src/drivers/md25/md25_main.cpp b/src/drivers/md25/md25_main.cpp
index 7e5904d05..d25d16fa1 100644
--- a/src/drivers/md25/md25_main.cpp
+++ b/src/drivers/md25/md25_main.cpp
@@ -97,8 +97,9 @@ usage(const char *reason)
int md25_main(int argc, char *argv[])
{
- if (argc < 1)
+ if (argc < 2) {
usage("missing command");
+ }
if (!strcmp(argv[1], "start")) {
diff --git a/src/drivers/px4flow/px4flow.cpp b/src/drivers/px4flow/px4flow.cpp
index 8ea7a6170..b343a3e30 100644
--- a/src/drivers/px4flow/px4flow.cpp
+++ b/src/drivers/px4flow/px4flow.cpp
@@ -674,7 +674,7 @@ fail:
g_dev = nullptr;
}
- errx(1, "driver start failed");
+ errx(1, "no PX4 FLOW connected");
}
/**
diff --git a/src/drivers/px4io/px4io.cpp b/src/drivers/px4io/px4io.cpp
index 33125699f..e5636ff0f 100644
--- a/src/drivers/px4io/px4io.cpp
+++ b/src/drivers/px4io/px4io.cpp
@@ -303,6 +303,10 @@ private:
uint64_t _battery_last_timestamp;///< last amp hour calculation timestamp
bool _cb_flighttermination; ///< true if the flight termination circuit breaker is enabled
+ int32_t _rssi_pwm_chan; ///< RSSI PWM input channel
+ int32_t _rssi_pwm_max; ///< max RSSI input on PWM channel
+ int32_t _rssi_pwm_min; ///< min RSSI input on PWM channel
+
#ifdef CONFIG_ARCH_BOARD_PX4FMU_V1
bool _dsm_vcc_ctl; ///< true if relay 1 controls DSM satellite RX power
#endif
@@ -524,7 +528,10 @@ PX4IO::PX4IO(device::Device *interface) :
_battery_amp_bias(0),
_battery_mamphour_total(0),
_battery_last_timestamp(0),
- _cb_flighttermination(true)
+ _cb_flighttermination(true),
+ _rssi_pwm_chan(0),
+ _rssi_pwm_max(0),
+ _rssi_pwm_min(0)
#ifdef CONFIG_ARCH_BOARD_PX4FMU_V1
, _dsm_vcc_ctl(false)
#endif
@@ -664,6 +671,10 @@ PX4IO::init()
if (_max_rc_input > RC_INPUT_MAX_CHANNELS)
_max_rc_input = RC_INPUT_MAX_CHANNELS;
+ param_get(param_find("RC_RSSI_PWM_CHAN"), &_rssi_pwm_chan);
+ param_get(param_find("RC_RSSI_PWM_MAX"), &_rssi_pwm_max);
+ param_get(param_find("RC_RSSI_PWM_MIN"), &_rssi_pwm_min);
+
/*
* Check for IO flight state - if FMU was flagged to be in
* armed state, FMU is recovering from an in-air reset.
@@ -1069,6 +1080,10 @@ PX4IO::task_main()
/* Update Circuit breakers */
_cb_flighttermination = circuit_breaker_enabled("CBRK_FLIGHTTERM", CBRK_FLIGHTTERM_KEY);
+ param_get(param_find("RC_RSSI_PWM_CHAN"), &_rssi_pwm_chan);
+ param_get(param_find("RC_RSSI_PWM_MAX"), &_rssi_pwm_max);
+ param_get(param_find("RC_RSSI_PWM_MIN"), &_rssi_pwm_min);
+
}
}
@@ -1633,6 +1648,15 @@ PX4IO::io_get_raw_rc_input(rc_input_values &input_rc)
input_rc.values[i] = regs[prolog + i];
}
+ /* get RSSI from input channel */
+ if (_rssi_pwm_chan > 0 && _rssi_pwm_chan <= RC_INPUT_MAX_CHANNELS && _rssi_pwm_max - _rssi_pwm_min != 0) {
+ int rssi = (input_rc.values[_rssi_pwm_chan - 1] - _rssi_pwm_min) /
+ ((_rssi_pwm_max - _rssi_pwm_min) / 100);
+ rssi = rssi > 100 ? 100 : rssi;
+ rssi = rssi < 0 ? 0 : rssi;
+ input_rc.rssi = rssi;
+ }
+
return ret;
}
diff --git a/src/drivers/rgbled/rgbled.cpp b/src/drivers/rgbled/rgbled.cpp
index 1e38a766e..512d6318d 100644
--- a/src/drivers/rgbled/rgbled.cpp
+++ b/src/drivers/rgbled/rgbled.cpp
@@ -625,7 +625,7 @@ rgbled_main(int argc, char *argv[])
if (g_rgbled == nullptr) {
// fall back to default bus
if (PX4_I2C_BUS_LED == PX4_I2C_BUS_EXPANSION) {
- errx(1, "init failed");
+ errx(1, "no RGB led on bus #%d", i2cdevice);
}
i2cdevice = PX4_I2C_BUS_LED;
}
@@ -640,7 +640,7 @@ rgbled_main(int argc, char *argv[])
if (OK != g_rgbled->init()) {
delete g_rgbled;
g_rgbled = nullptr;
- errx(1, "init failed");
+ errx(1, "no RGB led on bus #%d", i2cdevice);
}
}
diff --git a/src/drivers/roboclaw/roboclaw_main.cpp b/src/drivers/roboclaw/roboclaw_main.cpp
index 83086fd7c..ea7178076 100644
--- a/src/drivers/roboclaw/roboclaw_main.cpp
+++ b/src/drivers/roboclaw/roboclaw_main.cpp
@@ -92,8 +92,9 @@ static void usage()
int roboclaw_main(int argc, char *argv[])
{
- if (argc < 1)
+ if (argc < 2) {
usage();
+ }
if (!strcmp(argv[1], "start")) {
diff --git a/src/drivers/sf0x/sf0x.cpp b/src/drivers/sf0x/sf0x.cpp
index d6599c036..66641d640 100644
--- a/src/drivers/sf0x/sf0x.cpp
+++ b/src/drivers/sf0x/sf0x.cpp
@@ -114,6 +114,7 @@ protected:
virtual int probe();
private:
+ char _port[20];
float _min_distance;
float _max_distance;
work_s _work;
@@ -199,8 +200,13 @@ SF0X::SF0X(const char *port) :
_comms_errors(perf_alloc(PC_COUNT, "sf0x_comms_errors")),
_buffer_overflows(perf_alloc(PC_COUNT, "sf0x_buffer_overflows"))
{
+ /* store port name */
+ strncpy(_port, port, sizeof(_port));
+ /* enforce null termination */
+ _port[sizeof(_port) - 1] = '\0';
+
/* open fd */
- _fd = ::open(port, O_RDWR | O_NOCTTY | O_NONBLOCK);
+ _fd = ::open(_port, O_RDWR | O_NOCTTY | O_NONBLOCK);
if (_fd < 0) {
warnx("FAIL: laser fd");
@@ -633,7 +639,7 @@ SF0X::cycle()
/* fds initialized? */
if (_fd < 0) {
/* open fd */
- _fd = ::open(SF0X_DEFAULT_PORT, O_RDWR | O_NOCTTY | O_NONBLOCK);
+ _fd = ::open(_port, O_RDWR | O_NOCTTY | O_NONBLOCK);
}
/* collection phase? */
diff --git a/src/drivers/stm32/tone_alarm/tone_alarm.cpp b/src/drivers/stm32/tone_alarm/tone_alarm.cpp
index 8b6847348..a18b54981 100644
--- a/src/drivers/stm32/tone_alarm/tone_alarm.cpp
+++ b/src/drivers/stm32/tone_alarm/tone_alarm.cpp
@@ -890,8 +890,9 @@ tone_alarm_main(int argc, char *argv[])
if (argc > 1) {
const char *argv1 = argv[1];
- if (!strcmp(argv1, "start"))
- play_tune(TONE_STARTUP_TUNE);
+ if (!strcmp(argv1, "start")) {
+ play_tune(TONE_STOP_TUNE);
+ }
if (!strcmp(argv1, "stop"))
play_tune(TONE_STOP_TUNE);
diff --git a/src/examples/fixedwing_control/main.c b/src/examples/fixedwing_control/main.c
index 17b27290c..1d590ae61 100644
--- a/src/examples/fixedwing_control/main.c
+++ b/src/examples/fixedwing_control/main.c
@@ -418,7 +418,7 @@ usage(const char *reason)
*/
int ex_fixedwing_control_main(int argc, char *argv[])
{
- if (argc < 1) {
+ if (argc < 2) {
usage("missing command");
}
diff --git a/src/examples/flow_position_estimator/flow_position_estimator_main.c b/src/examples/flow_position_estimator/flow_position_estimator_main.c
index f8e3f2dc5..ab67bd253 100644
--- a/src/examples/flow_position_estimator/flow_position_estimator_main.c
+++ b/src/examples/flow_position_estimator/flow_position_estimator_main.c
@@ -99,7 +99,7 @@ static void usage(const char *reason)
*/
int flow_position_estimator_main(int argc, char *argv[])
{
- if (argc < 1) {
+ if (argc < 2) {
usage("missing command");
}
diff --git a/src/examples/matlab_csv_serial/matlab_csv_serial.c b/src/examples/matlab_csv_serial/matlab_csv_serial.c
index 8e439bdac..085ef1fed 100644
--- a/src/examples/matlab_csv_serial/matlab_csv_serial.c
+++ b/src/examples/matlab_csv_serial/matlab_csv_serial.c
@@ -91,7 +91,7 @@ static void usage(const char *reason)
*/
int matlab_csv_serial_main(int argc, char *argv[])
{
- if (argc < 1) {
+ if (argc < 2) {
usage("missing command");
}
diff --git a/src/examples/publisher/publisher_start_nuttx.cpp b/src/examples/publisher/publisher_start_nuttx.cpp
index 405b3c987..4ff2cebfb 100644
--- a/src/examples/publisher/publisher_start_nuttx.cpp
+++ b/src/examples/publisher/publisher_start_nuttx.cpp
@@ -54,7 +54,7 @@ extern int main(int argc, char **argv);
extern "C" __EXPORT int publisher_main(int argc, char *argv[]);
int publisher_main(int argc, char *argv[])
{
- if (argc < 1) {
+ if (argc < 2) {
errx(1, "usage: publisher {start|stop|status}");
}
diff --git a/src/examples/px4_daemon_app/px4_daemon_app.c b/src/examples/px4_daemon_app/px4_daemon_app.c
index 860b1af78..6e99939d1 100644
--- a/src/examples/px4_daemon_app/px4_daemon_app.c
+++ b/src/examples/px4_daemon_app/px4_daemon_app.c
@@ -88,7 +88,7 @@ usage(const char *reason)
*/
int px4_daemon_app_main(int argc, char *argv[])
{
- if (argc < 1) {
+ if (argc < 2) {
usage("missing command");
}
diff --git a/src/examples/rover_steering_control/main.cpp b/src/examples/rover_steering_control/main.cpp
index 96b40b23f..41df96775 100644
--- a/src/examples/rover_steering_control/main.cpp
+++ b/src/examples/rover_steering_control/main.cpp
@@ -412,7 +412,7 @@ usage(const char *reason)
*/
int rover_steering_control_main(int argc, char *argv[])
{
- if (argc < 1) {
+ if (argc < 2) {
usage("missing command");
}
diff --git a/src/examples/subscriber/subscriber_start_nuttx.cpp b/src/examples/subscriber/subscriber_start_nuttx.cpp
index b450230c1..757e8ec52 100644
--- a/src/examples/subscriber/subscriber_start_nuttx.cpp
+++ b/src/examples/subscriber/subscriber_start_nuttx.cpp
@@ -54,7 +54,7 @@ extern int main(int argc, char **argv);
extern "C" __EXPORT int subscriber_main(int argc, char *argv[]);
int subscriber_main(int argc, char *argv[])
{
- if (argc < 1) {
+ if (argc < 2) {
errx(1, "usage: subscriber {start|stop|status}");
}
diff --git a/src/lib/rc/sumd.c b/src/lib/rc/sumd.c
index a98c986bb..cea7790ec 100644
--- a/src/lib/rc/sumd.c
+++ b/src/lib/rc/sumd.c
@@ -269,7 +269,7 @@ int sumd_decode(uint8_t byte, uint8_t *rssi, uint8_t *rx_count, uint16_t *channe
uint8_t _cnt = *rx_count + 1;
*rx_count = _cnt;
- *rssi = 255;
+ *rssi = 100;
/* received Channels */
if ((uint16_t)_rxpacket.length > max_chan_count) {
diff --git a/src/lib/version/version.h b/src/lib/version/version.h
index d8ccb6774..b79fee182 100644
--- a/src/lib/version/version.h
+++ b/src/lib/version/version.h
@@ -43,14 +43,6 @@
#ifndef VERSION_H_
#define VERSION_H_
-/*
- GIT_VERSION is defined at build time via a Makefile call to the
- git command line.
- */
-#define FREEZE_STR(s) #s
-#define STRINGIFY(s) FREEZE_STR(s)
-#define FW_GIT STRINGIFY(GIT_VERSION)
-
#ifdef CONFIG_ARCH_BOARD_PX4FMU_V1
#define HW_ARCH "PX4FMU_V1"
#endif
@@ -63,4 +55,8 @@
#define HW_ARCH "AEROCORE"
#endif
+#ifdef CONFIG_ARCH_BOARD_PX4_STM32F4DISCOVERY
+#define HW_ARCH "PX4_STM32F4DISCOVERY"
+#endif
+
#endif /* VERSION_H_ */
diff --git a/src/modules/attitude_estimator_ekf/attitude_estimator_ekf_main.cpp b/src/modules/attitude_estimator_ekf/attitude_estimator_ekf_main.cpp
index c60d70b9f..3faf63a27 100755
--- a/src/modules/attitude_estimator_ekf/attitude_estimator_ekf_main.cpp
+++ b/src/modules/attitude_estimator_ekf/attitude_estimator_ekf_main.cpp
@@ -118,13 +118,14 @@ usage(const char *reason)
*/
int attitude_estimator_ekf_main(int argc, char *argv[])
{
- if (argc < 1)
+ if (argc < 2) {
usage("missing command");
+ }
if (!strcmp(argv[1], "start")) {
if (thread_running) {
- printf("attitude_estimator_ekf already running\n");
+ warnx("already running\n");
/* this is not an error */
exit(0);
}
@@ -176,8 +177,6 @@ int attitude_estimator_ekf_main(int argc, char *argv[])
int attitude_estimator_ekf_thread_main(int argc, char *argv[])
{
-const unsigned int loop_interval_alarm = 6500; // loop interval in microseconds
-
float dt = 0.005f;
/* state vector x has the following entries [ax,ay,az||mx,my,mz||wox,woy,woz||wx,wy,wz]' */
float z_k[9] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 9.81f, 0.2f, -0.2f, 0.2f}; /**< Measurement vector */
@@ -208,14 +207,10 @@ const unsigned int loop_interval_alarm = 6500; // loop interval in microseconds
}; /**< init: identity matrix */
float debugOutput[4] = { 0.0f };
- int overloadcounter = 19;
/* Initialize filter */
AttitudeEKF_initialize();
- /* store start time to guard against too slow update rates */
- uint64_t last_run = hrt_absolute_time();
-
struct sensor_combined_s raw;
memset(&raw, 0, sizeof(raw));
struct vehicle_gps_position_s gps;
@@ -317,7 +312,7 @@ const unsigned int loop_interval_alarm = 6500; // loop interval in microseconds
orb_copy(ORB_ID(vehicle_control_mode), sub_control_mode, &control_mode);
if (!control_mode.flag_system_hil_enabled) {
- warnx("WARNING: Not getting sensors - sensor app running?");
+ warnx("WARNING: Not getting sensor data - sensor app running?");
}
} else {
@@ -446,7 +441,11 @@ const unsigned int loop_interval_alarm = 6500; // loop interval in microseconds
z_k[5] = raw.accelerometer_m_s2[2] - acc(2);
/* update magnetometer measurements */
- if (sensor_last_timestamp[2] != raw.magnetometer_timestamp) {
+ if (sensor_last_timestamp[2] != raw.magnetometer_timestamp &&
+ /* check that the mag vector is > 0 */
+ fabsf(sqrtf(raw.magnetometer_ga[0] * raw.magnetometer_ga[0] +
+ raw.magnetometer_ga[1] * raw.magnetometer_ga[1] +
+ raw.magnetometer_ga[2] * raw.magnetometer_ga[2])) > 0.1f) {
update_vect[2] = 1;
// sensor_update_hz[2] = 1e6f / (raw.timestamp - sensor_last_timestamp[2]);
sensor_last_timestamp[2] = raw.magnetometer_timestamp;
@@ -466,8 +465,8 @@ const unsigned int loop_interval_alarm = 6500; // loop interval in microseconds
math::Vector<3> v(1.0f, 0.0f, 0.4f);
- math::Vector<3> vn = Rvis * v;
-
+ math::Vector<3> vn = Rvis.transposed() * v; //Rvis is Rwr (robot respect to world) while v is respect to world. Hence Rvis must be transposed having (Rwr)' * Vw
+ // Rrw * Vw = vn. This way we have consistency
z_k[6] = vn(0);
z_k[7] = vn(1);
z_k[8] = vn(2);
@@ -477,20 +476,6 @@ const unsigned int loop_interval_alarm = 6500; // loop interval in microseconds
z_k[8] = raw.magnetometer_ga[2];
}
- uint64_t now = hrt_absolute_time();
- unsigned int time_elapsed = now - last_run;
- last_run = now;
-
- if (time_elapsed > loop_interval_alarm) {
- //TODO: add warning, cpu overload here
- // if (overloadcounter == 20) {
- // printf("CPU OVERLOAD DETECTED IN ATTITUDE ESTIMATOR EKF (%lu > %lu)\n", time_elapsed, loop_interval_alarm);
- // overloadcounter = 0;
- // }
-
- overloadcounter++;
- }
-
static bool const_initialized = false;
/* initialize with good values once we have a reasonable dt estimate */
@@ -560,8 +545,9 @@ const unsigned int loop_interval_alarm = 6500; // loop interval in microseconds
continue;
}
- if (last_data > 0 && raw.timestamp - last_data > 30000)
- printf("[attitude estimator ekf] sensor data missed! (%llu)\n", raw.timestamp - last_data);
+ if (last_data > 0 && raw.timestamp - last_data > 30000) {
+ warnx("sensor data missed! (%llu)\n", raw.timestamp - last_data);
+ }
last_data = raw.timestamp;
@@ -597,12 +583,13 @@ const unsigned int loop_interval_alarm = 6500; // loop interval in microseconds
memcpy(&att.q[0],&q.data[0],sizeof(att.q));
att.R_valid = true;
- if (isfinite(att.roll) && isfinite(att.pitch) && isfinite(att.yaw)) {
+ if (isfinite(att.q[0]) && isfinite(att.q[1])
+ && isfinite(att.q[2]) && isfinite(att.q[3])) {
// Broadcast
orb_publish(ORB_ID(vehicle_attitude), pub_att, &att);
} else {
- warnx("NaN in roll/pitch/yaw estimate!");
+ warnx("ERR: NaN estimate!");
}
perf_end(ekf_loop_perf);
diff --git a/src/modules/attitude_estimator_ekf/attitude_estimator_ekf_params.c b/src/modules/attitude_estimator_ekf/attitude_estimator_ekf_params.c
index e143f37b9..fe480e12b 100755
--- a/src/modules/attitude_estimator_ekf/attitude_estimator_ekf_params.c
+++ b/src/modules/attitude_estimator_ekf/attitude_estimator_ekf_params.c
@@ -48,49 +48,49 @@
/**
* Body angular rate process noise
*
- * @group attitude_ekf
+ * @group Attitude EKF estimator
*/
PARAM_DEFINE_FLOAT(EKF_ATT_V3_Q0, 1e-4f);
/**
* Body angular acceleration process noise
*
- * @group attitude_ekf
+ * @group Attitude EKF estimator
*/
PARAM_DEFINE_FLOAT(EKF_ATT_V3_Q1, 0.08f);
/**
* Acceleration process noise
*
- * @group attitude_ekf
+ * @group Attitude EKF estimator
*/
PARAM_DEFINE_FLOAT(EKF_ATT_V3_Q2, 0.009f);
/**
* Magnet field vector process noise
*
- * @group attitude_ekf
+ * @group Attitude EKF estimator
*/
PARAM_DEFINE_FLOAT(EKF_ATT_V3_Q3, 0.005f);
/**
* Gyro measurement noise
*
- * @group attitude_ekf
+ * @group Attitude EKF estimator
*/
PARAM_DEFINE_FLOAT(EKF_ATT_V4_R0, 0.0008f);
/**
* Accel measurement noise
*
- * @group attitude_ekf
+ * @group Attitude EKF estimator
*/
PARAM_DEFINE_FLOAT(EKF_ATT_V4_R1, 10000.0f);
/**
* Mag measurement noise
*
- * @group attitude_ekf
+ * @group Attitude EKF estimator
*/
PARAM_DEFINE_FLOAT(EKF_ATT_V4_R2, 100.0f);
@@ -102,7 +102,7 @@ PARAM_DEFINE_INT32(ATT_ACC_COMP, 2);
/**
* Moment of inertia matrix diagonal entry (1, 1)
*
- * @group attitude_ekf
+ * @group Attitude EKF estimator
* @unit kg*m^2
*/
PARAM_DEFINE_FLOAT(ATT_J11, 0.0018);
@@ -110,7 +110,7 @@ PARAM_DEFINE_FLOAT(ATT_J11, 0.0018);
/**
* Moment of inertia matrix diagonal entry (2, 2)
*
- * @group attitude_ekf
+ * @group Attitude EKF estimator
* @unit kg*m^2
*/
PARAM_DEFINE_FLOAT(ATT_J22, 0.0018);
@@ -118,7 +118,7 @@ PARAM_DEFINE_FLOAT(ATT_J22, 0.0018);
/**
* Moment of inertia matrix diagonal entry (3, 3)
*
- * @group attitude_ekf
+ * @group Attitude EKF estimator
* @unit kg*m^2
*/
PARAM_DEFINE_FLOAT(ATT_J33, 0.0037);
@@ -128,7 +128,7 @@ PARAM_DEFINE_FLOAT(ATT_J33, 0.0037);
*
* If set to != 0 the moment of inertia will be used in the estimator
*
- * @group attitude_ekf
+ * @group Attitude EKF estimator
* @min 0
* @max 1
*/
diff --git a/src/modules/attitude_estimator_so3/attitude_estimator_so3_main.cpp b/src/modules/attitude_estimator_so3/attitude_estimator_so3_main.cpp
index 9414225ca..82bcbc66f 100755
--- a/src/modules/attitude_estimator_so3/attitude_estimator_so3_main.cpp
+++ b/src/modules/attitude_estimator_so3/attitude_estimator_so3_main.cpp
@@ -136,8 +136,9 @@ usage(const char *reason)
*/
int attitude_estimator_so3_main(int argc, char *argv[])
{
- if (argc < 1)
+ if (argc < 2) {
usage("missing command");
+ }
if (!strcmp(argv[1], "start")) {
diff --git a/src/modules/commander/PreflightCheck.cpp b/src/modules/commander/PreflightCheck.cpp
new file mode 100644
index 000000000..4d9bd8ae0
--- /dev/null
+++ b/src/modules/commander/PreflightCheck.cpp
@@ -0,0 +1,343 @@
+/****************************************************************************
+*
+* Copyright (c) 2012-2015 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 PreflightCheck.cpp
+*
+* Preflight check for main system components
+*
+* @author Lorenz Meier <lorenz@px4.io>
+* @author Johan Jansen <jnsn.johan@gmail.com>
+*/
+
+#include <nuttx/config.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <math.h>
+
+#include <systemlib/err.h>
+#include <systemlib/param/param.h>
+#include <systemlib/rc_check.h>
+
+#include <drivers/drv_hrt.h>
+#include <drivers/drv_mag.h>
+#include <drivers/drv_gyro.h>
+#include <drivers/drv_accel.h>
+#include <drivers/drv_baro.h>
+#include <drivers/drv_airspeed.h>
+
+#include <uORB/topics/airspeed.h>
+
+#include <mavlink/mavlink_log.h>
+
+#include "PreflightCheck.h"
+
+namespace Commander
+{
+static bool magnometerCheck(int mavlink_fd, unsigned instance, bool optional)
+{
+ bool success = true;
+
+ char s[30];
+ sprintf(s, "%s%u", MAG_BASE_DEVICE_PATH, instance);
+ int fd = open(s, 0);
+
+ if (fd < 0) {
+ if (!optional) {
+ mavlink_and_console_log_critical(mavlink_fd,
+ "PREFLIGHT FAIL: NO MAG SENSOR #%u", instance);
+ }
+
+ return false;
+ }
+
+ int calibration_devid;
+ int ret;
+ int devid = ioctl(fd, DEVIOCGDEVICEID, 0);
+ sprintf(s, "CAL_MAG%u_ID", instance);
+ param_get(param_find(s), &(calibration_devid));
+
+ if (devid != calibration_devid) {
+ mavlink_and_console_log_critical(mavlink_fd,
+ "PREFLIGHT FAIL: MAG #%u UNCALIBRATED", instance);
+ success = false;
+ goto out;
+ }
+
+ ret = ioctl(fd, MAGIOCSELFTEST, 0);
+
+ if (ret != OK) {
+ mavlink_and_console_log_critical(mavlink_fd,
+ "PREFLIGHT FAIL: MAG #%u SELFTEST FAILED", instance);
+ success = false;
+ goto out;
+ }
+
+out:
+ close(fd);
+ return success;
+}
+
+static bool accelerometerCheck(int mavlink_fd, unsigned instance, bool optional, bool dynamic)
+{
+ bool success = true;
+
+ char s[30];
+ sprintf(s, "%s%u", ACCEL_BASE_DEVICE_PATH, instance);
+ int fd = open(s, O_RDONLY);
+
+ if (fd < 0) {
+ if (!optional) {
+ mavlink_and_console_log_critical(mavlink_fd,
+ "PREFLIGHT FAIL: NO ACCEL SENSOR #%u", instance);
+ }
+
+ return false;
+ }
+
+ int calibration_devid;
+ int ret;
+ int devid = ioctl(fd, DEVIOCGDEVICEID, 0);
+ sprintf(s, "CAL_ACC%u_ID", instance);
+ param_get(param_find(s), &(calibration_devid));
+
+ if (devid != calibration_devid) {
+ mavlink_and_console_log_critical(mavlink_fd,
+ "PREFLIGHT FAIL: ACCEL #%u UNCALIBRATED", instance);
+ success = false;
+ goto out;
+ }
+
+ ret = ioctl(fd, ACCELIOCSELFTEST, 0);
+
+ if (ret != OK) {
+ mavlink_and_console_log_critical(mavlink_fd,
+ "PREFLIGHT FAIL: ACCEL #%u SELFTEST FAILED", instance);
+ success = false;
+ goto out;
+ }
+
+ if (dynamic) {
+ /* check measurement result range */
+ struct accel_report acc;
+ ret = read(fd, &acc, sizeof(acc));
+
+ if (ret == sizeof(acc)) {
+ /* evaluate values */
+ float accel_magnitude = sqrtf(acc.x * acc.x + acc.y * acc.y + acc.z * acc.z);
+
+ if (accel_magnitude < 4.0f || accel_magnitude > 15.0f /* m/s^2 */) {
+ mavlink_and_console_log_critical(mavlink_fd, "PREFLIGHT FAIL: ACCEL RANGE, hold still on arming");
+ /* this is frickin' fatal */
+ success = false;
+ goto out;
+ }
+ } else {
+ mavlink_log_critical(mavlink_fd, "PREFLIGHT FAIL: ACCEL READ");
+ /* this is frickin' fatal */
+ success = false;
+ goto out;
+ }
+ }
+
+out:
+ close(fd);
+ return success;
+}
+
+static bool gyroCheck(int mavlink_fd, unsigned instance, bool optional)
+{
+ bool success = true;
+
+ char s[30];
+ sprintf(s, "%s%u", GYRO_BASE_DEVICE_PATH, instance);
+ int fd = open(s, 0);
+
+ if (fd < 0) {
+ if (!optional) {
+ mavlink_and_console_log_critical(mavlink_fd,
+ "PREFLIGHT FAIL: NO GYRO SENSOR #%u", instance);
+ }
+
+ return false;
+ }
+
+ int calibration_devid;
+ int ret;
+ int devid = ioctl(fd, DEVIOCGDEVICEID, 0);
+ sprintf(s, "CAL_GYRO%u_ID", instance);
+ param_get(param_find(s), &(calibration_devid));
+
+ if (devid != calibration_devid) {
+ mavlink_and_console_log_critical(mavlink_fd,
+ "PREFLIGHT FAIL: GYRO #%u UNCALIBRATED", instance);
+ success = false;
+ goto out;
+ }
+
+ ret = ioctl(fd, GYROIOCSELFTEST, 0);
+
+ if (ret != OK) {
+ mavlink_and_console_log_critical(mavlink_fd,
+ "PREFLIGHT FAIL: GYRO #%u SELFTEST FAILED", instance);
+ success = false;
+ goto out;
+ }
+
+out:
+ close(fd);
+ return success;
+}
+
+static bool baroCheck(int mavlink_fd, unsigned instance, bool optional)
+{
+ bool success = true;
+
+ char s[30];
+ sprintf(s, "%s%u", BARO_BASE_DEVICE_PATH, instance);
+ int fd = open(s, 0);
+
+ if (fd < 0) {
+ if (!optional) {
+ mavlink_and_console_log_critical(mavlink_fd,
+ "PREFLIGHT FAIL: NO BARO SENSOR #%u", instance);
+ }
+
+ return false;
+ }
+
+ close(fd);
+ return success;
+}
+
+static bool airspeedCheck(int mavlink_fd, bool optional)
+{
+ bool success = true;
+ int ret;
+ int fd = orb_subscribe(ORB_ID(airspeed));
+
+ struct airspeed_s airspeed;
+
+ if ((ret = orb_copy(ORB_ID(airspeed), fd, &airspeed)) ||
+ (hrt_elapsed_time(&airspeed.timestamp) > (500 * 1000))) {
+ mavlink_and_console_log_critical(mavlink_fd, "PREFLIGHT FAIL: AIRSPEED SENSOR MISSING");
+ success = false;
+ goto out;
+ }
+
+ if (fabsf(airspeed.indicated_airspeed_m_s > 6.0f)) {
+ mavlink_and_console_log_critical(mavlink_fd, "AIRSPEED WARNING: WIND OR CALIBRATION ISSUE");
+ // XXX do not make this fatal yet
+ }
+
+out:
+ close(fd);
+ return success;
+}
+
+bool preflightCheck(int mavlink_fd, bool checkMag, bool checkAcc, bool checkGyro,
+ bool checkBaro, bool checkAirspeed, bool checkRC, bool checkDynamic)
+{
+ bool failed = false;
+
+ /* ---- MAG ---- */
+ if (checkMag) {
+ /* check all sensors, but fail only for mandatory ones */
+ for (unsigned i = 0; i < max_optional_mag_count; i++) {
+ bool required = (i < max_mandatory_mag_count);
+
+ if (!magnometerCheck(mavlink_fd, i, !required) && required) {
+ failed = true;
+ }
+ }
+ }
+
+ /* ---- ACCEL ---- */
+ if (checkAcc) {
+ /* check all sensors, but fail only for mandatory ones */
+ for (unsigned i = 0; i < max_optional_accel_count; i++) {
+ bool required = (i < max_mandatory_accel_count);
+
+ if (!accelerometerCheck(mavlink_fd, i, !required, checkDynamic) && required) {
+ failed = true;
+ }
+ }
+ }
+
+ /* ---- GYRO ---- */
+ if (checkGyro) {
+ /* check all sensors, but fail only for mandatory ones */
+ for (unsigned i = 0; i < max_optional_gyro_count; i++) {
+ bool required = (i < max_mandatory_gyro_count);
+
+ if (!gyroCheck(mavlink_fd, i, !required) && required) {
+ failed = true;
+ }
+ }
+ }
+
+ /* ---- BARO ---- */
+ if (checkBaro) {
+ /* check all sensors, but fail only for mandatory ones */
+ for (unsigned i = 0; i < max_optional_baro_count; i++) {
+ bool required = (i < max_mandatory_baro_count);
+
+ if (!baroCheck(mavlink_fd, i, !required) && required) {
+ failed = true;
+ }
+ }
+ }
+
+ /* ---- AIRSPEED ---- */
+ if (checkAirspeed) {
+ if (!airspeedCheck(mavlink_fd, true)) {
+ failed = true;
+ }
+ }
+
+ /* ---- RC CALIBRATION ---- */
+ if (checkRC) {
+ if (rc_calibration_check(mavlink_fd) != OK) {
+ failed = true;
+ }
+ }
+
+ /* Report status */
+ return !failed;
+}
+
+}
diff --git a/src/modules/commander/PreflightCheck.h b/src/modules/commander/PreflightCheck.h
new file mode 100644
index 000000000..66947a347
--- /dev/null
+++ b/src/modules/commander/PreflightCheck.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+ *
+ * Copyright (c) 2012-2015 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 PreflightCheck.h
+ *
+ * Preflight check for main system components
+ *
+ * @author Johan Jansen <jnsn.johan@gmail.com>
+ */
+
+#pragma once
+
+namespace Commander
+{
+/**
+* Runs a preflight check on all sensors to see if they are properly calibrated and healthy
+*
+* The function won't fail the test if optional sensors are not found, however,
+* it will fail the test if optional sensors are found but not in working condition.
+*
+* @param mavlink_fd
+* Mavlink output file descriptor for feedback when a sensor fails
+* @param checkMag
+* true if the magneteometer should be checked
+* @param checkAcc
+* true if the accelerometers should be checked
+* @param checkGyro
+* true if the gyroscopes should be checked
+* @param checkBaro
+* true if the barometer should be checked
+* @param checkRC
+* true if the Remote Controller should be checked
+**/
+bool preflightCheck(int mavlink_fd, bool checkMag, bool checkAcc,
+ bool checkGyro, bool checkBaro, bool checkAirspeed, bool checkRC, bool checkDynamic = false);
+
+const unsigned max_mandatory_gyro_count = 1;
+const unsigned max_optional_gyro_count = 3;
+
+const unsigned max_mandatory_accel_count = 1;
+const unsigned max_optional_accel_count = 3;
+
+const unsigned max_mandatory_mag_count = 1;
+const unsigned max_optional_mag_count = 3;
+
+const unsigned max_mandatory_baro_count = 1;
+const unsigned max_optional_baro_count = 1;
+
+}
diff --git a/src/modules/commander/accelerometer_calibration.cpp b/src/modules/commander/accelerometer_calibration.cpp
index 409c2ea00..f83640d28 100644
--- a/src/modules/commander/accelerometer_calibration.cpp
+++ b/src/modules/commander/accelerometer_calibration.cpp
@@ -152,11 +152,10 @@ static const int ERROR = -1;
static const char *sensor_name = "accel";
-int do_accel_calibration_measurements(int mavlink_fd, float (&accel_offs)[max_accel_sens][3], float (&accel_T)[max_accel_sens][3][3], unsigned *active_sensors);
-int read_accelerometer_avg(int (&subs)[max_accel_sens], float (&accel_avg)[max_accel_sens][detect_orientation_side_count][3], unsigned orient, unsigned samples_num);
+calibrate_return do_accel_calibration_measurements(int mavlink_fd, float (&accel_offs)[max_accel_sens][3], float (&accel_T)[max_accel_sens][3][3], unsigned *active_sensors);
+calibrate_return read_accelerometer_avg(int (&subs)[max_accel_sens], float (&accel_avg)[max_accel_sens][detect_orientation_side_count][3], unsigned orient, unsigned samples_num);
int mat_invert3(float src[3][3], float dst[3][3]);
-int calculate_calibration_values(unsigned sensor, float (&accel_ref)[max_accel_sens][detect_orientation_side_count][3], float (&accel_T)[max_accel_sens][3][3], float (&accel_offs)[max_accel_sens][3], float g);
-int accel_calibration_worker(detect_orientation_return orientation, void* worker_data);
+calibrate_return calculate_calibration_values(unsigned sensor, float (&accel_ref)[max_accel_sens][detect_orientation_side_count][3], float (&accel_T)[max_accel_sens][3][3], float (&accel_offs)[max_accel_sens][3], float g);
/// Data passed to calibration worker routine
typedef struct {
@@ -171,7 +170,7 @@ int do_accel_calibration(int mavlink_fd)
int fd;
int32_t device_id[max_accel_sens];
- mavlink_and_console_log_info(mavlink_fd, CAL_STARTED_MSG, sensor_name);
+ mavlink_and_console_log_info(mavlink_fd, CAL_QGC_STARTED_MSG, sensor_name);
struct accel_scale accel_scale = {
0.0f,
@@ -202,7 +201,7 @@ int do_accel_calibration(int mavlink_fd)
close(fd);
if (res != OK) {
- mavlink_and_console_log_critical(mavlink_fd, CAL_FAILED_RESET_CAL_MSG, s);
+ mavlink_and_console_log_critical(mavlink_fd, CAL_ERROR_RESET_CAL_MSG, s);
}
}
@@ -210,13 +209,23 @@ int do_accel_calibration(int mavlink_fd)
float accel_T[max_accel_sens][3][3];
unsigned active_sensors;
+ /* measure and calculate offsets & scales */
if (res == OK) {
- /* measure and calculate offsets & scales */
- res = do_accel_calibration_measurements(mavlink_fd, accel_offs, accel_T, &active_sensors);
+ calibrate_return cal_return = do_accel_calibration_measurements(mavlink_fd, accel_offs, accel_T, &active_sensors);
+ if (cal_return == calibrate_return_cancelled) {
+ // Cancel message already displayed, nothing left to do
+ return ERROR;
+ } else if (cal_return == calibrate_return_ok) {
+ res = OK;
+ } else {
+ res = ERROR;
+ }
}
- if (res != OK || active_sensors == 0) {
- mavlink_and_console_log_critical(mavlink_fd, CAL_FAILED_SENSOR_MSG);
+ if (res != OK) {
+ if (active_sensors == 0) {
+ mavlink_and_console_log_critical(mavlink_fd, CAL_ERROR_SENSOR_MSG);
+ }
return ERROR;
}
@@ -263,7 +272,7 @@ int do_accel_calibration(int mavlink_fd)
failed |= (OK != param_set_no_notification(param_find(str), &(device_id[i])));
if (failed) {
- mavlink_and_console_log_critical(mavlink_fd, CAL_FAILED_SET_PARAMS_MSG, i);
+ mavlink_and_console_log_critical(mavlink_fd, CAL_ERROR_SET_PARAMS_MSG, i);
return ERROR;
}
@@ -271,7 +280,7 @@ int do_accel_calibration(int mavlink_fd)
fd = open(str, 0);
if (fd < 0) {
- mavlink_and_console_log_critical(mavlink_fd, "sensor does not exist");
+ mavlink_and_console_log_critical(mavlink_fd, CAL_QGC_FAILED_MSG, "sensor does not exist");
res = ERROR;
} else {
res = ioctl(fd, ACCELIOCSSCALE, (long unsigned int)&accel_scale);
@@ -279,7 +288,7 @@ int do_accel_calibration(int mavlink_fd)
}
if (res != OK) {
- mavlink_and_console_log_critical(mavlink_fd, CAL_FAILED_APPLY_CAL_MSG, i);
+ mavlink_and_console_log_critical(mavlink_fd, CAL_ERROR_APPLY_CAL_MSG, i);
}
}
@@ -288,41 +297,47 @@ int do_accel_calibration(int mavlink_fd)
res = param_save_default();
if (res != OK) {
- mavlink_and_console_log_critical(mavlink_fd, CAL_FAILED_SAVE_PARAMS_MSG);
+ mavlink_and_console_log_critical(mavlink_fd, CAL_ERROR_SAVE_PARAMS_MSG);
}
- mavlink_and_console_log_info(mavlink_fd, CAL_DONE_MSG, sensor_name);
+ /* if there is a any preflight-check system response, let the barrage of messages through */
+ usleep(200000);
+
+ mavlink_and_console_log_info(mavlink_fd, CAL_QGC_DONE_MSG, sensor_name);
} else {
- mavlink_and_console_log_critical(mavlink_fd, CAL_FAILED_MSG, sensor_name);
+ mavlink_and_console_log_critical(mavlink_fd, CAL_QGC_FAILED_MSG, sensor_name);
}
+
+ /* give this message enough time to propagate */
+ usleep(600000);
return res;
}
-int accel_calibration_worker(detect_orientation_return orientation, void* data)
+static calibrate_return accel_calibration_worker(detect_orientation_return orientation, int cancel_sub, void* data)
{
const unsigned samples_num = 3000;
accel_worker_data_t* worker_data = (accel_worker_data_t*)(data);
- mavlink_and_console_log_info(worker_data->mavlink_fd, "Hold still, starting to measure %s side", detect_orientation_str(orientation));
+ mavlink_and_console_log_info(worker_data->mavlink_fd, "[cal] Hold still, measuring %s side", detect_orientation_str(orientation));
read_accelerometer_avg(worker_data->subs, worker_data->accel_ref, orientation, samples_num);
- mavlink_and_console_log_info(worker_data->mavlink_fd, "%s side result: [ %8.4f %8.4f %8.4f ]", detect_orientation_str(orientation),
+ mavlink_and_console_log_info(worker_data->mavlink_fd, "[cal] %s side result: [%8.4f %8.4f %8.4f]", detect_orientation_str(orientation),
(double)worker_data->accel_ref[0][orientation][0],
(double)worker_data->accel_ref[0][orientation][1],
(double)worker_data->accel_ref[0][orientation][2]);
worker_data->done_count++;
- mavlink_and_console_log_info(worker_data->mavlink_fd, CAL_PROGRESS_MSG, sensor_name, 17 * worker_data->done_count);
+ mavlink_and_console_log_info(worker_data->mavlink_fd, CAL_QGC_PROGRESS_MSG, 17 * worker_data->done_count);
- return OK;
+ return calibrate_return_ok;
}
-int do_accel_calibration_measurements(int mavlink_fd, float (&accel_offs)[max_accel_sens][3], float (&accel_T)[max_accel_sens][3][3], unsigned *active_sensors)
+calibrate_return do_accel_calibration_measurements(int mavlink_fd, float (&accel_offs)[max_accel_sens][3], float (&accel_T)[max_accel_sens][3][3], unsigned *active_sensors)
{
- int result = OK;
+ calibrate_return result = calibrate_return_ok;
*active_sensors = 0;
@@ -343,7 +358,7 @@ int do_accel_calibration_measurements(int mavlink_fd, float (&accel_offs)[max_ac
for (unsigned i = 0; i < max_accel_sens; i++) {
worker_data.subs[i] = orb_subscribe_multi(ORB_ID(sensor_accel), i);
if (worker_data.subs[i] < 0) {
- result = ERROR;
+ result = calibrate_return_error;
break;
}
@@ -353,8 +368,10 @@ int do_accel_calibration_measurements(int mavlink_fd, float (&accel_offs)[max_ac
timestamps[i] = arp.timestamp;
}
- if (result == OK) {
- result = calibrate_from_orientation(mavlink_fd, data_collected, accel_calibration_worker, &worker_data);
+ if (result == calibrate_return_ok) {
+ int cancel_sub = calibrate_cancel_subscribe();
+ result = calibrate_from_orientation(mavlink_fd, cancel_sub, data_collected, accel_calibration_worker, &worker_data, false /* normal still */);
+ calibrate_cancel_unsubscribe(cancel_sub);
}
/* close all subscriptions */
@@ -370,13 +387,13 @@ int do_accel_calibration_measurements(int mavlink_fd, float (&accel_offs)[max_ac
}
}
- if (result == OK) {
+ if (result == calibrate_return_ok) {
/* calculate offsets and transform matrix */
for (unsigned i = 0; i < (*active_sensors); i++) {
result = calculate_calibration_values(i, worker_data.accel_ref, accel_T, accel_offs, CONSTANTS_ONE_G);
- if (result != OK) {
- mavlink_and_console_log_critical(mavlink_fd, "ERROR: calibration values calculation error");
+ if (result != calibrate_return_ok) {
+ mavlink_and_console_log_critical(mavlink_fd, "[cal] ERROR: calibration calculation error");
break;
}
}
@@ -388,7 +405,7 @@ int do_accel_calibration_measurements(int mavlink_fd, float (&accel_offs)[max_ac
/*
* Read specified number of accelerometer samples, calculate average and dispersion.
*/
-int read_accelerometer_avg(int (&subs)[max_accel_sens], float (&accel_avg)[max_accel_sens][detect_orientation_side_count][3], unsigned orient, unsigned samples_num)
+calibrate_return read_accelerometer_avg(int (&subs)[max_accel_sens], float (&accel_avg)[max_accel_sens][detect_orientation_side_count][3], unsigned orient, unsigned samples_num)
{
struct pollfd fds[max_accel_sens];
@@ -432,7 +449,7 @@ int read_accelerometer_avg(int (&subs)[max_accel_sens], float (&accel_avg)[max_a
}
if (errcount > samples_num / 10) {
- return ERROR;
+ return calibrate_return_error;
}
}
@@ -442,7 +459,7 @@ int read_accelerometer_avg(int (&subs)[max_accel_sens], float (&accel_avg)[max_a
}
}
- return OK;
+ return calibrate_return_ok;
}
int mat_invert3(float src[3][3], float dst[3][3])
@@ -468,7 +485,7 @@ int mat_invert3(float src[3][3], float dst[3][3])
return OK;
}
-int calculate_calibration_values(unsigned sensor, float (&accel_ref)[max_accel_sens][detect_orientation_side_count][3], float (&accel_T)[max_accel_sens][3][3], float (&accel_offs)[max_accel_sens][3], float g)
+calibrate_return calculate_calibration_values(unsigned sensor, float (&accel_ref)[max_accel_sens][detect_orientation_side_count][3], float (&accel_T)[max_accel_sens][3][3], float (&accel_offs)[max_accel_sens][3], float g)
{
/* calculate offsets */
for (unsigned i = 0; i < 3; i++) {
@@ -490,7 +507,7 @@ int calculate_calibration_values(unsigned sensor, float (&accel_ref)[max_accel_s
float mat_A_inv[3][3];
if (mat_invert3(mat_A, mat_A_inv) != OK) {
- return ERROR;
+ return calibrate_return_error;
}
/* copy results to accel_T */
@@ -501,5 +518,5 @@ int calculate_calibration_values(unsigned sensor, float (&accel_ref)[max_accel_s
}
}
- return OK;
+ return calibrate_return_ok;
}
diff --git a/src/modules/commander/airspeed_calibration.cpp b/src/modules/commander/airspeed_calibration.cpp
index 747d915ff..837a3f1e8 100644
--- a/src/modules/commander/airspeed_calibration.cpp
+++ b/src/modules/commander/airspeed_calibration.cpp
@@ -38,6 +38,7 @@
#include "airspeed_calibration.h"
#include "calibration_messages.h"
+#include "calibration_routines.h"
#include "commander_helper.h"
#include <stdio.h>
@@ -61,19 +62,20 @@ static const int ERROR = -1;
static const char *sensor_name = "dpress";
-#define HUMAN_ASPD_CAL_FAILED_MSG "Calibration failed, see http://px4.io/help/aspd"
-
static void feedback_calibration_failed(int mavlink_fd)
{
sleep(5);
- mavlink_log_critical(mavlink_fd, CAL_FAILED_MSG, sensor_name);
- mavlink_log_critical(mavlink_fd, HUMAN_ASPD_CAL_FAILED_MSG);
+ mavlink_log_critical(mavlink_fd, CAL_QGC_FAILED_MSG, sensor_name);
}
int do_airspeed_calibration(int mavlink_fd)
{
+ int result = OK;
+ unsigned calibration_counter = 0;
+ const unsigned maxcount = 3000;
+
/* give directions */
- mavlink_log_info(mavlink_fd, CAL_STARTED_MSG, sensor_name);
+ mavlink_log_info(mavlink_fd, CAL_QGC_STARTED_MSG, sensor_name);
const unsigned calibration_count = 2000;
@@ -96,11 +98,13 @@ int do_airspeed_calibration(int mavlink_fd)
paramreset_successful = true;
} else {
- mavlink_log_critical(mavlink_fd, "airspeed offset zero failed");
+ mavlink_log_critical(mavlink_fd, "[cal] airspeed offset zero failed");
}
close(fd);
}
+
+ int cancel_sub = calibrate_cancel_subscribe();
if (!paramreset_successful) {
@@ -108,26 +112,26 @@ int do_airspeed_calibration(int mavlink_fd)
float analog_scaling = 0.0f;
param_get(param_find("SENS_DPRES_ANSC"), &(analog_scaling));
if (fabsf(analog_scaling) < 0.1f) {
- mavlink_log_critical(mavlink_fd, "No airspeed sensor, see http://px4.io/help/aspd");
- close(diff_pres_sub);
- return ERROR;
+ mavlink_log_critical(mavlink_fd, "[cal] No airspeed sensor, see http://px4.io/help/aspd");
+ goto error_return;
}
/* set scaling offset parameter */
if (param_set(param_find("SENS_DPRES_OFF"), &(diff_pres_offset))) {
- mavlink_log_critical(mavlink_fd, CAL_FAILED_SET_PARAMS_MSG);
- close(diff_pres_sub);
- return ERROR;
+ mavlink_log_critical(mavlink_fd, CAL_ERROR_SET_PARAMS_MSG);
+ goto error_return;
}
}
- unsigned calibration_counter = 0;
-
- mavlink_log_critical(mavlink_fd, "Ensure sensor is not measuring wind");
+ mavlink_log_critical(mavlink_fd, "[cal] Ensure sensor is not measuring wind");
usleep(500 * 1000);
while (calibration_counter < calibration_count) {
+ if (calibrate_cancel_check(mavlink_fd, cancel_sub)) {
+ goto error_return;
+ }
+
/* wait blocking for new data */
struct pollfd fds[1];
fds[0].fd = diff_pres_sub;
@@ -142,14 +146,13 @@ int do_airspeed_calibration(int mavlink_fd)
calibration_counter++;
if (calibration_counter % (calibration_count / 20) == 0) {
- mavlink_log_info(mavlink_fd, CAL_PROGRESS_MSG, sensor_name, (calibration_counter * 80) / calibration_count);
+ mavlink_log_info(mavlink_fd, CAL_QGC_PROGRESS_MSG, (calibration_counter * 80) / calibration_count);
}
} else if (poll_ret == 0) {
/* any poll failure for 1s is a reason to abort */
feedback_calibration_failed(mavlink_fd);
- close(diff_pres_sub);
- return ERROR;
+ goto error_return;
}
}
@@ -161,16 +164,15 @@ int do_airspeed_calibration(int mavlink_fd)
airscale.offset_pa = diff_pres_offset;
if (fd_scale > 0) {
if (OK != ioctl(fd_scale, AIRSPEEDIOCSSCALE, (long unsigned int)&airscale)) {
- mavlink_log_critical(mavlink_fd, "airspeed offset update failed");
+ mavlink_log_critical(mavlink_fd, "[cal] airspeed offset update failed");
}
close(fd_scale);
}
if (param_set(param_find("SENS_DPRES_OFF"), &(diff_pres_offset))) {
- mavlink_log_critical(mavlink_fd, CAL_FAILED_SET_PARAMS_MSG);
- close(diff_pres_sub);
- return ERROR;
+ mavlink_log_critical(mavlink_fd, CAL_ERROR_SET_PARAMS_MSG);
+ goto error_return;
}
/* auto-save to EEPROM */
@@ -178,30 +180,31 @@ int do_airspeed_calibration(int mavlink_fd)
if (save_ret != 0) {
warn("WARNING: auto-save of params to storage failed");
- mavlink_log_critical(mavlink_fd, CAL_FAILED_SAVE_PARAMS_MSG);
- close(diff_pres_sub);
- return ERROR;
+ mavlink_log_critical(mavlink_fd, CAL_ERROR_SAVE_PARAMS_MSG);
+ goto error_return;
}
} else {
feedback_calibration_failed(mavlink_fd);
- close(diff_pres_sub);
- return ERROR;
+ goto error_return;
}
- mavlink_log_critical(mavlink_fd, "Offset of %d Pascal", (int)diff_pres_offset);
+ mavlink_log_critical(mavlink_fd, "[cal] Offset of %d Pascal", (int)diff_pres_offset);
/* wait 500 ms to ensure parameter propagated through the system */
usleep(500 * 1000);
- mavlink_log_critical(mavlink_fd, "Create airflow now");
+ mavlink_log_critical(mavlink_fd, "[cal] Create airflow now");
calibration_counter = 0;
- const unsigned maxcount = 3000;
/* just take a few samples and make sure pitot tubes are not reversed, timeout after ~30 seconds */
while (calibration_counter < maxcount) {
+ if (calibrate_cancel_check(mavlink_fd, cancel_sub)) {
+ goto error_return;
+ }
+
/* wait blocking for new data */
struct pollfd fds[1];
fds[0].fd = diff_pres_sub;
@@ -216,7 +219,7 @@ int do_airspeed_calibration(int mavlink_fd)
if (fabsf(diff_pres.differential_pressure_raw_pa) < 50.0f) {
if (calibration_counter % 500 == 0) {
- mavlink_log_info(mavlink_fd, "Create air pressure! (got %d, wanted: 50 Pa)",
+ mavlink_log_info(mavlink_fd, "[cal] Create air pressure! (got %d, wanted: 50 Pa)",
(int)diff_pres.differential_pressure_raw_pa);
}
continue;
@@ -224,30 +227,26 @@ int do_airspeed_calibration(int mavlink_fd)
/* do not allow negative values */
if (diff_pres.differential_pressure_raw_pa < 0.0f) {
- mavlink_log_info(mavlink_fd, "ERROR: Negative pressure difference detected! (%d Pa)",
+ mavlink_log_info(mavlink_fd, "[cal] Negative pressure difference detected (%d Pa)",
(int)diff_pres.differential_pressure_raw_pa);
- mavlink_log_critical(mavlink_fd, "Swap static and dynamic ports!");
- close(diff_pres_sub);
+ mavlink_log_info(mavlink_fd, "[cal] Swap static and dynamic ports!");
/* the user setup is wrong, wipe the calibration to force a proper re-calibration */
diff_pres_offset = 0.0f;
if (param_set(param_find("SENS_DPRES_OFF"), &(diff_pres_offset))) {
- mavlink_log_critical(mavlink_fd, CAL_FAILED_SET_PARAMS_MSG);
- close(diff_pres_sub);
- return ERROR;
+ mavlink_log_critical(mavlink_fd, CAL_ERROR_SET_PARAMS_MSG);
+ goto error_return;
}
/* save */
- mavlink_log_info(mavlink_fd, CAL_PROGRESS_MSG, sensor_name, 0);
+ mavlink_log_info(mavlink_fd, CAL_QGC_PROGRESS_MSG, 0);
(void)param_save_default();
- close(diff_pres_sub);
-
feedback_calibration_failed(mavlink_fd);
- return ERROR;
+ goto error_return;
} else {
- mavlink_log_info(mavlink_fd, "Positive pressure: OK (%d Pa)",
+ mavlink_log_info(mavlink_fd, "[cal] Positive pressure: OK (%d Pa)",
(int)diff_pres.differential_pressure_raw_pa);
break;
}
@@ -255,21 +254,30 @@ int do_airspeed_calibration(int mavlink_fd)
} else if (poll_ret == 0) {
/* any poll failure for 1s is a reason to abort */
feedback_calibration_failed(mavlink_fd);
- close(diff_pres_sub);
- return ERROR;
+ goto error_return;
}
}
if (calibration_counter == maxcount) {
feedback_calibration_failed(mavlink_fd);
- close(diff_pres_sub);
- return ERROR;
+ goto error_return;
}
- mavlink_log_info(mavlink_fd, CAL_PROGRESS_MSG, sensor_name, 100);
+ mavlink_log_info(mavlink_fd, CAL_QGC_PROGRESS_MSG, 100);
- mavlink_log_info(mavlink_fd, CAL_DONE_MSG, sensor_name);
+ mavlink_log_info(mavlink_fd, CAL_QGC_DONE_MSG, sensor_name);
tune_neutral(true);
+
+normal_return:
+ calibrate_cancel_unsubscribe(cancel_sub);
close(diff_pres_sub);
- return OK;
+
+ // This give a chance for the log messages to go out of the queue before someone else stomps on then
+ sleep(1);
+
+ return result;
+
+error_return:
+ result = ERROR;
+ goto normal_return;
}
diff --git a/src/modules/commander/calibration_messages.h b/src/modules/commander/calibration_messages.h
index 29f44dc36..7b4baae62 100644
--- a/src/modules/commander/calibration_messages.h
+++ b/src/modules/commander/calibration_messages.h
@@ -42,17 +42,25 @@
#ifndef CALIBRATION_MESSAGES_H_
#define CALIBRATION_MESSAGES_H_
-#define CAL_STARTED_MSG "%s calibration: started"
-#define CAL_DONE_MSG "%s calibration: done"
-#define CAL_FAILED_MSG "%s calibration: failed"
-#define CAL_PROGRESS_MSG "%s calibration: progress <%u>"
+// The calibration message defines which begin with CAL_QGC_ are used by QGroundControl to run a state
+// machine to provide visual feedback for calibration. As such, the text for them or semantics of when
+// they are displayed cannot be modified without causing QGC to break. If modifications are made, make
+// sure to bump the calibration version number which will cause QGC to perform log based calibration
+// instead of visual calibration until such a time as QGC is update to the new version.
-#define CAL_FAILED_UNKNOWN_ERROR "ERROR: unknown error"
-#define CAL_FAILED_SENSOR_MSG "ERROR: failed reading sensor"
-#define CAL_FAILED_RESET_CAL_MSG "ERROR: failed to reset calibration, sensor %u"
-#define CAL_FAILED_APPLY_CAL_MSG "ERROR: failed to apply calibration, sensor %u"
-#define CAL_FAILED_SET_PARAMS_MSG "ERROR: failed to set parameters, sensor %u"
-#define CAL_FAILED_SAVE_PARAMS_MSG "ERROR: failed to save parameters"
-#define CAL_FAILED_ORIENTATION_TIMEOUT "ERROR: timed out waiting for correct orientation"
+// The number in the cal started message is used to indicate the version stamp for the current calibration code.
+#define CAL_QGC_STARTED_MSG "[cal] calibration started: 1 %s"
+#define CAL_QGC_DONE_MSG "[cal] calibration done: %s"
+#define CAL_QGC_FAILED_MSG "[cal] calibration failed: %s"
+#define CAL_QGC_CANCELLED_MSG "[cal] calibration cancelled"
+#define CAL_QGC_PROGRESS_MSG "[cal] progress <%u>"
+#define CAL_QGC_ORIENTATION_DETECTED_MSG "[cal] %s orientation detected"
+#define CAL_QGC_SIDE_DONE_MSG "[cal] %s side done, rotate to a different side"
+
+#define CAL_ERROR_SENSOR_MSG "[cal] calibration failed: reading sensor"
+#define CAL_ERROR_RESET_CAL_MSG "[cal] calibration failed: to reset, sensor %u"
+#define CAL_ERROR_APPLY_CAL_MSG "[cal] calibration failed: to apply calibration, sensor %u"
+#define CAL_ERROR_SET_PARAMS_MSG "[cal] calibration failed: to set parameters, sensor %u"
+#define CAL_ERROR_SAVE_PARAMS_MSG "[cal] calibration failed: failed to save parameters"
#endif /* CALIBRATION_MESSAGES_H_ */
diff --git a/src/modules/commander/calibration_routines.cpp b/src/modules/commander/calibration_routines.cpp
index 192b8c727..7e8c0fa52 100644
--- a/src/modules/commander/calibration_routines.cpp
+++ b/src/modules/commander/calibration_routines.cpp
@@ -48,6 +48,8 @@
#include <geo/geo.h>
#include <string.h>
+#include <uORB/topics/vehicle_command.h>
+
#include "calibration_routines.h"
#include "calibration_messages.h"
#include "commander_helper.h"
@@ -230,23 +232,19 @@ int sphere_fit_least_squares(const float x[], const float y[], const float z[],
return 0;
}
-enum detect_orientation_return detect_orientation(int mavlink_fd, int accel_sub)
+enum detect_orientation_return detect_orientation(int mavlink_fd, int cancel_sub, int accel_sub, bool lenient_still_position)
{
const unsigned ndim = 3;
struct accel_report sensor;
- /* exponential moving average of accel */
- float accel_ema[ndim] = { 0.0f };
- /* max-hold dispersion of accel */
- float accel_disp[3] = { 0.0f, 0.0f, 0.0f };
- /* EMA time constant in seconds*/
- float ema_len = 0.5f;
- /* set "still" threshold to 0.25 m/s^2 */
- float still_thr2 = powf(0.25f, 2);
- /* set accel error threshold to 5m/s^2 */
- float accel_err_thr = 5.0f;
- /* still time required in us */
- hrt_abstime still_time = 2000000;
+ float accel_ema[ndim] = { 0.0f }; // exponential moving average of accel
+ float accel_disp[3] = { 0.0f, 0.0f, 0.0f }; // max-hold dispersion of accel
+ float ema_len = 0.5f; // EMA time constant in seconds
+ const float normal_still_thr = 0.25; // normal still threshold
+ float still_thr2 = powf(lenient_still_position ? (normal_still_thr * 3) : normal_still_thr, 2);
+ float accel_err_thr = 5.0f; // set accel error threshold to 5m/s^2
+ hrt_abstime still_time = lenient_still_position ? 1000000 : 1500000; // still time required in us
+
struct pollfd fds[1];
fds[0].fd = accel_sub;
fds[0].events = POLLIN;
@@ -308,7 +306,7 @@ enum detect_orientation_return detect_orientation(int mavlink_fd, int accel_sub)
/* is still now */
if (t_still == 0) {
/* first time */
- mavlink_and_console_log_info(mavlink_fd, "detected rest position, hold still...");
+ mavlink_and_console_log_info(mavlink_fd, "[cal] detected rest position, hold still...");
t_still = t;
t_timeout = t + timeout;
@@ -325,8 +323,8 @@ enum detect_orientation_return detect_orientation(int mavlink_fd, int accel_sub)
accel_disp[2] > still_thr2 * 4.0f) {
/* not still, reset still start time */
if (t_still != 0) {
- mavlink_and_console_log_info(mavlink_fd, "detected motion, hold still...");
- sleep(3);
+ mavlink_and_console_log_info(mavlink_fd, "[cal] detected motion, hold still...");
+ usleep(500000);
t_still = 0;
}
}
@@ -340,7 +338,7 @@ enum detect_orientation_return detect_orientation(int mavlink_fd, int accel_sub)
}
if (poll_errcount > 1000) {
- mavlink_and_console_log_critical(mavlink_fd, CAL_FAILED_SENSOR_MSG);
+ mavlink_and_console_log_critical(mavlink_fd, CAL_ERROR_SENSOR_MSG);
return DETECT_ORIENTATION_ERROR;
}
}
@@ -381,7 +379,7 @@ enum detect_orientation_return detect_orientation(int mavlink_fd, int accel_sub)
return DETECT_ORIENTATION_RIGHTSIDE_UP; // [ 0, 0, -g ]
}
- mavlink_and_console_log_critical(mavlink_fd, "ERROR: invalid orientation");
+ mavlink_and_console_log_critical(mavlink_fd, "[cal] ERROR: invalid orientation");
return DETECT_ORIENTATION_ERROR; // Can't detect orientation
}
@@ -401,28 +399,35 @@ const char* detect_orientation_str(enum detect_orientation_return orientation)
return rgOrientationStrs[orientation];
}
-int calibrate_from_orientation(int mavlink_fd,
- bool side_data_collected[detect_orientation_side_count],
- calibration_from_orientation_worker_t calibration_worker,
- void* worker_data)
+calibrate_return calibrate_from_orientation(int mavlink_fd,
+ int cancel_sub,
+ bool side_data_collected[detect_orientation_side_count],
+ calibration_from_orientation_worker_t calibration_worker,
+ void* worker_data,
+ bool lenient_still_position)
{
- int result = OK;
+ calibrate_return result = calibrate_return_ok;
// Setup subscriptions to onboard accel sensor
int sub_accel = orb_subscribe_multi(ORB_ID(sensor_accel), 0);
if (sub_accel < 0) {
- mavlink_and_console_log_critical(mavlink_fd, "No onboard accel found, abort");
- return ERROR;
+ mavlink_and_console_log_critical(mavlink_fd, CAL_QGC_FAILED_MSG, "No onboard accel");
+ return calibrate_return_error;
}
unsigned orientation_failures = 0;
- // Rotate through all three main positions
+ // Rotate through all requested orientation
while (true) {
- if (orientation_failures > 10) {
- result = ERROR;
- mavlink_and_console_log_info(mavlink_fd, CAL_FAILED_ORIENTATION_TIMEOUT);
+ if (calibrate_cancel_check(mavlink_fd, cancel_sub)) {
+ result = calibrate_return_cancelled;
+ break;
+ }
+
+ if (orientation_failures > 4) {
+ result = calibrate_return_error;
+ mavlink_and_console_log_critical(mavlink_fd, CAL_QGC_FAILED_MSG, "timeout: no motion");
break;
}
@@ -450,44 +455,102 @@ int calibrate_from_orientation(int mavlink_fd,
strcat(pendingStr, detect_orientation_str((enum detect_orientation_return)cur_orientation));
}
}
- mavlink_and_console_log_info(mavlink_fd, "pending:%s", pendingStr);
+ mavlink_and_console_log_info(mavlink_fd, "[cal] pending:%s", pendingStr);
- mavlink_and_console_log_info(mavlink_fd, "hold the vehicle still on one of the pending sides");
- enum detect_orientation_return orient = detect_orientation(mavlink_fd, sub_accel);
+ mavlink_and_console_log_info(mavlink_fd, "[cal] hold vehicle still on a pending side");
+ enum detect_orientation_return orient = detect_orientation(mavlink_fd, cancel_sub, sub_accel, lenient_still_position);
if (orient == DETECT_ORIENTATION_ERROR) {
orientation_failures++;
- mavlink_and_console_log_info(mavlink_fd, "detected motion, hold still...");
+ mavlink_and_console_log_info(mavlink_fd, "[cal] detected motion, hold still...");
continue;
}
/* inform user about already handled side */
if (side_data_collected[orient]) {
orientation_failures++;
- mavlink_and_console_log_info(mavlink_fd, "%s side already completed or not needed", detect_orientation_str(orient));
- mavlink_and_console_log_info(mavlink_fd, "rotate to a pending side");
+ mavlink_and_console_log_info(mavlink_fd, "[cal] %s side completed or not needed", detect_orientation_str(orient));
+ mavlink_and_console_log_info(mavlink_fd, "[cal] rotate to a pending side");
continue;
}
- mavlink_and_console_log_info(mavlink_fd, "%s orientation detected", detect_orientation_str(orient));
+ mavlink_and_console_log_info(mavlink_fd, CAL_QGC_ORIENTATION_DETECTED_MSG, detect_orientation_str(orient));
orientation_failures = 0;
// Call worker routine
- calibration_worker(orient, worker_data);
+ result = calibration_worker(orient, cancel_sub, worker_data);
+ if (result != calibrate_return_ok ) {
+ break;
+ }
- mavlink_and_console_log_info(mavlink_fd, "%s side done, rotate to a different side", detect_orientation_str(orient));
+ mavlink_and_console_log_info(mavlink_fd, CAL_QGC_SIDE_DONE_MSG, detect_orientation_str(orient));
// Note that this side is complete
side_data_collected[orient] = true;
tune_neutral(true);
- sleep(1);
+ usleep(500000);
}
if (sub_accel >= 0) {
close(sub_accel);
}
- // FIXME: Do we need an orientation complete routine?
-
return result;
}
+
+int calibrate_cancel_subscribe(void)
+{
+ return orb_subscribe(ORB_ID(vehicle_command));
+}
+
+void calibrate_cancel_unsubscribe(int cmd_sub)
+{
+ orb_unsubscribe(cmd_sub);
+}
+
+static void calibrate_answer_command(int mavlink_fd, struct vehicle_command_s &cmd, enum VEHICLE_CMD_RESULT result)
+{
+ switch (result) {
+ case VEHICLE_CMD_RESULT_ACCEPTED:
+ tune_positive(true);
+ break;
+
+ case VEHICLE_CMD_RESULT_DENIED:
+ mavlink_log_critical(mavlink_fd, "command denied during calibration: %u", cmd.command);
+ tune_negative(true);
+ break;
+
+ default:
+ break;
+ }
+}
+
+bool calibrate_cancel_check(int mavlink_fd, int cancel_sub)
+{
+ struct pollfd fds[1];
+ fds[0].fd = cancel_sub;
+ fds[0].events = POLLIN;
+
+ if (poll(&fds[0], 1, 0) > 0) {
+ struct vehicle_command_s cmd;
+ memset(&cmd, 0, sizeof(cmd));
+
+ orb_copy(ORB_ID(vehicle_command), cancel_sub, &cmd);
+
+ if (cmd.command == VEHICLE_CMD_PREFLIGHT_CALIBRATION &&
+ (int)cmd.param1 == 0 &&
+ (int)cmd.param2 == 0 &&
+ (int)cmd.param3 == 0 &&
+ (int)cmd.param4 == 0 &&
+ (int)cmd.param5 == 0 &&
+ (int)cmd.param6 == 0) {
+ calibrate_answer_command(mavlink_fd, cmd, VEHICLE_CMD_RESULT_ACCEPTED);
+ mavlink_log_critical(mavlink_fd, CAL_QGC_CANCELLED_MSG);
+ return true;
+ } else {
+ calibrate_answer_command(mavlink_fd, cmd, VEHICLE_CMD_RESULT_DENIED);
+ }
+ }
+
+ return false;
+} \ No newline at end of file
diff --git a/src/modules/commander/calibration_routines.h b/src/modules/commander/calibration_routines.h
index 8f34f0204..b8232730a 100644
--- a/src/modules/commander/calibration_routines.h
+++ b/src/modules/commander/calibration_routines.h
@@ -1,6 +1,6 @@
/****************************************************************************
*
- * Copyright (c) 2012 PX4 Development Team. All rights reserved.
+ * Copyright (c) 2015 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
@@ -31,12 +31,8 @@
*
****************************************************************************/
-/**
- * @file calibration_routines.h
- * Calibration routines definitions.
- *
- * @author Lorenz Meier <lm@inf.ethz.ch>
- */
+/// @file calibration_routines.h
+/// @authot Don Gagne <don@thegagnes.com>
/**
* Least-squares fit of a sphere to a set of points.
@@ -75,30 +71,45 @@ enum detect_orientation_return {
};
static const unsigned detect_orientation_side_count = 6;
-/**
- * Wait for vehicle to become still and detect it's orientation.
- *
- * @param mavlink_fd the MAVLink file descriptor to print output to
- * @param accel_sub Subscription to onboard accel
- *
- * @return detect_orientation)_return according to orientation when vehicle is still and ready for measurements,
- * DETECT_ORIENTATION_ERROR if vehicle is not still after 30s or orientation error is more than 5m/s^2
- */
-enum detect_orientation_return detect_orientation(int mavlink_fd, int accel_sub);
+/// Wait for vehicle to become still and detect it's orientation
+/// @return Returns detect_orientation_return according to orientation when vehicle
+/// and ready for measurements
+enum detect_orientation_return detect_orientation(int mavlink_fd, ///< Mavlink fd to write output to
+ int cancel_sub, ///< Cancel subscription from calibration_cancel_subscribe
+ int accel_sub, ///< Orb subcription to accel sensor
+ bool lenient_still_detection); ///< true: Use more lenient still position detection
-
-/**
- * Returns the human readable string representation of the orientation
- *
- * @param orientation Orientation to return string for, "error" if buffer is too small
- *
- * @return str Returned orientation string
- */
+/// Returns the human readable string representation of the orientation
+/// @param orientation Orientation to return string for, "error" if buffer is too small
const char* detect_orientation_str(enum detect_orientation_return orientation);
-typedef int (*calibration_from_orientation_worker_t)(detect_orientation_return orientation, void* worker_data);
+enum calibrate_return {
+ calibrate_return_ok,
+ calibrate_return_error,
+ calibrate_return_cancelled
+};
+
+typedef calibrate_return (*calibration_from_orientation_worker_t)(detect_orientation_return orientation, ///< Orientation which was detected
+ int cancel_sub, ///< Cancel subscription from calibration_cancel_subscribe
+ void* worker_data); ///< Opaque worker data
+
+/// Perform calibration sequence which require a rest orientation detection prior to calibration.
+/// @return OK: Calibration succeeded, ERROR: Calibration failed
+calibrate_return calibrate_from_orientation(int mavlink_fd, ///< Mavlink fd to write output to
+ int cancel_sub, ///< Cancel subscription from calibration_cancel_subscribe
+ bool side_data_collected[detect_orientation_side_count], ///< Sides for which data still needs calibration
+ calibration_from_orientation_worker_t calibration_worker, ///< Worker routine which performs the actual calibration
+ void* worker_data, ///< Opaque data passed to worker routine
+ bool lenient_still_detection); ///< true: Use more lenient still position detection
+
+/// Called at the beginning of calibration in order to subscribe to the cancel command
+/// @return Handle to vehicle_command subscription
+int calibrate_cancel_subscribe(void);
+
+/// Called to cancel the subscription to the cancel command
+/// @param cancel_sub Cancel subcription from calibration_cancel_subscribe
+void calibrate_cancel_unsubscribe(int cancel_sub);
-int calibrate_from_orientation(int mavlink_fd,
- bool side_data_collected[detect_orientation_side_count],
- calibration_from_orientation_worker_t calibration_worker,
- void* worker_data);
+/// Used to periodically check for a cancel command
+bool calibrate_cancel_check(int mavlink_fd, ///< Mavlink fd for output
+ int cancel_sub); ///< Cancel subcription fromcalibration_cancel_subscribe
diff --git a/src/modules/commander/commander.cpp b/src/modules/commander/commander.cpp
index 453d5f921..7aaf5e5cd 100644
--- a/src/modules/commander/commander.cpp
+++ b/src/modules/commander/commander.cpp
@@ -114,6 +114,7 @@
#include "baro_calibration.h"
#include "rc_calibration.h"
#include "airspeed_calibration.h"
+#include "PreflightCheck.h"
/* oddly, ERROR is not defined for c++ */
#ifdef ERROR
@@ -181,21 +182,6 @@ static struct safety_s safety;
static struct vehicle_control_mode_s control_mode;
static struct offboard_control_mode_s offboard_control_mode;
-/* tasks waiting for low prio thread */
-typedef enum {
- LOW_PRIO_TASK_NONE = 0,
- LOW_PRIO_TASK_PARAM_SAVE,
- LOW_PRIO_TASK_PARAM_LOAD,
- LOW_PRIO_TASK_GYRO_CALIBRATION,
- LOW_PRIO_TASK_MAG_CALIBRATION,
- LOW_PRIO_TASK_ALTITUDE_CALIBRATION,
- LOW_PRIO_TASK_RC_CALIBRATION,
- LOW_PRIO_TASK_ACCEL_CALIBRATION,
- LOW_PRIO_TASK_AIRSPEED_CALIBRATION
-} low_prio_task_t;
-
-static low_prio_task_t low_prio_task = LOW_PRIO_TASK_NONE;
-
/**
* The daemon app only briefly exists to start
* the background job. The stack size assigned in the
@@ -227,6 +213,8 @@ int commander_thread_main(int argc, char *argv[]);
void control_status_leds(vehicle_status_s *status, const actuator_armed_s *actuator_armed, bool changed);
+void get_circuit_breaker_params();
+
void check_valid(hrt_abstime timestamp, hrt_abstime timeout, bool valid_in, bool *valid_out, bool *changed);
transition_result_t set_main_state_rc(struct vehicle_status_s *status, struct manual_control_setpoint_s *sp_man);
@@ -261,7 +249,7 @@ void answer_command(struct vehicle_command_s &cmd, enum VEHICLE_CMD_RESULT resul
int commander_main(int argc, char *argv[])
{
- if (argc < 1) {
+ if (argc < 2) {
usage("missing command");
}
@@ -535,9 +523,9 @@ bool handle_command(struct vehicle_status_s *status_local, const struct safety_s
break;
case VEHICLE_CMD_COMPONENT_ARM_DISARM: {
+
// Adhere to MAVLink specs, but base on knowledge that these fundamentally encode ints
// for logic state parameters
-
if (static_cast<int>(cmd->param1 + 0.5f) != 0 && static_cast<int>(cmd->param1 + 0.5f) != 1) {
mavlink_log_critical(mavlink_fd, "Unsupported ARM_DISARM param: %.3f", (double)cmd->param1);
@@ -549,6 +537,16 @@ bool handle_command(struct vehicle_status_s *status_local, const struct safety_s
if (cmd->source_system == status_local->system_id && cmd->source_component == status_local->component_id) {
status_local->arming_state = vehicle_status_s::ARMING_STATE_IN_AIR_RESTORE;
}
+ else {
+
+ // Refuse to arm if preflight checks have failed
+ if (!status.hil_state != vehicle_status_s::HIL_STATE_ON && !status.condition_system_sensors_initialized) {
+ mavlink_log_critical(mavlink_fd, "Arming DENIED. Preflight checks have failed.");
+ cmd_result = VEHICLE_CMD_RESULT_DENIED;
+ break;
+ }
+
+ }
transition_result_t arming_res = arm_disarm(cmd_arms, mavlink_fd, "arm/disarm component command");
@@ -949,10 +947,10 @@ int commander_thread_main(int argc, char *argv[])
if (dm_read(DM_KEY_MISSION_STATE, 0, &mission, sizeof(mission_s)) == sizeof(mission_s)) {
if (mission.dataman_id >= 0 && mission.dataman_id <= 1) {
- warnx("loaded mission state: dataman_id=%d, count=%u, current=%d", mission.dataman_id, mission.count,
- mission.current_seq);
- mavlink_log_info(mavlink_fd, "[cmd] dataman_id=%d, count=%u, current=%d",
- mission.dataman_id, mission.count, mission.current_seq);
+ if (mission.count > 0) {
+ mavlink_log_info(mavlink_fd, "[cmd] Mission #%d loaded, %u WPs, curr: %d",
+ mission.dataman_id, mission.count, mission.current_seq);
+ }
} else {
const char *missionfail = "reading mission state failed";
@@ -1021,7 +1019,7 @@ int commander_thread_main(int argc, char *argv[])
bool telemetry_lost[TELEMETRY_STATUS_ORB_ID_NUM];
for (int i = 0; i < TELEMETRY_STATUS_ORB_ID_NUM; i++) {
- telemetry_subs[i] = orb_subscribe(telemetry_status_orb_id[i]);
+ telemetry_subs[i] = -1;
telemetry_last_heartbeat[i] = 0;
telemetry_last_dl_loss[i] = 0;
telemetry_lost[i] = true;
@@ -1114,6 +1112,28 @@ int commander_thread_main(int argc, char *argv[])
commander_initialized = true;
thread_running = true;
+ /* update vehicle status to find out vehicle type (required for preflight checks) */
+ param_get(_param_sys_type, &(status.system_type)); // get system type
+ status.is_rotary_wing = is_rotary_wing(&status) || is_vtol(&status);
+
+ get_circuit_breaker_params();
+
+ bool checkAirspeed = false;
+ /* Perform airspeed check only if circuit breaker is not
+ * engaged and it's not a rotary wing */
+ if (!status.circuit_breaker_engaged_airspd_check && !status.is_rotary_wing) {
+ checkAirspeed = true;
+ }
+
+ // Run preflight check
+ status.condition_system_sensors_initialized = Commander::preflightCheck(mavlink_fd, true, true, true, true, checkAirspeed, true);
+ if (!status.condition_system_sensors_initialized) {
+ set_tune_override(TONE_GPS_WARNING_TUNE); //sensor fail tune
+ }
+ else {
+ set_tune_override(TONE_STARTUP_TUNE); //normal boot tune
+ }
+
const hrt_abstime commander_boot_timestamp = hrt_absolute_time();
transition_result_t arming_ret;
@@ -1139,7 +1159,7 @@ int commander_thread_main(int argc, char *argv[])
/* initialize low priority thread */
pthread_attr_t commander_low_prio_attr;
pthread_attr_init(&commander_low_prio_attr);
- pthread_attr_setstacksize(&commander_low_prio_attr, 2100);
+ pthread_attr_setstacksize(&commander_low_prio_attr, 2000);
struct sched_param param;
(void)pthread_attr_getschedparam(&commander_low_prio_attr, &param);
@@ -1177,15 +1197,7 @@ int commander_thread_main(int argc, char *argv[])
}
/* disable manual override for all systems that rely on electronic stabilization */
- if (status.system_type == vehicle_status_s::VEHICLE_TYPE_COAXIAL ||
- status.system_type == vehicle_status_s::VEHICLE_TYPE_HELICOPTER ||
- status.system_type == vehicle_status_s::VEHICLE_TYPE_TRICOPTER ||
- status.system_type == vehicle_status_s::VEHICLE_TYPE_QUADROTOR ||
- status.system_type == vehicle_status_s::VEHICLE_TYPE_HEXAROTOR ||
- status.system_type == vehicle_status_s::VEHICLE_TYPE_OCTOROTOR ||
- (status.system_type == vehicle_status_s::VEHICLE_TYPE_VTOL_DUOROTOR && vtol_status.vtol_in_rw_mode) ||
- (status.system_type == vehicle_status_s::VEHICLE_TYPE_VTOL_QUADROTOR && vtol_status.vtol_in_rw_mode)) {
-
+ if (is_rotary_wing(&status) || (is_vtol(&status) && vtol_status.vtol_in_rw_mode)) {
status.is_rotary_wing = true;
} else {
@@ -1193,21 +1205,13 @@ int commander_thread_main(int argc, char *argv[])
}
/* set vehicle_status.is_vtol flag */
- status.is_vtol = (status.system_type == vehicle_status_s::VEHICLE_TYPE_VTOL_DUOROTOR) ||
- (status.system_type == vehicle_status_s::VEHICLE_TYPE_VTOL_QUADROTOR);
+ status.is_vtol = is_vtol(&status);
/* check and update system / component ID */
param_get(_param_system_id, &(status.system_id));
param_get(_param_component_id, &(status.component_id));
- status.circuit_breaker_engaged_power_check =
- circuit_breaker_enabled("CBRK_SUPPLY_CHK", CBRK_SUPPLY_CHK_KEY);
- status.circuit_breaker_engaged_airspd_check =
- circuit_breaker_enabled("CBRK_AIRSPD_CHK", CBRK_AIRSPD_CHK_KEY);
- status.circuit_breaker_engaged_enginefailure_check =
- circuit_breaker_enabled("CBRK_ENGINEFAIL", CBRK_ENGINEFAIL_KEY);
- status.circuit_breaker_engaged_gpsfailure_check =
- circuit_breaker_enabled("CBRK_GPSFAIL", CBRK_GPSFAIL_KEY);
+ get_circuit_breaker_params();
status_changed = true;
@@ -1268,6 +1272,11 @@ int commander_thread_main(int argc, char *argv[])
}
for (int i = 0; i < TELEMETRY_STATUS_ORB_ID_NUM; i++) {
+
+ if (telemetry_subs[i] < 0 && (OK == orb_exists(telemetry_status_orb_id[i], 0))) {
+ telemetry_subs[i] = orb_subscribe(telemetry_status_orb_id[i]);
+ }
+
orb_check(telemetry_subs[i], &updated);
if (updated) {
@@ -1282,7 +1291,15 @@ int commander_thread_main(int argc, char *argv[])
telemetry.heartbeat_time > 0 &&
hrt_elapsed_time(&telemetry.heartbeat_time) < datalink_loss_timeout * 1e6) {
- (void)rc_calibration_check(mavlink_fd);
+ bool chAirspeed = false;
+ /* Perform airspeed check only if circuit breaker is not
+ * engaged and it's not a rotary wing */
+ if (!status.circuit_breaker_engaged_airspd_check && !status.is_rotary_wing) {
+ chAirspeed = true;
+ }
+
+ /* provide RC and sensor status feedback to the user */
+ (void)Commander::preflightCheck(mavlink_fd, true, true, true, true, chAirspeed, true);
}
telemetry_last_heartbeat[i] = telemetry.heartbeat_time;
@@ -1387,8 +1404,8 @@ int commander_thread_main(int argc, char *argv[])
orb_copy(ORB_ID(vtol_vehicle_status), vtol_vehicle_status_sub, &vtol_status);
status.vtol_fw_permanent_stab = vtol_status.fw_permanent_stab;
- /* Make sure that this is only adjusted if vehicle realy is of type vtol*/
- if ((status.system_type == vehicle_status_s::VEHICLE_TYPE_VTOL_DUOROTOR) || (status.system_type == vehicle_status_s::VEHICLE_TYPE_VTOL_QUADROTOR)) {
+ /* Make sure that this is only adjusted if vehicle really is of type vtol*/
+ if (is_vtol(&status)) {
status.is_rotary_wing = vtol_status.vtol_in_rw_mode;
}
}
@@ -1549,7 +1566,9 @@ int commander_thread_main(int argc, char *argv[])
/* if battery voltage is getting lower, warn using buzzer, etc. */
if (status.condition_battery_voltage_valid && status.battery_remaining < 0.18f && !low_battery_voltage_actions_done) {
low_battery_voltage_actions_done = true;
- mavlink_log_critical(mavlink_fd, "LOW BATTERY, RETURN TO LAND ADVISED");
+ if (armed.armed) {
+ mavlink_log_critical(mavlink_fd, "LOW BATTERY, RETURN TO LAND ADVISED");
+ }
status.battery_warning = vehicle_status_s::VEHICLE_BATTERY_WARNING_LOW;
status_changed = true;
@@ -1557,7 +1576,6 @@ int commander_thread_main(int argc, char *argv[])
&& !critical_battery_voltage_actions_done && low_battery_voltage_actions_done) {
/* critical battery voltage, this is rather an emergency, change state machine */
critical_battery_voltage_actions_done = true;
- mavlink_log_emergency(mavlink_fd, "CRITICAL BATTERY, LAND IMMEDIATELY");
status.battery_warning = vehicle_status_s::VEHICLE_BATTERY_WARNING_CRITICAL;
if (!armed.armed) {
@@ -1567,7 +1585,11 @@ int commander_thread_main(int argc, char *argv[])
if (arming_ret == TRANSITION_CHANGED) {
arming_state_changed = true;
+ mavlink_and_console_log_critical(mavlink_fd, "LOW BATTERY, LOCKING ARMING DOWN");
}
+
+ } else {
+ mavlink_and_console_log_emergency(mavlink_fd, "CRITICAL BATTERY, LAND IMMEDIATELY");
}
status_changed = true;
@@ -1576,8 +1598,7 @@ int commander_thread_main(int argc, char *argv[])
/* End battery voltage check */
/* If in INIT state, try to proceed to STANDBY state */
- if (status.arming_state == vehicle_status_s::ARMING_STATE_INIT && low_prio_task == LOW_PRIO_TASK_NONE) {
- /* TODO: check for sensors */
+ if (status.arming_state == vehicle_status_s::ARMING_STATE_INIT) {
arming_ret = arming_state_transition(&status, &safety, vehicle_status_s::ARMING_STATE_STANDBY, &armed, true /* fRunPreArmChecks */,
mavlink_fd);
@@ -1585,8 +1606,6 @@ int commander_thread_main(int argc, char *argv[])
arming_state_changed = true;
}
- } else {
- /* TODO: Add emergency stuff if sensors are lost */
}
@@ -1793,13 +1812,17 @@ int commander_thread_main(int argc, char *argv[])
for (int i = 0; i < TELEMETRY_STATUS_ORB_ID_NUM; i++) {
if (telemetry_last_heartbeat[i] != 0 &&
hrt_elapsed_time(&telemetry_last_heartbeat[i]) < datalink_loss_timeout * 1e6) {
- /* handle the case where data link was regained,
+ /* handle the case where data link was gained first time or regained,
* accept datalink as healthy only after datalink_regain_timeout seconds
* */
if (telemetry_lost[i] &&
hrt_elapsed_time(&telemetry_last_dl_loss[i]) > datalink_regain_timeout * 1e6) {
- mavlink_log_info(mavlink_fd, "data link %i regained", i);
+ /* only report a regain */
+ if (telemetry_last_dl_loss[i] > 0) {
+ mavlink_and_console_log_critical(mavlink_fd, "data link #%i regained", i);
+ }
+
telemetry_lost[i] = false;
have_link = true;
@@ -1810,10 +1833,12 @@ int commander_thread_main(int argc, char *argv[])
}
} else {
- telemetry_last_dl_loss[i] = hrt_absolute_time();
if (!telemetry_lost[i]) {
- mavlink_log_info(mavlink_fd, "data link %i lost", i);
+ /* only reset the timestamp to a different time on state change */
+ telemetry_last_dl_loss[i] = hrt_absolute_time();
+
+ mavlink_and_console_log_critical(mavlink_fd, "data link #%i lost", i);
telemetry_lost[i] = true;
}
}
@@ -1828,7 +1853,7 @@ int commander_thread_main(int argc, char *argv[])
} else {
if (!status.data_link_lost) {
- mavlink_log_info(mavlink_fd, "ALL DATA LINKS LOST");
+ mavlink_and_console_log_critical(mavlink_fd, "ALL DATA LINKS LOST");
status.data_link_lost = true;
status.data_link_lost_counter++;
status_changed = true;
@@ -2080,6 +2105,19 @@ int commander_thread_main(int argc, char *argv[])
}
void
+get_circuit_breaker_params()
+{
+ status.circuit_breaker_engaged_power_check =
+ circuit_breaker_enabled("CBRK_SUPPLY_CHK", CBRK_SUPPLY_CHK_KEY);
+ status.circuit_breaker_engaged_airspd_check =
+ circuit_breaker_enabled("CBRK_AIRSPD_CHK", CBRK_AIRSPD_CHK_KEY);
+ status.circuit_breaker_engaged_enginefailure_check =
+ circuit_breaker_enabled("CBRK_ENGINEFAIL", CBRK_ENGINEFAIL_KEY);
+ status.circuit_breaker_engaged_gpsfailure_check =
+ circuit_breaker_enabled("CBRK_GPSFAIL", CBRK_GPSFAIL_KEY);
+}
+
+void
check_valid(hrt_abstime timestamp, hrt_abstime timeout, bool valid_in, bool *valid_out, bool *changed)
{
hrt_abstime t = hrt_absolute_time();
@@ -2103,7 +2141,7 @@ control_status_leds(vehicle_status_s *status_local, const actuator_armed_s *actu
rgbled_set_mode(RGBLED_MODE_ON);
set_normal_color = true;
- } else if (status_local->arming_state == vehicle_status_s::ARMING_STATE_ARMED_ERROR) {
+ } else if (status_local->arming_state == vehicle_status_s::ARMING_STATE_ARMED_ERROR || !status.condition_system_sensors_initialized) {
rgbled_set_mode(RGBLED_MODE_BLINK_FAST);
rgbled_set_color(RGBLED_COLOR_RED);
@@ -2185,13 +2223,34 @@ set_main_state_rc(struct vehicle_status_s *status_local, struct manual_control_s
if (res == TRANSITION_DENIED) {
print_reject_mode(status_local, "OFFBOARD");
+ /* mode rejected, continue to evaluate the main system mode */
} else {
+ /* changed successfully or already in this state */
+ return res;
+ }
+ }
+
+ /* RTL switch overrides main switch */
+ if (sp_man->return_switch == manual_control_setpoint_s::SWITCH_POS_ON) {
+ res = main_state_transition(status_local,vehicle_status_s::MAIN_STATE_AUTO_RTL);
+
+ if (res == TRANSITION_DENIED) {
+ print_reject_mode(status_local, "AUTO_RTL");
+
+ /* fallback to LOITER if home position not set */
+ res = main_state_transition(status_local,vehicle_status_s::MAIN_STATE_AUTO_LOITER);
+ }
+
+ if (res != TRANSITION_DENIED) {
+ /* changed successfully or already in this state */
return res;
}
+
+ /* if we get here mode was rejected, continue to evaluate the main system mode */
}
- /* offboard switched off or denied, check main mode switch */
+ /* offboard and RTL switches off or denied, check main mode switch */
switch (sp_man->mode_switch) {
case manual_control_setpoint_s::SWITCH_POS_NONE:
res = TRANSITION_NOT_CHANGED;
@@ -2236,23 +2295,7 @@ set_main_state_rc(struct vehicle_status_s *status_local, struct manual_control_s
break;
case manual_control_setpoint_s::SWITCH_POS_ON: // AUTO
- if (sp_man->return_switch == manual_control_setpoint_s::SWITCH_POS_ON) {
- res = main_state_transition(status_local,vehicle_status_s::MAIN_STATE_AUTO_RTL);
-
- if (res != TRANSITION_DENIED) {
- break; // changed successfully or already in this state
- }
-
- print_reject_mode(status_local, "AUTO_RTL");
-
- // fallback to LOITER if home position not set
- res = main_state_transition(status_local,vehicle_status_s::MAIN_STATE_AUTO_LOITER);
-
- if (res != TRANSITION_DENIED) {
- break; // changed successfully or already in this state
- }
-
- } else if (sp_man->loiter_switch == manual_control_setpoint_s::SWITCH_POS_ON) {
+ if (sp_man->loiter_switch == manual_control_setpoint_s::SWITCH_POS_ON) {
res = main_state_transition(status_local,vehicle_status_s::MAIN_STATE_AUTO_LOITER);
if (res != TRANSITION_DENIED) {
@@ -2623,7 +2666,7 @@ void *commander_low_prio_loop(void *arg)
/* try to go to INIT/PREFLIGHT arming state */
if (TRANSITION_DENIED == arming_state_transition(&status, &safety, vehicle_status_s::ARMING_STATE_INIT, &armed,
- true /* fRunPreArmChecks */, mavlink_fd)) {
+ false /* fRunPreArmChecks */, mavlink_fd)) {
answer_command(cmd, VEHICLE_CMD_RESULT_DENIED);
break;
}
@@ -2672,22 +2715,33 @@ void *commander_low_prio_loop(void *arg)
/* enable RC control input */
status.rc_input_blocked = false;
mavlink_log_info(mavlink_fd, "CAL: Re-enabling RC IN");
+ calib_ret = OK;
}
-
- /* this always succeeds */
- calib_ret = OK;
-
}
if (calib_ret == OK) {
tune_positive(true);
+ // Update preflight check status
+ // we do not set the calibration return value based on it because the calibration
+ // might have worked just fine, but the preflight check fails for a different reason,
+ // so this would be prone to false negatives.
+
+ bool checkAirspeed = false;
+ /* Perform airspeed check only if circuit breaker is not
+ * engaged and it's not a rotary wing */
+ if (!status.circuit_breaker_engaged_airspd_check && !status.is_rotary_wing) {
+ checkAirspeed = true;
+ }
+
+ status.condition_system_sensors_initialized = Commander::preflightCheck(mavlink_fd, true, true, true, true, checkAirspeed, true);
+
+ arming_state_transition(&status, &safety, vehicle_status_s::ARMING_STATE_STANDBY, &armed, true /* fRunPreArmChecks */, mavlink_fd);
+
} else {
tune_negative(true);
}
- arming_state_transition(&status, &safety, vehicle_status_s::ARMING_STATE_STANDBY, &armed, true /* fRunPreArmChecks */, mavlink_fd);
-
break;
}
@@ -2716,9 +2770,15 @@ void *commander_low_prio_loop(void *arg)
}
} else if (((int)(cmd.param1)) == 1) {
+
int ret = param_save_default();
if (ret == OK) {
+ if (need_param_autosave) {
+ need_param_autosave = false;
+ need_param_autosave_timeout = 0;
+ }
+
mavlink_log_info(mavlink_fd, "settings saved");
answer_command(cmd, VEHICLE_CMD_RESULT_ACCEPTED);
diff --git a/src/modules/commander/commander_helper.cpp b/src/modules/commander/commander_helper.cpp
index a5e4d1972..99b926be4 100644
--- a/src/modules/commander/commander_helper.cpp
+++ b/src/modules/commander/commander_helper.cpp
@@ -84,6 +84,13 @@ bool is_rotary_wing(const struct vehicle_status_s *current_status)
|| (current_status->system_type == vehicle_status_s::VEHICLE_TYPE_COAXIAL);
}
+bool is_vtol(const struct vehicle_status_s * current_status) {
+ return (current_status->system_type == vehicle_status_s::VEHICLE_TYPE_VTOL_DUOROTOR ||
+ current_status->system_type == vehicle_status_s::VEHICLE_TYPE_VTOL_QUADROTOR ||
+ current_status->system_type == vehicle_status_s::VEHICLE_TYPE_VTOL_HEXAROTOR ||
+ current_status->system_type == vehicle_status_s::VEHICLE_TYPE_VTOL_OCTOROTOR);
+}
+
static int buzzer = -1;
static hrt_abstime blink_msg_end = 0; // end time for currently blinking LED message, 0 if no blink message
static hrt_abstime tune_end = 0; // end time of currently played tune, 0 for repeating tunes or silence
diff --git a/src/modules/commander/commander_helper.h b/src/modules/commander/commander_helper.h
index 0cefedba7..bf0c0505d 100644
--- a/src/modules/commander/commander_helper.h
+++ b/src/modules/commander/commander_helper.h
@@ -51,6 +51,7 @@
bool is_multirotor(const struct vehicle_status_s *current_status);
bool is_rotary_wing(const struct vehicle_status_s *current_status);
+bool is_vtol(const struct vehicle_status_s *current_status);
int buzzer_init(void);
void buzzer_deinit(void);
diff --git a/src/modules/commander/commander_params.c b/src/modules/commander/commander_params.c
index a55012243..6663525cc 100644
--- a/src/modules/commander/commander_params.c
+++ b/src/modules/commander/commander_params.c
@@ -105,7 +105,7 @@ PARAM_DEFINE_FLOAT(BAT_CAPACITY, -1.0f);
*
* Set to 1 to enable actions triggered when the datalink is lost.
*
- * @group commander
+ * @group Commander
* @min 0
* @max 1
*/
@@ -115,7 +115,7 @@ PARAM_DEFINE_INT32(COM_DL_LOSS_EN, 0);
*
* After this amount of seconds without datalink the data link lost mode triggers
*
- * @group commander
+ * @group Commander
* @unit second
* @min 0
* @max 30
@@ -127,7 +127,7 @@ PARAM_DEFINE_INT32(COM_DL_LOSS_T, 10);
* After a data link loss: after this this amount of seconds with a healthy datalink the 'datalink loss'
* flag is set back to false
*
- * @group commander
+ * @group Commander
* @unit second
* @min 0
* @max 30
@@ -138,9 +138,9 @@ PARAM_DEFINE_INT32(COM_DL_REG_T, 0);
*
* Engine failure triggers only above this throttle value
*
- * @group commander
- * @min 0.0f
- * @max 1.0f
+ * @group Commander
+ * @min 0.0
+ * @max 1.0
*/
PARAM_DEFINE_FLOAT(COM_EF_THROT, 0.5f);
@@ -148,9 +148,9 @@ PARAM_DEFINE_FLOAT(COM_EF_THROT, 0.5f);
*
* Engine failure triggers only below this current/throttle value
*
- * @group commander
- * @min 0.0f
- * @max 7.0f
+ * @group Commander
+ * @min 0.0
+ * @max 7.0
*/
PARAM_DEFINE_FLOAT(COM_EF_C2T, 5.0f);
@@ -159,10 +159,10 @@ PARAM_DEFINE_FLOAT(COM_EF_C2T, 5.0f);
* Engine failure triggers only if the throttle threshold and the
* current to throttle threshold are violated for this time
*
- * @group commander
+ * @group Commander
* @unit second
- * @min 0.0f
- * @max 7.0f
+ * @min 0.0
+ * @max 7.0
*/
PARAM_DEFINE_FLOAT(COM_EF_TIME, 10.0f);
@@ -170,7 +170,7 @@ PARAM_DEFINE_FLOAT(COM_EF_TIME, 10.0f);
*
* After this amount of seconds without RC connection the rc lost flag is set to true
*
- * @group commander
+ * @group Commander
* @unit second
* @min 0
* @max 35
@@ -183,7 +183,7 @@ PARAM_DEFINE_FLOAT(COM_RC_LOSS_T, 0.5);
* Default is on, as the interoperability with currently deployed GCS solutions depends on parameters
* being sticky. Developers can default it to off.
*
- * @group commander
+ * @group Commander
* @min 0
* @max 1
*/
diff --git a/src/modules/commander/commander_tests/module.mk b/src/modules/commander/commander_tests/module.mk
index 4d10275d1..64afa86c4 100644
--- a/src/modules/commander/commander_tests/module.mk
+++ b/src/modules/commander/commander_tests/module.mk
@@ -38,4 +38,5 @@
MODULE_COMMAND = commander_tests
SRCS = commander_tests.cpp \
state_machine_helper_test.cpp \
- ../state_machine_helper.cpp
+ ../state_machine_helper.cpp \
+ ../PreflightCheck.cpp
diff --git a/src/modules/commander/commander_tests/state_machine_helper_test.cpp b/src/modules/commander/commander_tests/state_machine_helper_test.cpp
index 4ddb4e0fb..967304cb4 100644
--- a/src/modules/commander/commander_tests/state_machine_helper_test.cpp
+++ b/src/modules/commander/commander_tests/state_machine_helper_test.cpp
@@ -255,10 +255,10 @@ bool StateMachineHelperTest::armingStateTransitionTest(void)
// Sensor tests
- { "no transition: init to standby - sensors not initialized",
+ { "transition to standby error: init to standby - sensors not initialized",
{ vehicle_status_s::ARMING_STATE_INIT, ATT_DISARMED, ATT_NOT_READY_TO_ARM }, vehicle_status_s::HIL_STATE_OFF, ATT_SENSORS_NOT_INITIALIZED, ATT_SAFETY_AVAILABLE, ATT_SAFETY_ON,
vehicle_status_s::ARMING_STATE_STANDBY,
- { vehicle_status_s::ARMING_STATE_INIT, ATT_DISARMED, ATT_NOT_READY_TO_ARM }, TRANSITION_DENIED },
+ { vehicle_status_s::ARMING_STATE_STANDBY_ERROR, ATT_DISARMED, ATT_NOT_READY_TO_ARM }, TRANSITION_DENIED },
// Safety switch arming tests
diff --git a/src/modules/commander/gyro_calibration.cpp b/src/modules/commander/gyro_calibration.cpp
index e2a7ef743..bdef8771e 100644
--- a/src/modules/commander/gyro_calibration.cpp
+++ b/src/modules/commander/gyro_calibration.cpp
@@ -39,6 +39,7 @@
#include "gyro_calibration.h"
#include "calibration_messages.h"
+#include "calibration_routines.h"
#include "commander_helper.h"
#include <stdio.h>
@@ -62,149 +63,180 @@ static const int ERROR = -1;
static const char *sensor_name = "gyro";
-int do_gyro_calibration(int mavlink_fd)
-{
- const unsigned max_gyros = 3;
-
- int32_t device_id[3];
- mavlink_log_info(mavlink_fd, CAL_STARTED_MSG, sensor_name);
- mavlink_log_info(mavlink_fd, "HOLD STILL");
-
- /* wait for the user to respond */
- sleep(2);
-
- struct gyro_scale gyro_scale_zero = {
- 0.0f,
- 1.0f,
- 0.0f,
- 1.0f,
- 0.0f,
- 1.0f,
- };
-
- struct gyro_scale gyro_scale[max_gyros] = {};
-
- int res = OK;
+static const unsigned max_gyros = 3;
- /* store board ID */
- uint32_t mcu_id[3];
- mcu_unique_id(&mcu_id[0]);
-
- /* store last 32bit number - not unique, but unique in a given set */
- (void)param_set(param_find("CAL_BOARD_ID"), &mcu_id[2]);
-
- char str[30];
+/// Data passed to calibration worker routine
+typedef struct {
+ int mavlink_fd;
+ int32_t device_id[max_gyros];
+ int gyro_sensor_sub[max_gyros];
+ struct gyro_scale gyro_scale[max_gyros];
+ struct gyro_report gyro_report_0;
+} gyro_worker_data_t;
+static calibrate_return gyro_calibration_worker(detect_orientation_return orientation, int cancel_sub, void* data)
+{
+ gyro_worker_data_t* worker_data = (gyro_worker_data_t*)(data);
+ unsigned calibration_counter[max_gyros] = { 0 };
+ const unsigned calibration_count = 5000;
+ struct gyro_report gyro_report;
+ unsigned poll_errcount = 0;
+
+ struct pollfd fds[max_gyros];
for (unsigned s = 0; s < max_gyros; s++) {
-
- /* ensure all scale fields are initialized tha same as the first struct */
- (void)memcpy(&gyro_scale[s], &gyro_scale_zero, sizeof(gyro_scale[0]));
-
- sprintf(str, "%s%u", GYRO_BASE_DEVICE_PATH, s);
- /* reset all offsets to zero and all scales to one */
- int fd = open(str, 0);
-
- if (fd < 0) {
- continue;
+ fds[s].fd = worker_data->gyro_sensor_sub[s];
+ fds[s].events = POLLIN;
+ }
+
+ memset(&worker_data->gyro_report_0, 0, sizeof(worker_data->gyro_report_0));
+
+ /* use first gyro to pace, but count correctly per-gyro for statistics */
+ while (calibration_counter[0] < calibration_count) {
+ if (calibrate_cancel_check(worker_data->mavlink_fd, cancel_sub)) {
+ return calibrate_return_cancelled;
}
-
- device_id[s] = ioctl(fd, DEVIOCGDEVICEID, 0);
-
- res = ioctl(fd, GYROIOCSSCALE, (long unsigned int)&gyro_scale_zero);
- close(fd);
-
- if (res != OK) {
- mavlink_log_critical(mavlink_fd, CAL_FAILED_RESET_CAL_MSG, s);
+
+ int poll_ret = poll(&fds[0], max_gyros, 1000);
+
+ if (poll_ret > 0) {
+
+ for (unsigned s = 0; s < max_gyros; s++) {
+ bool changed;
+ orb_check(worker_data->gyro_sensor_sub[s], &changed);
+
+ if (changed) {
+ orb_copy(ORB_ID(sensor_gyro), worker_data->gyro_sensor_sub[s], &gyro_report);
+
+ if (s == 0) {
+ orb_copy(ORB_ID(sensor_gyro), worker_data->gyro_sensor_sub[s], &worker_data->gyro_report_0);
+ }
+
+ worker_data->gyro_scale[s].x_offset += gyro_report.x;
+ worker_data->gyro_scale[s].y_offset += gyro_report.y;
+ worker_data->gyro_scale[s].z_offset += gyro_report.z;
+ calibration_counter[s]++;
+ }
+
+ if (s == 0 && calibration_counter[0] % (calibration_count / 20) == 0) {
+ mavlink_log_info(worker_data->mavlink_fd, CAL_QGC_PROGRESS_MSG, (calibration_counter[0] * 100) / calibration_count);
+ }
+ }
+
+ } else {
+ poll_errcount++;
+ }
+
+ if (poll_errcount > 1000) {
+ mavlink_log_critical(worker_data->mavlink_fd, CAL_ERROR_SENSOR_MSG);
+ return calibrate_return_error;
}
}
-
- unsigned calibration_counter[max_gyros] = { 0 };
- const unsigned calibration_count = 5000;
-
- struct gyro_report gyro_report_0 = {};
-
- if (res == OK) {
- /* determine gyro mean values */
- unsigned poll_errcount = 0;
-
- /* subscribe to gyro sensor topic */
- int sub_sensor_gyro[max_gyros];
- struct pollfd fds[max_gyros];
-
- for (unsigned s = 0; s < max_gyros; s++) {
- sub_sensor_gyro[s] = orb_subscribe_multi(ORB_ID(sensor_gyro), s);
- fds[s].fd = sub_sensor_gyro[s];
- fds[s].events = POLLIN;
+
+ for (unsigned s = 0; s < max_gyros; s++) {
+ if (worker_data->device_id[s] != 0 && calibration_counter[s] < calibration_count / 2) {
+ mavlink_log_critical(worker_data->mavlink_fd, "[cal] ERROR: missing data, sensor %d", s)
+ return calibrate_return_error;
}
- struct gyro_report gyro_report;
-
- /* use first gyro to pace, but count correctly per-gyro for statistics */
- while (calibration_counter[0] < calibration_count) {
- /* wait blocking for new data */
-
- int poll_ret = poll(&fds[0], max_gyros, 1000);
-
- if (poll_ret > 0) {
-
- for (unsigned s = 0; s < max_gyros; s++) {
- bool changed;
- orb_check(sub_sensor_gyro[s], &changed);
-
- if (changed) {
- orb_copy(ORB_ID(sensor_gyro), sub_sensor_gyro[s], &gyro_report);
-
- if (s == 0) {
- orb_copy(ORB_ID(sensor_gyro), sub_sensor_gyro[s], &gyro_report_0);
- }
+ worker_data->gyro_scale[s].x_offset /= calibration_counter[s];
+ worker_data->gyro_scale[s].y_offset /= calibration_counter[s];
+ worker_data->gyro_scale[s].z_offset /= calibration_counter[s];
+ }
- gyro_scale[s].x_offset += gyro_report.x;
- gyro_scale[s].y_offset += gyro_report.y;
- gyro_scale[s].z_offset += gyro_report.z;
- calibration_counter[s]++;
- }
+ return calibrate_return_ok;
+}
- if (s == 0 && calibration_counter[0] % (calibration_count / 20) == 0) {
- mavlink_log_info(mavlink_fd, CAL_PROGRESS_MSG, sensor_name, (calibration_counter[0] * 100) / calibration_count);
- }
- }
+int do_gyro_calibration(int mavlink_fd)
+{
+ int res = OK;
+ gyro_worker_data_t worker_data;
- } else {
- poll_errcount++;
- }
+ mavlink_log_info(mavlink_fd, CAL_QGC_STARTED_MSG, sensor_name);
- if (poll_errcount > 1000) {
- mavlink_log_critical(mavlink_fd, CAL_FAILED_SENSOR_MSG);
- res = ERROR;
- break;
- }
+ worker_data.mavlink_fd = mavlink_fd;
+
+ struct gyro_scale gyro_scale_zero = {
+ 0.0f, // x offset
+ 1.0f, // x scale
+ 0.0f, // y offset
+ 1.0f, // y scale
+ 0.0f, // z offset
+ 1.0f, // z scale
+ };
+
+ for (unsigned s = 0; s < max_gyros; s++) {
+ char str[30];
+
+ // Reset gyro ids to unavailable
+ worker_data.device_id[s] = 0;
+ (void)sprintf(str, "CAL_GYRO%u_ID", s);
+ res = param_set_no_notification(param_find(str), &(worker_data.device_id[s]));
+ if (res != OK) {
+ mavlink_log_critical(mavlink_fd, "[cal] Unable to reset CAL_GYRO%u_ID", s);
+ return ERROR;
}
+
+ // Reset all offsets to 0 and scales to 1
+ (void)memcpy(&worker_data.gyro_scale[s], &gyro_scale_zero, sizeof(gyro_scale));
+ sprintf(str, "%s%u", GYRO_BASE_DEVICE_PATH, s);
+ int fd = open(str, 0);
+ if (fd >= 0) {
+ worker_data.device_id[s] = ioctl(fd, DEVIOCGDEVICEID, 0);
+ res = ioctl(fd, GYROIOCSSCALE, (long unsigned int)&gyro_scale_zero);
+ close(fd);
- for (unsigned s = 0; s < max_gyros; s++) {
- close(sub_sensor_gyro[s]);
-
- gyro_scale[s].x_offset /= calibration_counter[s];
- gyro_scale[s].y_offset /= calibration_counter[s];
- gyro_scale[s].z_offset /= calibration_counter[s];
+ if (res != OK) {
+ mavlink_log_critical(mavlink_fd, CAL_ERROR_RESET_CAL_MSG, s);
+ return ERROR;
+ }
}
+
+ }
+
+ for (unsigned s = 0; s < max_gyros; s++) {
+ worker_data.gyro_sensor_sub[s] = orb_subscribe_multi(ORB_ID(sensor_gyro), s);
+ }
+
+ // Calibrate right-side up
+
+ bool side_collected[detect_orientation_side_count] = { true, true, true, true, true, false };
+
+ int cancel_sub = calibrate_cancel_subscribe();
+ calibrate_return cal_return = calibrate_from_orientation(mavlink_fd, // Mavlink fd to write output
+ cancel_sub, // Subscription to vehicle_command for cancel support
+ side_collected, // Sides to calibrate
+ gyro_calibration_worker, // Calibration worker
+ &worker_data, // Opaque data for calibration worked
+ true); // true: lenient still detection
+ calibrate_cancel_unsubscribe(cancel_sub);
+
+ for (unsigned s = 0; s < max_gyros; s++) {
+ close(worker_data.gyro_sensor_sub[s]);
}
+ if (cal_return == calibrate_return_cancelled) {
+ // Cancel message already sent, we are done here
+ return ERROR;
+ } else if (cal_return == calibrate_return_error) {
+ res = ERROR;
+ }
+
if (res == OK) {
/* check offsets */
- float xdiff = gyro_report_0.x - gyro_scale[0].x_offset;
- float ydiff = gyro_report_0.y - gyro_scale[0].y_offset;
- float zdiff = gyro_report_0.z - gyro_scale[0].z_offset;
+ float xdiff = worker_data.gyro_report_0.x - worker_data.gyro_scale[0].x_offset;
+ float ydiff = worker_data.gyro_report_0.y - worker_data.gyro_scale[0].y_offset;
+ float zdiff = worker_data.gyro_report_0.z - worker_data.gyro_scale[0].z_offset;
/* maximum allowable calibration error in radians */
- const float maxoff = 0.002f;
+ const float maxoff = 0.0055f;
- if (!isfinite(gyro_scale[0].x_offset) ||
- !isfinite(gyro_scale[0].y_offset) ||
- !isfinite(gyro_scale[0].z_offset) ||
+ if (!isfinite(worker_data.gyro_scale[0].x_offset) ||
+ !isfinite(worker_data.gyro_scale[0].y_offset) ||
+ !isfinite(worker_data.gyro_scale[0].z_offset) ||
fabsf(xdiff) > maxoff ||
fabsf(ydiff) > maxoff ||
fabsf(zdiff) > maxoff) {
- mavlink_log_critical(mavlink_fd, "ERROR: Motion during calibration");
+ mavlink_and_console_log_critical(mavlink_fd, "[cal] ERROR: Motion during calibration");
res = ERROR;
}
}
@@ -214,59 +246,69 @@ int do_gyro_calibration(int mavlink_fd)
bool failed = false;
for (unsigned s = 0; s < max_gyros; s++) {
+ if (worker_data.device_id[s] != 0) {
+ char str[30];
+
+ (void)sprintf(str, "CAL_GYRO%u_XOFF", s);
+ failed |= (OK != param_set_no_notification(param_find(str), &(worker_data.gyro_scale[s].x_offset)));
+ (void)sprintf(str, "CAL_GYRO%u_YOFF", s);
+ failed |= (OK != param_set_no_notification(param_find(str), &(worker_data.gyro_scale[s].y_offset)));
+ (void)sprintf(str, "CAL_GYRO%u_ZOFF", s);
+ failed |= (OK != param_set_no_notification(param_find(str), &(worker_data.gyro_scale[s].z_offset)));
+ (void)sprintf(str, "CAL_GYRO%u_ID", s);
+ failed |= (OK != param_set_no_notification(param_find(str), &(worker_data.device_id[s])));
+
+ /* apply new scaling and offsets */
+ (void)sprintf(str, "%s%u", GYRO_BASE_DEVICE_PATH, s);
+ int fd = open(str, 0);
+
+ if (fd < 0) {
+ failed = true;
+ continue;
+ }
- /* if any reasonable amount of data is missing, skip */
- if (calibration_counter[s] < calibration_count / 2) {
- continue;
- }
-
- (void)sprintf(str, "CAL_GYRO%u_XOFF", s);
- failed |= (OK != param_set(param_find(str), &(gyro_scale[s].x_offset)));
- (void)sprintf(str, "CAL_GYRO%u_YOFF", s);
- failed |= (OK != param_set(param_find(str), &(gyro_scale[s].y_offset)));
- (void)sprintf(str, "CAL_GYRO%u_ZOFF", s);
- failed |= (OK != param_set(param_find(str), &(gyro_scale[s].z_offset)));
- (void)sprintf(str, "CAL_GYRO%u_ID", s);
- failed |= (OK != param_set(param_find(str), &(device_id[s])));
-
- /* apply new scaling and offsets */
- (void)sprintf(str, "%s%u", GYRO_BASE_DEVICE_PATH, s);
- int fd = open(str, 0);
-
- if (fd < 0) {
- failed = true;
- continue;
- }
-
- res = ioctl(fd, GYROIOCSSCALE, (long unsigned int)&gyro_scale[s]);
- close(fd);
+ res = ioctl(fd, GYROIOCSSCALE, (long unsigned int)&worker_data.gyro_scale[s]);
+ close(fd);
- if (res != OK) {
- mavlink_log_critical(mavlink_fd, CAL_FAILED_APPLY_CAL_MSG);
+ if (res != OK) {
+ mavlink_log_critical(mavlink_fd, CAL_ERROR_APPLY_CAL_MSG);
+ }
}
}
if (failed) {
- mavlink_and_console_log_critical(mavlink_fd, "ERROR: failed to set offset params");
+ mavlink_and_console_log_critical(mavlink_fd, "[cal] ERROR: failed to set offset params");
res = ERROR;
}
}
+ /* store board ID */
+ uint32_t mcu_id[3];
+ mcu_unique_id(&mcu_id[0]);
+
+ /* store last 32bit number - not unique, but unique in a given set */
+ (void)param_set(param_find("CAL_BOARD_ID"), &mcu_id[2]);
+
if (res == OK) {
/* auto-save to EEPROM */
res = param_save_default();
if (res != OK) {
- mavlink_log_critical(mavlink_fd, CAL_FAILED_SAVE_PARAMS_MSG);
+ mavlink_log_critical(mavlink_fd, CAL_ERROR_SAVE_PARAMS_MSG);
}
}
- if (res == OK) {
- mavlink_log_info(mavlink_fd, CAL_DONE_MSG, sensor_name);
+ /* if there is a any preflight-check system response, let the barrage of messages through */
+ usleep(200000);
+ if (res == OK) {
+ mavlink_log_info(mavlink_fd, CAL_QGC_DONE_MSG, sensor_name);
} else {
- mavlink_log_info(mavlink_fd, CAL_FAILED_MSG, sensor_name);
+ mavlink_log_info(mavlink_fd, CAL_QGC_FAILED_MSG, sensor_name);
}
+ /* give this message enough time to propagate */
+ usleep(600000);
+
return res;
}
diff --git a/src/modules/commander/mag_calibration.cpp b/src/modules/commander/mag_calibration.cpp
index 198acb027..8a8d85818 100644
--- a/src/modules/commander/mag_calibration.cpp
+++ b/src/modules/commander/mag_calibration.cpp
@@ -65,8 +65,7 @@ static const int ERROR = -1;
static const char *sensor_name = "mag";
static const unsigned max_mags = 3;
-int mag_calibrate_all(int mavlink_fd, int32_t (&device_ids)[max_mags]);
-int mag_calibration_worker(detect_orientation_return orientation, void* worker_data);
+calibrate_return mag_calibrate_all(int mavlink_fd, int32_t (&device_ids)[max_mags]);
/// Data passed to calibration worker routine
typedef struct {
@@ -86,7 +85,7 @@ typedef struct {
int do_mag_calibration(int mavlink_fd)
{
- mavlink_and_console_log_info(mavlink_fd, CAL_STARTED_MSG, sensor_name);
+ mavlink_and_console_log_info(mavlink_fd, CAL_QGC_STARTED_MSG, sensor_name);
struct mag_scale mscale_null = {
0.0f,
@@ -113,7 +112,7 @@ int do_mag_calibration(int mavlink_fd)
(void)sprintf(str, "CAL_MAG%u_ID", cur_mag);
result = param_set_no_notification(param_find(str), &(device_ids[cur_mag]));
if (result != OK) {
- mavlink_and_console_log_info(mavlink_fd, "Unabled to reset CAL_MAG%u_ID", cur_mag);
+ mavlink_and_console_log_info(mavlink_fd, "[cal] Unable to reset CAL_MAG%u_ID", cur_mag);
break;
}
@@ -131,15 +130,15 @@ int do_mag_calibration(int mavlink_fd)
result = ioctl(fd, MAGIOCSSCALE, (long unsigned int)&mscale_null);
if (result != OK) {
- mavlink_and_console_log_critical(mavlink_fd, CAL_FAILED_RESET_CAL_MSG, cur_mag);
+ mavlink_and_console_log_critical(mavlink_fd, CAL_ERROR_RESET_CAL_MSG, cur_mag);
}
+ /* calibrate range */
if (result == OK) {
- /* calibrate range */
result = ioctl(fd, MAGIOCCALIBRATE, fd);
if (result != OK) {
- mavlink_and_console_log_info(mavlink_fd, "Skipped scale calibration, sensor %u", cur_mag);
+ mavlink_and_console_log_info(mavlink_fd, "[cal] Skipped scale calibration, sensor %u", cur_mag);
/* this is non-fatal - mark it accordingly */
result = OK;
}
@@ -148,39 +147,52 @@ int do_mag_calibration(int mavlink_fd)
close(fd);
}
+ // Calibrate all mags at the same time
if (result == OK) {
- // Calibrate all mags at the same time
- result = mag_calibrate_all(mavlink_fd, device_ids);
- }
-
- if (result == OK) {
- /* auto-save to EEPROM */
- result = param_save_default();
- if (result != OK) {
- mavlink_and_console_log_critical(mavlink_fd, CAL_FAILED_SAVE_PARAMS_MSG);
+ switch (mag_calibrate_all(mavlink_fd, device_ids)) {
+ case calibrate_return_cancelled:
+ // Cancel message already displayed, we're done here
+ result = ERROR;
+ break;
+
+ case calibrate_return_ok:
+ /* auto-save to EEPROM */
+ result = param_save_default();
+
+ /* if there is a any preflight-check system response, let the barrage of messages through */
+ usleep(200000);
+
+ if (result == OK) {
+ mavlink_and_console_log_info(mavlink_fd, CAL_QGC_PROGRESS_MSG, 100);
+ mavlink_and_console_log_info(mavlink_fd, CAL_QGC_DONE_MSG, sensor_name);
+ break;
+ } else {
+ mavlink_and_console_log_critical(mavlink_fd, CAL_ERROR_SAVE_PARAMS_MSG);
+ }
+ // Fall through
+
+ default:
+ mavlink_and_console_log_critical(mavlink_fd, CAL_QGC_FAILED_MSG, sensor_name);
+ break;
}
}
-
- if (result == OK) {
- mavlink_and_console_log_info(mavlink_fd, CAL_PROGRESS_MSG, sensor_name, 100);
- mavlink_and_console_log_info(mavlink_fd, CAL_DONE_MSG, sensor_name);
- } else {
- mavlink_and_console_log_critical(mavlink_fd, CAL_FAILED_MSG, sensor_name);
- }
+ /* give this message enough time to propagate */
+ usleep(600000);
+
return result;
}
-int mag_calibration_worker(detect_orientation_return orientation, void* data)
+static calibrate_return mag_calibration_worker(detect_orientation_return orientation, int cancel_sub, void* data)
{
- int result = OK;
+ calibrate_return result = calibrate_return_ok;
unsigned int calibration_counter_side;
mag_worker_data_t* worker_data = (mag_worker_data_t*)(data);
- mavlink_and_console_log_info(worker_data->mavlink_fd, "Rotate vehicle around the detected orientation");
- mavlink_and_console_log_info(worker_data->mavlink_fd, "Continue rotation for %u seconds", worker_data->calibration_interval_perside_seconds);
+ mavlink_and_console_log_info(worker_data->mavlink_fd, "[cal] Rotate vehicle around the detected orientation");
+ mavlink_and_console_log_info(worker_data->mavlink_fd, "[cal] Continue rotation for %u seconds", worker_data->calibration_interval_perside_seconds);
sleep(2);
uint64_t calibration_deadline = hrt_absolute_time() + worker_data->calibration_interval_perside_useconds;
@@ -191,6 +203,11 @@ int mag_calibration_worker(detect_orientation_return orientation, void* data)
while (hrt_absolute_time() < calibration_deadline &&
calibration_counter_side < worker_data->calibration_points_perside) {
+ if (calibrate_cancel_check(worker_data->mavlink_fd, cancel_sub)) {
+ result = calibrate_return_cancelled;
+ break;
+ }
+
// Wait clocking for new data on all mags
struct pollfd fds[max_mags];
size_t fd_count = 0;
@@ -222,8 +239,7 @@ int mag_calibration_worker(detect_orientation_return orientation, void* data)
// Progress indicator for side
mavlink_and_console_log_info(worker_data->mavlink_fd,
- "%s %s side calibration: progress <%u>",
- sensor_name,
+ "[cal] %s side calibration: progress <%u>",
detect_orientation_str(orientation),
(unsigned)(100 * ((float)calibration_counter_side / (float)worker_data->calibration_points_perside)));
} else {
@@ -231,50 +247,25 @@ int mag_calibration_worker(detect_orientation_return orientation, void* data)
}
if (poll_errcount > worker_data->calibration_points_perside * 3) {
- result = ERROR;
- mavlink_and_console_log_info(worker_data->mavlink_fd, CAL_FAILED_SENSOR_MSG);
+ result = calibrate_return_error;
+ mavlink_and_console_log_info(worker_data->mavlink_fd, CAL_ERROR_SENSOR_MSG);
break;
}
}
- // Mark the opposite side as collected as well. No need to collect opposite side since it
- // would generate similar points.
- detect_orientation_return alternateOrientation = orientation;
- switch (orientation) {
- case DETECT_ORIENTATION_TAIL_DOWN:
- alternateOrientation = DETECT_ORIENTATION_NOSE_DOWN;
- break;
- case DETECT_ORIENTATION_NOSE_DOWN:
- alternateOrientation = DETECT_ORIENTATION_TAIL_DOWN;
- break;
- case DETECT_ORIENTATION_LEFT:
- alternateOrientation = DETECT_ORIENTATION_RIGHT;
- break;
- case DETECT_ORIENTATION_RIGHT:
- alternateOrientation = DETECT_ORIENTATION_LEFT;
- break;
- case DETECT_ORIENTATION_UPSIDE_DOWN:
- alternateOrientation = DETECT_ORIENTATION_RIGHTSIDE_UP;
- break;
- case DETECT_ORIENTATION_RIGHTSIDE_UP:
- alternateOrientation = DETECT_ORIENTATION_UPSIDE_DOWN;
- break;
- case DETECT_ORIENTATION_ERROR:
- warnx("Invalid orientation in mag_calibration_worker");
- break;
+ if (result == calibrate_return_ok) {
+ mavlink_and_console_log_info(worker_data->mavlink_fd, "[cal] %s side done, rotate to a different side", detect_orientation_str(orientation));
+
+ worker_data->done_count++;
+ mavlink_and_console_log_info(worker_data->mavlink_fd, CAL_QGC_PROGRESS_MSG, 34 * worker_data->done_count);
}
- worker_data->side_data_collected[alternateOrientation] = true;
- mavlink_and_console_log_info(worker_data->mavlink_fd, "%s side done, rotate to a different side", detect_orientation_str(alternateOrientation));
-
- worker_data->done_count++;
- mavlink_and_console_log_info(worker_data->mavlink_fd, CAL_PROGRESS_MSG, sensor_name, 34 * worker_data->done_count);
return result;
}
-int mag_calibrate_all(int mavlink_fd, int32_t (&device_ids)[max_mags])
+calibrate_return mag_calibrate_all(int mavlink_fd, int32_t (&device_ids)[max_mags])
{
- int result = OK;
+ calibrate_return result = calibrate_return_ok;
mag_worker_data_t worker_data;
@@ -285,10 +276,13 @@ int mag_calibrate_all(int mavlink_fd, int32_t (&device_ids)[max_mags])
worker_data.calibration_interval_perside_seconds = 20;
worker_data.calibration_interval_perside_useconds = worker_data.calibration_interval_perside_seconds * 1000 * 1000;
- // Initialize to collect all sides
- for (size_t cur_side=0; cur_side<6; cur_side++) {
- worker_data.side_data_collected[cur_side] = false;
- }
+ // Collect: Right-side up, Left Side, Nose down
+ worker_data.side_data_collected[DETECT_ORIENTATION_RIGHTSIDE_UP] = false;
+ worker_data.side_data_collected[DETECT_ORIENTATION_LEFT] = false;
+ worker_data.side_data_collected[DETECT_ORIENTATION_NOSE_DOWN] = false;
+ worker_data.side_data_collected[DETECT_ORIENTATION_TAIL_DOWN] = true;
+ worker_data.side_data_collected[DETECT_ORIENTATION_UPSIDE_DOWN] = true;
+ worker_data.side_data_collected[DETECT_ORIENTATION_RIGHT] = true;
for (size_t cur_mag=0; cur_mag<max_mags; cur_mag++) {
// Initialize to no subscription
@@ -310,21 +304,21 @@ int mag_calibrate_all(int mavlink_fd, int32_t (&device_ids)[max_mags])
worker_data.y[cur_mag] = reinterpret_cast<float *>(malloc(sizeof(float) * calibration_points_maxcount));
worker_data.z[cur_mag] = reinterpret_cast<float *>(malloc(sizeof(float) * calibration_points_maxcount));
if (worker_data.x[cur_mag] == NULL || worker_data.y[cur_mag] == NULL || worker_data.z[cur_mag] == NULL) {
- mavlink_and_console_log_critical(mavlink_fd, "ERROR: out of memory");
- result = ERROR;
+ mavlink_and_console_log_critical(mavlink_fd, "[cal] ERROR: out of memory");
+ result = calibrate_return_error;
}
}
// Setup subscriptions to mag sensors
- if (result == OK) {
+ if (result == calibrate_return_ok) {
for (unsigned cur_mag=0; cur_mag<max_mags; cur_mag++) {
if (device_ids[cur_mag] != 0) {
// Mag in this slot is available
worker_data.sub_mag[cur_mag] = orb_subscribe_multi(ORB_ID(sensor_mag), cur_mag);
if (worker_data.sub_mag[cur_mag] < 0) {
- mavlink_and_console_log_critical(mavlink_fd, "Mag #%u not found, abort", cur_mag);
- result = ERROR;
+ mavlink_and_console_log_critical(mavlink_fd, "[cal] Mag #%u not found, abort", cur_mag);
+ result = calibrate_return_error;
break;
}
}
@@ -332,7 +326,7 @@ int mag_calibrate_all(int mavlink_fd, int32_t (&device_ids)[max_mags])
}
// Limit update rate to get equally spaced measurements over time (in ms)
- if (result == OK) {
+ if (result == calibrate_return_ok) {
for (unsigned cur_mag=0; cur_mag<max_mags; cur_mag++) {
if (device_ids[cur_mag] != 0) {
// Mag in this slot is available
@@ -344,8 +338,18 @@ int mag_calibrate_all(int mavlink_fd, int32_t (&device_ids)[max_mags])
}
}
-
- result = calibrate_from_orientation(mavlink_fd, worker_data.side_data_collected, mag_calibration_worker, &worker_data);
+
+ if (result == calibrate_return_ok) {
+ int cancel_sub = calibrate_cancel_subscribe();
+
+ result = calibrate_from_orientation(mavlink_fd, // Mavlink fd to write output
+ cancel_sub, // Subscription to vehicle_command for cancel support
+ worker_data.side_data_collected, // Sides to calibrate
+ mag_calibration_worker, // Calibration worker
+ &worker_data, // Opaque data for calibration worked
+ true); // true: lenient still detection
+ calibrate_cancel_unsubscribe(cancel_sub);
+ }
// Close subscriptions
for (unsigned cur_mag=0; cur_mag<max_mags; cur_mag++) {
@@ -363,7 +367,7 @@ int mag_calibrate_all(int mavlink_fd, int32_t (&device_ids)[max_mags])
float sphere_radius[max_mags];
// Sphere fit the data to get calibration values
- if (result == OK) {
+ if (result == calibrate_return_ok) {
for (unsigned cur_mag=0; cur_mag<max_mags; cur_mag++) {
if (device_ids[cur_mag] != 0) {
// Mag in this slot is available and we should have values for it to calibrate
@@ -375,8 +379,8 @@ int mag_calibrate_all(int mavlink_fd, int32_t (&device_ids)[max_mags])
&sphere_radius[cur_mag]);
if (!isfinite(sphere_x[cur_mag]) || !isfinite(sphere_y[cur_mag]) || !isfinite(sphere_z[cur_mag])) {
- mavlink_and_console_log_info(mavlink_fd, "ERROR: NaN in sphere fit for mag #%u", cur_mag);
- result = ERROR;
+ mavlink_and_console_log_critical(mavlink_fd, "[cal] ERROR: NaN in sphere fit for mag #%u", cur_mag);
+ result = calibrate_return_error;
}
}
}
@@ -389,7 +393,7 @@ int mag_calibrate_all(int mavlink_fd, int32_t (&device_ids)[max_mags])
free(worker_data.z[cur_mag]);
}
- if (result == OK) {
+ if (result == calibrate_return_ok) {
for (unsigned cur_mag=0; cur_mag<max_mags; cur_mag++) {
if (device_ids[cur_mag] != 0) {
int fd_mag = -1;
@@ -400,27 +404,25 @@ int mag_calibrate_all(int mavlink_fd, int32_t (&device_ids)[max_mags])
(void)sprintf(str, "%s%u", MAG_BASE_DEVICE_PATH, cur_mag);
fd_mag = open(str, 0);
if (fd_mag < 0) {
- mavlink_and_console_log_info(mavlink_fd, "ERROR: unable to open mag device #%u", cur_mag);
- result = ERROR;
+ mavlink_and_console_log_critical(mavlink_fd, "[cal] ERROR: unable to open mag device #%u", cur_mag);
+ result = calibrate_return_error;
}
- if (result == OK) {
- result = ioctl(fd_mag, MAGIOCGSCALE, (long unsigned int)&mscale);
- if (result != OK) {
- mavlink_and_console_log_info(mavlink_fd, "ERROR: failed to get current calibration #%u", cur_mag);
- result = ERROR;
+ if (result == calibrate_return_ok) {
+ if (ioctl(fd_mag, MAGIOCGSCALE, (long unsigned int)&mscale) != OK) {
+ mavlink_and_console_log_critical(mavlink_fd, "[cal] ERROR: failed to get current calibration #%u", cur_mag);
+ result = calibrate_return_error;
}
}
- if (result == OK) {
+ if (result == calibrate_return_ok) {
mscale.x_offset = sphere_x[cur_mag];
mscale.y_offset = sphere_y[cur_mag];
mscale.z_offset = sphere_z[cur_mag];
- result = ioctl(fd_mag, MAGIOCSSCALE, (long unsigned int)&mscale);
- if (result != OK) {
- mavlink_and_console_log_info(mavlink_fd, CAL_FAILED_APPLY_CAL_MSG, cur_mag);
- result = ERROR;
+ if (ioctl(fd_mag, MAGIOCSSCALE, (long unsigned int)&mscale) != OK) {
+ mavlink_and_console_log_critical(mavlink_fd, CAL_ERROR_APPLY_CAL_MSG, cur_mag);
+ result = calibrate_return_error;
}
}
@@ -429,7 +431,7 @@ int mag_calibrate_all(int mavlink_fd, int32_t (&device_ids)[max_mags])
close(fd_mag);
}
- if (result == OK) {
+ if (result == calibrate_return_ok) {
bool failed = false;
/* set parameters */
@@ -449,13 +451,13 @@ int mag_calibrate_all(int mavlink_fd, int32_t (&device_ids)[max_mags])
failed |= (OK != param_set_no_notification(param_find(str), &(mscale.z_scale)));
if (failed) {
- mavlink_and_console_log_info(mavlink_fd, CAL_FAILED_SET_PARAMS_MSG, cur_mag);
- result = ERROR;
+ mavlink_and_console_log_critical(mavlink_fd, CAL_ERROR_SET_PARAMS_MSG, cur_mag);
+ result = calibrate_return_error;
} else {
- mavlink_and_console_log_info(mavlink_fd, "mag #%u off: x:%.2f y:%.2f z:%.2f Ga",
+ mavlink_and_console_log_info(mavlink_fd, "[cal] mag #%u off: x:%.2f y:%.2f z:%.2f Ga",
cur_mag,
(double)mscale.x_offset, (double)mscale.y_offset, (double)mscale.z_offset);
- mavlink_and_console_log_info(mavlink_fd, "mag #%u scale: x:%.2f y:%.2f z:%.2f",
+ mavlink_and_console_log_info(mavlink_fd, "[cal] mag #%u scale: x:%.2f y:%.2f z:%.2f",
cur_mag,
(double)mscale.x_scale, (double)mscale.y_scale, (double)mscale.z_scale);
}
diff --git a/src/modules/commander/module.mk b/src/modules/commander/module.mk
index 4ee8732fc..4437041e2 100644
--- a/src/modules/commander/module.mk
+++ b/src/modules/commander/module.mk
@@ -46,7 +46,8 @@ SRCS = commander.cpp \
mag_calibration.cpp \
baro_calibration.cpp \
rc_calibration.cpp \
- airspeed_calibration.cpp
+ airspeed_calibration.cpp \
+ PreflightCheck.cpp
MODULE_STACKSIZE = 5000
diff --git a/src/modules/commander/state_machine_helper.cpp b/src/modules/commander/state_machine_helper.cpp
index e1d2d72d1..73fdb0940 100644
--- a/src/modules/commander/state_machine_helper.cpp
+++ b/src/modules/commander/state_machine_helper.cpp
@@ -52,18 +52,17 @@
#include <uORB/topics/vehicle_status.h>
#include <uORB/topics/actuator_controls.h>
#include <uORB/topics/differential_pressure.h>
-#include <uORB/topics/airspeed.h>
#include <systemlib/systemlib.h>
#include <systemlib/param/param.h>
#include <systemlib/err.h>
#include <drivers/drv_hrt.h>
#include <drivers/drv_accel.h>
-#include <drivers/drv_airspeed.h>
#include <drivers/drv_device.h>
#include <mavlink/mavlink_log.h>
#include "state_machine_helper.h"
#include "commander_helper.h"
+#include "PreflightCheck.h"
/* oddly, ERROR is not defined for c++ */
#ifdef ERROR
@@ -77,12 +76,12 @@ static const int ERROR = -1;
// though the transition is marked as true additional checks must be made. See arming_state_transition
// code for those checks.
static const bool arming_transitions[vehicle_status_s::ARMING_STATE_MAX][vehicle_status_s::ARMING_STATE_MAX] = {
- // INIT, STANDBY, ARMED, ARMED_ERROR, STANDBY_ERROR, REBOOT, IN_AIR_RESTORE
- { /* vehicle_status_s::ARMING_STATE_INIT */ true, true, false, false, false, false, false },
+ // INIT, STANDBY, ARMED, ARMED_ERROR, STANDBY_ERROR, REBOOT, IN_AIR_RESTORE
+ { /* vehicle_status_s::ARMING_STATE_INIT */ true, true, false, false, true, false, false },
{ /* vehicle_status_s::ARMING_STATE_STANDBY */ true, true, true, true, false, false, false },
{ /* vehicle_status_s::ARMING_STATE_ARMED */ false, true, true, false, false, false, true },
{ /* vehicle_status_s::ARMING_STATE_ARMED_ERROR */ false, false, true, true, false, false, false },
- { /* vehicle_status_s::ARMING_STATE_STANDBY_ERROR */ true, true, false, true, true, false, false },
+ { /* vehicle_status_s::ARMING_STATE_STANDBY_ERROR */ true, true, true, true, true, false, false },
{ /* vehicle_status_s::ARMING_STATE_REBOOT */ true, true, false, false, true, true, true },
{ /* vehicle_status_s::ARMING_STATE_IN_AIR_RESTORE */ false, false, false, false, false, false, false }, // NYI
};
@@ -138,6 +137,13 @@ arming_state_transition(struct vehicle_status_s *status, ///< current vehicle s
/* enforce lockdown in HIL */
if (status->hil_state == vehicle_status_s::HIL_STATE_ON) {
armed->lockdown = true;
+ prearm_ret = OK;
+ status->condition_system_sensors_initialized = true;
+
+ /* recover from a prearm fail */
+ if (status->arming_state == vehicle_status_s::ARMING_STATE_STANDBY_ERROR) {
+ status->arming_state = vehicle_status_s::ARMING_STATE_STANDBY;
+ }
} else {
armed->lockdown = false;
@@ -175,7 +181,7 @@ arming_state_transition(struct vehicle_status_s *status, ///< current vehicle s
// Fail transition if power is not good
if (!status->condition_power_input_valid) {
- mavlink_log_critical(mavlink_fd, "NOT ARMING: Connect power module.");
+ mavlink_and_console_log_critical(mavlink_fd, "NOT ARMING: Connect power module.");
feedback_provided = true;
valid_transition = false;
}
@@ -185,7 +191,7 @@ arming_state_transition(struct vehicle_status_s *status, ///< current vehicle s
if (status->condition_power_input_valid && (status->avionics_power_rail_voltage > 0.0f)) {
// Check avionics rail voltages
if (status->avionics_power_rail_voltage < 4.75f) {
- mavlink_log_critical(mavlink_fd, "NOT ARMING: Avionics power low: %6.2f Volt", (double)status->avionics_power_rail_voltage);
+ mavlink_and_console_log_critical(mavlink_fd, "NOT ARMING: Avionics power low: %6.2f Volt", (double)status->avionics_power_rail_voltage);
feedback_provided = true;
valid_transition = false;
} else if (status->avionics_power_rail_voltage < 4.9f) {
@@ -210,11 +216,35 @@ arming_state_transition(struct vehicle_status_s *status, ///< current vehicle s
valid_transition = true;
}
- /* Sensors need to be initialized for STANDBY state */
- if (new_arming_state == vehicle_status_s::ARMING_STATE_STANDBY && !status->condition_system_sensors_initialized) {
- mavlink_log_critical(mavlink_fd, "NOT ARMING: Sensors not operational.");
+ // Sensors need to be initialized for STANDBY state, except for HIL
+ if ((status->hil_state != vehicle_status_s::HIL_STATE_ON) &&
+ (new_arming_state == vehicle_status_s::ARMING_STATE_STANDBY) &&
+ (!status->condition_system_sensors_initialized)) {
+ mavlink_and_console_log_critical(mavlink_fd, "Not ready to fly: Sensors need inspection");
feedback_provided = true;
valid_transition = false;
+ status->arming_state = vehicle_status_s::ARMING_STATE_STANDBY_ERROR;
+ }
+
+ // Check if we are trying to arm, checks look good but we are in STANDBY_ERROR
+ if (status->arming_state == vehicle_status_s::ARMING_STATE_STANDBY_ERROR) {
+
+ if (new_arming_state == vehicle_status_s::ARMING_STATE_ARMED) {
+
+ if (status->condition_system_sensors_initialized) {
+ mavlink_and_console_log_critical(mavlink_fd, "Preflight check now OK, power cycle before arming");
+ } else {
+ mavlink_and_console_log_critical(mavlink_fd, "Preflight check failed, refusing to arm");
+ }
+ feedback_provided = true;
+
+ } else if ((new_arming_state == vehicle_status_s::ARMING_STATE_STANDBY) &&
+ status->condition_system_sensors_initialized) {
+ mavlink_and_console_log_critical(mavlink_fd, "Preflight check resolved, power cycle to complete");
+ feedback_provided = true;
+ } else {
+
+ }
}
// Finish up the state transition
@@ -649,69 +679,15 @@ bool set_nav_state(struct vehicle_status_s *status, const bool data_link_loss_en
int prearm_check(const struct vehicle_status_s *status, const int mavlink_fd)
{
- int ret;
- bool failed = false;
-
- int fd = open(ACCEL0_DEVICE_PATH, O_RDONLY);
-
- if (fd < 0) {
- mavlink_log_critical(mavlink_fd, "ARM FAIL: ACCEL SENSOR MISSING");
- failed = true;
- goto system_eval;
- }
-
- ret = ioctl(fd, ACCELIOCSELFTEST, 0);
-
- if (ret != OK) {
- mavlink_log_critical(mavlink_fd, "ARM FAIL: ACCEL CALIBRATION");
- failed = true;
- goto system_eval;
- }
-
- /* check measurement result range */
- struct accel_report acc;
- ret = read(fd, &acc, sizeof(acc));
-
- if (ret == sizeof(acc)) {
- /* evaluate values */
- float accel_magnitude = sqrtf(acc.x * acc.x + acc.y * acc.y + acc.z * acc.z);
-
- if (accel_magnitude < 4.0f || accel_magnitude > 15.0f /* m/s^2 */) {
- mavlink_log_critical(mavlink_fd, "ARM FAIL: ACCEL RANGE, hold still");
- /* this is frickin' fatal */
- failed = true;
- goto system_eval;
- }
- } else {
- mavlink_log_critical(mavlink_fd, "ARM FAIL: ACCEL READ");
- /* this is frickin' fatal */
- failed = true;
- goto system_eval;
- }
-
+ /* at this point this equals the preflight check, but might add additional
+ * quantities later.
+ */
+ bool checkAirspeed = false;
/* Perform airspeed check only if circuit breaker is not
* engaged and it's not a rotary wing */
if (!status->circuit_breaker_engaged_airspd_check && !status->is_rotary_wing) {
- /* accel done, close it */
- close(fd);
- fd = orb_subscribe(ORB_ID(airspeed));
-
- struct airspeed_s airspeed;
-
- if ((ret = orb_copy(ORB_ID(airspeed), fd, &airspeed)) ||
- (hrt_elapsed_time(&airspeed.timestamp) > (500 * 1000))) {
- mavlink_log_critical(mavlink_fd, "ARM FAIL: AIRSPEED SENSOR MISSING");
- failed = true;
- goto system_eval;
- }
-
- if (fabsf(airspeed.indicated_airspeed_m_s > 6.0f)) {
- mavlink_log_critical(mavlink_fd, "AIRSPEED WARNING: WIND OR CALIBRATION ISSUE");
- // XXX do not make this fatal yet
- }
+ checkAirspeed = true;
}
-system_eval:
- close(fd);
- return (failed);
+ return !Commander::preflightCheck(mavlink_fd, true, true, true, true, checkAirspeed, true, true);
}
diff --git a/src/modules/dataman/dataman.c b/src/modules/dataman/dataman.c
index 68bf12024..b442b7430 100644
--- a/src/modules/dataman/dataman.c
+++ b/src/modules/dataman/dataman.c
@@ -685,20 +685,21 @@ task_main(int argc, char *argv[])
fsync(g_task_fd);
+ printf("dataman: ");
/* see if we need to erase any items based on restart type */
int sys_restart_val;
if (param_get(param_find("SYS_RESTART_TYPE"), &sys_restart_val) == OK) {
if (sys_restart_val == DM_INIT_REASON_POWER_ON) {
- warnx("Power on restart");
+ printf("Power on restart");
_restart(DM_INIT_REASON_POWER_ON);
} else if (sys_restart_val == DM_INIT_REASON_IN_FLIGHT) {
- warnx("In flight restart");
+ printf("In flight restart");
_restart(DM_INIT_REASON_IN_FLIGHT);
} else {
- warnx("Unknown restart");
+ printf("Unknown restart");
}
} else {
- warnx("Unknown restart");
+ printf("Unknown restart");
}
/* We use two file descriptors, one for the caller context and one for the worker thread */
@@ -706,7 +707,7 @@ task_main(int argc, char *argv[])
/* worker thread is shutting down but still processing requests */
g_fd = g_task_fd;
- warnx("Initialized, data manager file '%s' size is %d bytes", k_data_manager_device_path, max_offset);
+ printf(", data manager file '%s' size is %d bytes\n", k_data_manager_device_path, max_offset);
/* Tell startup that the worker thread has completed its initialization */
sem_post(&g_init_sema);
diff --git a/src/modules/ekf_att_pos_estimator/ekf_att_pos_estimator_main.cpp b/src/modules/ekf_att_pos_estimator/ekf_att_pos_estimator_main.cpp
index c16e72ea0..e0b4cb2a0 100644
--- a/src/modules/ekf_att_pos_estimator/ekf_att_pos_estimator_main.cpp
+++ b/src/modules/ekf_att_pos_estimator/ekf_att_pos_estimator_main.cpp
@@ -937,7 +937,7 @@ void AttitudePositionEstimatorEKF::updateSensorFusion(const bool fuseGPS, const
// Convert GPS measurements to Pos NE, hgt and Vel NED
// set fusion flags
- _ekf->fuseVelData = true;
+ _ekf->fuseVelData = _gps.vel_ned_valid;
_ekf->fusePosData = true;
// recall states stored at time of measurement after adjusting for delays
@@ -1422,30 +1422,41 @@ void AttitudePositionEstimatorEKF::pollData()
int last_mag_main = _mag_main;
- // XXX we compensate the offsets upfront - should be close to zero.
+ Vector3f mag0(_sensor_combined.magnetometer_ga[0], _sensor_combined.magnetometer_ga[1],
+ _sensor_combined.magnetometer_ga[2]);
+
+ Vector3f mag1(_sensor_combined.magnetometer1_ga[0], _sensor_combined.magnetometer1_ga[1],
+ _sensor_combined.magnetometer1_ga[2]);
+
+ const unsigned mag_timeout_us = 200000;
/* fail over to the 2nd mag if we know the first is down */
- if (_sensor_combined.magnetometer_errcount <= _sensor_combined.magnetometer1_errcount) {
- _ekf->magData.x = _sensor_combined.magnetometer_ga[0];
+ if (hrt_elapsed_time(&_sensor_combined.magnetometer_timestamp) < mag_timeout_us &&
+ _sensor_combined.magnetometer_errcount <= _sensor_combined.magnetometer1_errcount &&
+ mag0.length() > 0.1f) {
+ _ekf->magData.x = mag0.x;
_ekf->magBias.x = 0.000001f; // _mag_offsets.x_offset
- _ekf->magData.y = _sensor_combined.magnetometer_ga[1];
+ _ekf->magData.y = mag0.y;
_ekf->magBias.y = 0.000001f; // _mag_offsets.y_offset
- _ekf->magData.z = _sensor_combined.magnetometer_ga[2];
+ _ekf->magData.z = mag0.z;
_ekf->magBias.z = 0.000001f; // _mag_offsets.y_offset
_mag_main = 0;
- } else {
- _ekf->magData.x = _sensor_combined.magnetometer1_ga[0];
+ } else if (hrt_elapsed_time(&_sensor_combined.magnetometer1_timestamp) < mag_timeout_us &&
+ mag1.length() > 0.1f) {
+ _ekf->magData.x = mag1.x;
_ekf->magBias.x = 0.000001f; // _mag_offsets.x_offset
- _ekf->magData.y = _sensor_combined.magnetometer1_ga[1];
+ _ekf->magData.y = mag1.y;
_ekf->magBias.y = 0.000001f; // _mag_offsets.y_offset
- _ekf->magData.z = _sensor_combined.magnetometer1_ga[2];
+ _ekf->magData.z = mag1.z;
_ekf->magBias.z = 0.000001f; // _mag_offsets.y_offset
_mag_main = 1;
+ } else {
+ _mag_valid = false;
}
if (last_mag_main != _mag_main) {
@@ -1516,7 +1527,7 @@ int AttitudePositionEstimatorEKF::trip_nan()
int ekf_att_pos_estimator_main(int argc, char *argv[])
{
- if (argc < 1) {
+ if (argc < 2) {
errx(1, "usage: ekf_att_pos_estimator {start|stop|status|logging}");
}
diff --git a/src/modules/fixedwing_backside/fixedwing_backside_main.cpp b/src/modules/fixedwing_backside/fixedwing_backside_main.cpp
index 71b387b1e..bd1486324 100644
--- a/src/modules/fixedwing_backside/fixedwing_backside_main.cpp
+++ b/src/modules/fixedwing_backside/fixedwing_backside_main.cpp
@@ -97,8 +97,9 @@ usage(const char *reason)
int fixedwing_backside_main(int argc, char *argv[])
{
- if (argc < 1)
+ if (argc < 2) {
usage("missing command");
+ }
if (!strcmp(argv[1], "start")) {
diff --git a/src/modules/fw_att_control/fw_att_control_main.cpp b/src/modules/fw_att_control/fw_att_control_main.cpp
index 8b41144f6..0a8d07fed 100644
--- a/src/modules/fw_att_control/fw_att_control_main.cpp
+++ b/src/modules/fw_att_control/fw_att_control_main.cpp
@@ -1134,8 +1134,9 @@ FixedwingAttitudeControl::start()
int fw_att_control_main(int argc, char *argv[])
{
- if (argc < 1)
+ if (argc < 2) {
errx(1, "usage: fw_att_control {start|stop|status}");
+ }
if (!strcmp(argv[1], "start")) {
diff --git a/src/modules/fw_att_control/fw_att_control_params.c b/src/modules/fw_att_control/fw_att_control_params.c
index cfc5ae965..6b248cbe2 100644
--- a/src/modules/fw_att_control/fw_att_control_params.c
+++ b/src/modules/fw_att_control/fw_att_control_params.c
@@ -136,8 +136,7 @@ PARAM_DEFINE_FLOAT(FW_PR_IMAX, 0.2f);
* @max 2.0
* @group FW Attitude Control
*/
-PARAM_DEFINE_FLOAT(FW_P_ROLLFF,
- 0.0f); //xxx: set to 0 as default, see comment in ECL_PitchController::control_attitude (float turn_offset = ...)
+PARAM_DEFINE_FLOAT(FW_P_ROLLFF, 0.0f);
/**
* Roll rate proportional Gain
diff --git a/src/modules/fw_pos_control_l1/fw_pos_control_l1_main.cpp b/src/modules/fw_pos_control_l1/fw_pos_control_l1_main.cpp
index 427df9739..34265d6a4 100644
--- a/src/modules/fw_pos_control_l1/fw_pos_control_l1_main.cpp
+++ b/src/modules/fw_pos_control_l1/fw_pos_control_l1_main.cpp
@@ -1638,8 +1638,9 @@ FixedwingPositionControl::start()
int fw_pos_control_l1_main(int argc, char *argv[])
{
- if (argc < 1)
+ if (argc < 2) {
errx(1, "usage: fw_pos_control_l1 {start|stop|status}");
+ }
if (!strcmp(argv[1], "start")) {
diff --git a/src/modules/fw_pos_control_l1/mtecs/mTecs_params.c b/src/modules/fw_pos_control_l1/mtecs/mTecs_params.c
index 58a1e9f6b..fff506865 100644
--- a/src/modules/fw_pos_control_l1/mtecs/mTecs_params.c
+++ b/src/modules/fw_pos_control_l1/mtecs/mTecs_params.c
@@ -157,8 +157,8 @@ PARAM_DEFINE_FLOAT(MT_THR_MAX, 1.0f);
/**
* Minimal Pitch Setpoint in Degrees
*
- * @min -90.0f
- * @max 90.0f
+ * @min -90.0
+ * @max 90.0
* @unit deg
* @group mTECS
*/
@@ -167,8 +167,8 @@ PARAM_DEFINE_FLOAT(MT_PIT_MIN, -45.0f);
/**
* Maximal Pitch Setpoint in Degrees
*
- * @min -90.0f
- * @max 90.0f
+ * @min -90.0
+ * @max 90.0
* @unit deg
* @group mTECS
*/
@@ -192,8 +192,8 @@ PARAM_DEFINE_FLOAT(MT_FPA_LP, 1.0f);
* P gain for the altitude control
* Maps the altitude error to the flight path angle setpoint
*
- * @min 0.0f
- * @max 10.0f
+ * @min 0.0
+ * @max 10.0
* @group mTECS
*/
PARAM_DEFINE_FLOAT(MT_FPA_P, 0.3f);
@@ -202,8 +202,8 @@ PARAM_DEFINE_FLOAT(MT_FPA_P, 0.3f);
* D gain for the altitude control
* Maps the change of altitude error to the flight path angle setpoint
*
- * @min 0.0f
- * @max 10.0f
+ * @min 0.0
+ * @max 10.0
* @group mTECS
*/
PARAM_DEFINE_FLOAT(MT_FPA_D, 0.0f);
@@ -219,8 +219,8 @@ PARAM_DEFINE_FLOAT(MT_FPA_D_LP, 1.0f);
/**
* Minimal flight path angle setpoint
*
- * @min -90.0f
- * @max 90.0f
+ * @min -90.0
+ * @max 90.0
* @unit deg
* @group mTECS
*/
@@ -229,8 +229,8 @@ PARAM_DEFINE_FLOAT(MT_FPA_MIN, -20.0f);
/**
* Maximal flight path angle setpoint
*
- * @min -90.0f
- * @max 90.0f
+ * @min -90.0
+ * @max 90.0
* @unit deg
* @group mTECS
*/
@@ -254,8 +254,8 @@ PARAM_DEFINE_FLOAT(MT_AD_LP, 0.5f);
* P gain for the airspeed control
* Maps the airspeed error to the acceleration setpoint
*
- * @min 0.0f
- * @max 10.0f
+ * @min 0.0
+ * @max 10.0
* @group mTECS
*/
PARAM_DEFINE_FLOAT(MT_ACC_P, 0.3f);
@@ -264,8 +264,8 @@ PARAM_DEFINE_FLOAT(MT_ACC_P, 0.3f);
* D gain for the airspeed control
* Maps the change of airspeed error to the acceleration setpoint
*
- * @min 0.0f
- * @max 10.0f
+ * @min 0.0
+ * @max 10.0
* @group mTECS
*/
PARAM_DEFINE_FLOAT(MT_ACC_D, 0.0f);
@@ -296,8 +296,8 @@ PARAM_DEFINE_FLOAT(MT_ACC_MAX, 40.0f);
/**
* Minimal throttle during takeoff
*
- * @min 0.0f
- * @max 1.0f
+ * @min 0.0
+ * @max 1.0
* @group mTECS
*/
PARAM_DEFINE_FLOAT(MT_TKF_THR_MIN, 1.0f);
@@ -305,8 +305,8 @@ PARAM_DEFINE_FLOAT(MT_TKF_THR_MIN, 1.0f);
/**
* Maximal throttle during takeoff
*
- * @min 0.0f
- * @max 1.0f
+ * @min 0.0
+ * @max 1.0
* @group mTECS
*/
PARAM_DEFINE_FLOAT(MT_TKF_THR_MAX, 1.0f);
@@ -314,8 +314,8 @@ PARAM_DEFINE_FLOAT(MT_TKF_THR_MAX, 1.0f);
/**
* Minimal pitch during takeoff
*
- * @min -90.0f
- * @max 90.0f
+ * @min -90.0
+ * @max 90.0
* @unit deg
* @group mTECS
*/
@@ -324,8 +324,8 @@ PARAM_DEFINE_FLOAT(MT_TKF_PIT_MIN, 0.0f);
/**
* Maximal pitch during takeoff
*
- * @min -90.0f
- * @max 90.0f
+ * @min -90.0
+ * @max 90.0
* @unit deg
* @group mTECS
*/
@@ -334,8 +334,8 @@ PARAM_DEFINE_FLOAT(MT_TKF_PIT_MAX, 45.0f);
/**
* Minimal throttle in underspeed mode
*
- * @min 0.0f
- * @max 1.0f
+ * @min 0.0
+ * @max 1.0
* @group mTECS
*/
PARAM_DEFINE_FLOAT(MT_USP_THR_MIN, 1.0f);
@@ -343,8 +343,8 @@ PARAM_DEFINE_FLOAT(MT_USP_THR_MIN, 1.0f);
/**
* Maximal throttle in underspeed mode
*
- * @min 0.0f
- * @max 1.0f
+ * @min 0.0
+ * @max 1.0
* @group mTECS
*/
PARAM_DEFINE_FLOAT(MT_USP_THR_MAX, 1.0f);
@@ -352,8 +352,8 @@ PARAM_DEFINE_FLOAT(MT_USP_THR_MAX, 1.0f);
/**
* Minimal pitch in underspeed mode
*
- * @min -90.0f
- * @max 90.0f
+ * @min -90.0
+ * @max 90.0
* @unit deg
* @group mTECS
*/
@@ -362,8 +362,8 @@ PARAM_DEFINE_FLOAT(MT_USP_PIT_MIN, -45.0f);
/**
* Maximal pitch in underspeed mode
*
- * @min -90.0f
- * @max 90.0f
+ * @min -90.0
+ * @max 90.0
* @unit deg
* @group mTECS
*/
@@ -372,8 +372,8 @@ PARAM_DEFINE_FLOAT(MT_USP_PIT_MAX, 0.0f);
/**
* Minimal throttle in landing mode (only last phase of landing)
*
- * @min 0.0f
- * @max 1.0f
+ * @min 0.0
+ * @max 1.0
* @group mTECS
*/
PARAM_DEFINE_FLOAT(MT_LND_THR_MIN, 0.0f);
@@ -381,8 +381,8 @@ PARAM_DEFINE_FLOAT(MT_LND_THR_MIN, 0.0f);
/**
* Maximal throttle in landing mode (only last phase of landing)
*
- * @min 0.0f
- * @max 1.0f
+ * @min 0.0
+ * @max 1.0
* @group mTECS
*/
PARAM_DEFINE_FLOAT(MT_LND_THR_MAX, 0.0f);
@@ -390,8 +390,8 @@ PARAM_DEFINE_FLOAT(MT_LND_THR_MAX, 0.0f);
/**
* Minimal pitch in landing mode
*
- * @min -90.0f
- * @max 90.0f
+ * @min -90.0
+ * @max 90.0
* @unit deg
* @group mTECS
*/
@@ -400,8 +400,8 @@ PARAM_DEFINE_FLOAT(MT_LND_PIT_MIN, -5.0f);
/**
* Maximal pitch in landing mode
*
- * @min -90.0f
- * @max 90.0f
+ * @min -90.0
+ * @max 90.0
* @unit deg
* @group mTECS
*/
@@ -410,8 +410,8 @@ PARAM_DEFINE_FLOAT(MT_LND_PIT_MAX, 15.0f);
/**
* Integrator Limit for Total Energy Rate Control
*
- * @min 0.0f
- * @max 10.0f
+ * @min 0.0
+ * @max 10.0
* @group mTECS
*/
PARAM_DEFINE_FLOAT(MT_THR_I_MAX, 10.0f);
@@ -419,8 +419,8 @@ PARAM_DEFINE_FLOAT(MT_THR_I_MAX, 10.0f);
/**
* Integrator Limit for Energy Distribution Rate Control
*
- * @min 0.0f
- * @max 10.0f
+ * @min 0.0
+ * @max 10.0
* @group mTECS
*/
PARAM_DEFINE_FLOAT(MT_PIT_I_MAX, 10.0f);
diff --git a/src/modules/land_detector/land_detector_main.cpp b/src/modules/land_detector/land_detector_main.cpp
index 011567e57..b4b7c33a2 100644
--- a/src/modules/land_detector/land_detector_main.cpp
+++ b/src/modules/land_detector/land_detector_main.cpp
@@ -178,7 +178,7 @@ static int land_detector_start(const char *mode)
int land_detector_main(int argc, char *argv[])
{
- if (argc < 1) {
+ if (argc < 2) {
goto exiterr;
}
diff --git a/src/modules/mavlink/mavlink.c b/src/modules/mavlink/mavlink.c
index 9afe74af1..796d5cbf2 100644
--- a/src/modules/mavlink/mavlink.c
+++ b/src/modules/mavlink/mavlink.c
@@ -64,14 +64,18 @@ PARAM_DEFINE_INT32(MAV_COMP_ID, 50);
PARAM_DEFINE_INT32(MAV_TYPE, MAV_TYPE_FIXED_WING);
/**
* Use/Accept HIL GPS message (even if not in HIL mode)
+ *
* If set to 1 incomming HIL GPS messages are parsed.
+ *
* @group MAVLink
*/
PARAM_DEFINE_INT32(MAV_USEHILGPS, 0);
/**
* Forward external setpoint messages
+ *
* If set to 1 incomming external setpoint messages will be directly forwarded to the controllers if in offboard
* control mode
+ *
* @group MAVLink
*/
PARAM_DEFINE_INT32(MAV_FWDEXTSP, 1);
diff --git a/src/modules/mavlink/mavlink_main.cpp b/src/modules/mavlink/mavlink_main.cpp
index ba049bac4..22ff3edf6 100644
--- a/src/modules/mavlink/mavlink_main.cpp
+++ b/src/modules/mavlink/mavlink_main.cpp
@@ -90,7 +90,7 @@
static const int ERROR = -1;
#define DEFAULT_DEVICE_NAME "/dev/ttyS1"
-#define MAX_DATA_RATE 20000 ///< max data rate in bytes/s
+#define MAX_DATA_RATE 60000 ///< max data rate in bytes/s
#define MAIN_LOOP_DELAY 10000 ///< 100 Hz @ 1000 bytes/s data rate
#define FLOW_CONTROL_DISABLE_THRESHOLD 40 ///< picked so that some messages still would fit it.
diff --git a/src/modules/mavlink/mavlink_messages.cpp b/src/modules/mavlink/mavlink_messages.cpp
index 7d6b60e22..7ddc52fd1 100644
--- a/src/modules/mavlink/mavlink_messages.cpp
+++ b/src/modules/mavlink/mavlink_messages.cpp
@@ -539,7 +539,8 @@ protected:
msg.errors_count2 = status.errors_count2;
msg.errors_count3 = status.errors_count3;
msg.errors_count4 = status.errors_count4;
- msg.battery_remaining = status.battery_remaining * 100.0f;
+ msg.battery_remaining = (msg.voltage_battery > 0) ?
+ status.battery_remaining * 100.0f : -1;
_mavlink->send_message(MAVLINK_MSG_ID_SYS_STATUS, &msg);
}
@@ -1867,29 +1868,8 @@ protected:
struct rc_input_values rc;
if (_rc_sub->update(&_rc_time, &rc)) {
- const unsigned port_width = 8;
-
- /* deprecated message (but still needed for compatibility!) */
- for (unsigned i = 0; (i * port_width) < rc.channel_count; i++) {
- /* channels are sent in MAVLink main loop at a fixed interval */
- mavlink_rc_channels_raw_t msg;
-
- msg.time_boot_ms = rc.timestamp_publication / 1000;
- msg.port = i;
- msg.chan1_raw = (rc.channel_count > (i * port_width) + 0) ? rc.values[(i * port_width) + 0] : UINT16_MAX;
- msg.chan2_raw = (rc.channel_count > (i * port_width) + 1) ? rc.values[(i * port_width) + 1] : UINT16_MAX;
- msg.chan3_raw = (rc.channel_count > (i * port_width) + 2) ? rc.values[(i * port_width) + 2] : UINT16_MAX;
- msg.chan4_raw = (rc.channel_count > (i * port_width) + 3) ? rc.values[(i * port_width) + 3] : UINT16_MAX;
- msg.chan5_raw = (rc.channel_count > (i * port_width) + 4) ? rc.values[(i * port_width) + 4] : UINT16_MAX;
- msg.chan6_raw = (rc.channel_count > (i * port_width) + 5) ? rc.values[(i * port_width) + 5] : UINT16_MAX;
- msg.chan7_raw = (rc.channel_count > (i * port_width) + 6) ? rc.values[(i * port_width) + 6] : UINT16_MAX;
- msg.chan8_raw = (rc.channel_count > (i * port_width) + 7) ? rc.values[(i * port_width) + 7] : UINT16_MAX;
- msg.rssi = rc.rssi;
-
- _mavlink->send_message(MAVLINK_MSG_ID_RC_CHANNELS_RAW, &msg);
- }
- /* new message */
+ /* send RC channel data and RSSI */
mavlink_rc_channels_t msg;
msg.time_boot_ms = rc.timestamp_publication / 1000;
@@ -1913,55 +1893,7 @@ protected:
msg.chan17_raw = (rc.channel_count > 16) ? rc.values[16] : UINT16_MAX;
msg.chan18_raw = (rc.channel_count > 17) ? rc.values[17] : UINT16_MAX;
- /* RSSI has a max value of 100, and when Spektrum or S.BUS are
- * available, the RSSI field is invalid, as they do not provide
- * an RSSI measurement. Use an out of band magic value to signal
- * these digital ports. XXX revise MAVLink spec to address this.
- * One option would be to use the top bit to toggle between RSSI
- * and input source mode.
- *
- * Full RSSI field: 0b 1 111 1111
- *
- * ^ If bit is set, RSSI encodes type + RSSI
- *
- * ^ These three bits encode a total of 8
- * digital RC input types.
- * 0: PPM, 1: SBUS, 2: Spektrum, 2: ST24
- * ^ These four bits encode a total of
- * 16 RSSI levels. 15 = full, 0 = no signal
- *
- */
-
- /* Initialize RSSI with the special mode level flag */
- msg.rssi = (1 << 7);
-
- /* Set RSSI */
- msg.rssi |= (rc.rssi <= 100) ? ((rc.rssi / 7) + 1) : 15;
-
- switch (rc.input_source) {
- case RC_INPUT_SOURCE_PX4FMU_PPM:
- /* fallthrough */
- case RC_INPUT_SOURCE_PX4IO_PPM:
- msg.rssi |= (0 << 4);
- break;
- case RC_INPUT_SOURCE_PX4IO_SPEKTRUM:
- msg.rssi |= (1 << 4);
- break;
- case RC_INPUT_SOURCE_PX4IO_SBUS:
- msg.rssi |= (2 << 4);
- break;
- case RC_INPUT_SOURCE_PX4IO_ST24:
- msg.rssi |= (3 << 4);
- break;
- case RC_INPUT_SOURCE_UNKNOWN:
- // do nothing
- break;
- }
-
- if (rc.rc_lost) {
- /* RSSI is by definition zero */
- msg.rssi = 0;
- }
+ msg.rssi = rc.rssi;
_mavlink->send_message(MAVLINK_MSG_ID_RC_CHANNELS, &msg);
}
@@ -2299,7 +2231,7 @@ protected:
};
-StreamListItem *streams_list[] = {
+const StreamListItem *streams_list[] = {
new StreamListItem(&MavlinkStreamHeartbeat::new_instance, &MavlinkStreamHeartbeat::get_name_static),
new StreamListItem(&MavlinkStreamStatustext::new_instance, &MavlinkStreamStatustext::get_name_static),
new StreamListItem(&MavlinkStreamCommandLong::new_instance, &MavlinkStreamCommandLong::get_name_static),
diff --git a/src/modules/mavlink/mavlink_messages.h b/src/modules/mavlink/mavlink_messages.h
index 7e4416609..5b6b9d633 100644
--- a/src/modules/mavlink/mavlink_messages.h
+++ b/src/modules/mavlink/mavlink_messages.h
@@ -56,6 +56,6 @@ public:
~StreamListItem() {};
};
-extern StreamListItem *streams_list[];
+extern const StreamListItem *streams_list[];
#endif /* MAVLINK_MESSAGES_H_ */
diff --git a/src/modules/mavlink/mavlink_parameters.cpp b/src/modules/mavlink/mavlink_parameters.cpp
index e7e0c11df..9c8794017 100644
--- a/src/modules/mavlink/mavlink_parameters.cpp
+++ b/src/modules/mavlink/mavlink_parameters.cpp
@@ -74,7 +74,6 @@ MavlinkParametersManager::handle_message(const mavlink_message_t *msg)
(req_list.target_component == mavlink_system.compid || req_list.target_component == MAV_COMP_ID_ALL)) {
_send_all_index = 0;
- _mavlink->send_statustext_info("[pm] sending list");
}
break;
}
@@ -131,7 +130,7 @@ MavlinkParametersManager::handle_message(const mavlink_message_t *msg)
} else {
/* when index is >= 0, send this parameter again */
- send_param(param_for_index(req_read.param_index));
+ send_param(param_for_used_index(req_read.param_index));
}
}
break;
@@ -193,6 +192,7 @@ MavlinkParametersManager::send(const hrt_abstime t)
/* look for the first parameter which is used */
param_t p;
do {
+ /* walk through all parameters, including unused ones */
p = param_for_index(_send_all_index);
_send_all_index++;
} while (p != PARAM_INVALID && !param_used(p));
@@ -201,7 +201,7 @@ MavlinkParametersManager::send(const hrt_abstime t)
send_param(p);
}
- if (_send_all_index >= (int) param_count()) {
+ if ((p == PARAM_INVALID) || (_send_all_index >= (int) param_count())) {
_send_all_index = -1;
}
}
diff --git a/src/modules/mavlink/mavlink_receiver.cpp b/src/modules/mavlink/mavlink_receiver.cpp
index 3f9f7e139..c4e332bf1 100644
--- a/src/modules/mavlink/mavlink_receiver.cpp
+++ b/src/modules/mavlink/mavlink_receiver.cpp
@@ -121,6 +121,7 @@ MavlinkReceiver::MavlinkReceiver(Mavlink *parent) :
_rc_pub(-1),
_manual_pub(-1),
_land_detector_pub(-1),
+ _time_offset_pub(-1),
_control_mode_sub(orb_subscribe(ORB_ID(vehicle_control_mode))),
_hil_frames(0),
_old_timestamp(0),
@@ -729,8 +730,8 @@ MavlinkReceiver::handle_message_vision_position_estimate(mavlink_message_t *msg)
// Use the component ID to identify the vision sensor
vision_position.id = msg->compid;
- vision_position.timestamp_boot = to_hrt(pos.usec); // Synced time
- vision_position.timestamp_computer = pos.usec;
+ vision_position.timestamp_boot = hrt_absolute_time(); // Monotonic time
+ vision_position.timestamp_computer = sync_stamp(pos.usec); // Synced time
vision_position.x = pos.x;
vision_position.y = pos.y;
vision_position.z = pos.z;
@@ -821,7 +822,7 @@ MavlinkReceiver::handle_message_set_attitude_target(mavlink_message_t *msg)
/* Publish attitude setpoint if attitude and thrust ignore bits are not set */
if (!(_offboard_control_mode.ignore_attitude)) {
- static struct vehicle_attitude_setpoint_s att_sp = {};
+ struct vehicle_attitude_setpoint_s att_sp = {};
att_sp.timestamp = hrt_absolute_time();
mavlink_quaternion_to_euler(set_attitude_target.q,
&att_sp.roll_body, &att_sp.pitch_body, &att_sp.yaw_body);
@@ -1013,6 +1014,9 @@ MavlinkReceiver::handle_message_timesync(mavlink_message_t *msg)
mavlink_timesync_t tsync;
mavlink_msg_timesync_decode(msg, &tsync);
+ struct time_offset_s tsync_offset;
+ memset(&tsync_offset, 0, sizeof(tsync_offset));
+
uint64_t now_ns = hrt_absolute_time() * 1000LL ;
if (tsync.tc1 == 0) {
@@ -1039,6 +1043,15 @@ MavlinkReceiver::handle_message_timesync(mavlink_message_t *msg)
}
}
+ tsync_offset.offset_ns = _time_offset ;
+
+ if (_time_offset_pub < 0) {
+ _time_offset_pub = orb_advertise(ORB_ID(time_offset), &tsync_offset);
+
+ } else {
+ orb_publish(ORB_ID(time_offset), _time_offset_pub, &tsync_offset);
+ }
+
}
void
@@ -1522,9 +1535,12 @@ void MavlinkReceiver::print_status()
}
-uint64_t MavlinkReceiver::to_hrt(uint64_t usec)
+uint64_t MavlinkReceiver::sync_stamp(uint64_t usec)
{
- return usec - (_time_offset / 1000) ;
+ if(_time_offset > 0)
+ return usec - (_time_offset / 1000) ;
+ else
+ return hrt_absolute_time();
}
diff --git a/src/modules/mavlink/mavlink_receiver.h b/src/modules/mavlink/mavlink_receiver.h
index ffacb59a6..2b6174f8f 100644
--- a/src/modules/mavlink/mavlink_receiver.h
+++ b/src/modules/mavlink/mavlink_receiver.h
@@ -73,6 +73,7 @@
#include <uORB/topics/airspeed.h>
#include <uORB/topics/battery_status.h>
#include <uORB/topics/vehicle_force_setpoint.h>
+#include <uORB/topics/time_offset.h>
#include "mavlink_ftp.h"
@@ -138,9 +139,10 @@ private:
void *receive_thread(void *arg);
/**
- * Convert remote nsec timestamp to local hrt time (usec)
+ * Convert remote timestamp to local hrt time (usec)
+ * Use timesync if available, monotonic boot time otherwise
*/
- uint64_t to_hrt(uint64_t nsec);
+ uint64_t sync_stamp(uint64_t usec);
/**
* Exponential moving average filter to smooth time offset
*/
@@ -177,6 +179,7 @@ private:
orb_advert_t _rc_pub;
orb_advert_t _manual_pub;
orb_advert_t _land_detector_pub;
+ orb_advert_t _time_offset_pub;
int _control_mode_sub;
int _hil_frames;
uint64_t _old_timestamp;
diff --git a/src/modules/mc_att_control/mc_att_control_main.cpp b/src/modules/mc_att_control/mc_att_control_main.cpp
index d47731622..ec512ab56 100644
--- a/src/modules/mc_att_control/mc_att_control_main.cpp
+++ b/src/modules/mc_att_control/mc_att_control_main.cpp
@@ -77,6 +77,8 @@
#include <uORB/topics/vehicle_status.h>
#include <uORB/topics/actuator_armed.h>
#include <uORB/topics/parameter_update.h>
+#include <uORB/topics/multirotor_motor_limits.h>
+#include <uORB/topics/mc_att_ctrl_status.h>
#include <systemlib/param/param.h>
#include <systemlib/err.h>
#include <systemlib/perf_counter.h>
@@ -129,10 +131,12 @@ private:
int _manual_control_sp_sub; /**< manual control setpoint subscription */
int _armed_sub; /**< arming status subscription */
int _vehicle_status_sub; /**< vehicle status subscription */
+ int _motor_limits_sub; /**< motor limits subscription */
orb_advert_t _att_sp_pub; /**< attitude setpoint publication */
orb_advert_t _v_rates_sp_pub; /**< rate setpoint publication */
orb_advert_t _actuators_0_pub; /**< attitude actuator controls publication */
+ orb_advert_t _controller_status_pub; /**< controller status publication */
orb_id_t _rates_sp_id; /**< pointer to correct rates setpoint uORB metadata structure */
orb_id_t _actuators_id; /**< pointer to correct actuator controls0 uORB metadata structure */
@@ -147,6 +151,8 @@ private:
struct actuator_controls_s _actuators; /**< actuator controls */
struct actuator_armed_s _armed; /**< actuator arming status */
struct vehicle_status_s _vehicle_status; /**< vehicle status */
+ struct multirotor_motor_limits_s _motor_limits; /**< motor limits */
+ struct mc_att_ctrl_status_s _controller_status; /**< controller status */
perf_counter_t _loop_perf; /**< loop performance counter */
perf_counter_t _controller_latency_perf;
@@ -262,6 +268,11 @@ private:
void vehicle_status_poll();
/**
+ * Check for vehicle motor limits status.
+ */
+ void vehicle_motor_limits_poll();
+
+ /**
* Shim for calling task_main from task_create.
*/
static void task_main_trampoline(int argc, char *argv[]);
@@ -302,6 +313,7 @@ MulticopterAttitudeControl::MulticopterAttitudeControl() :
_att_sp_pub(-1),
_v_rates_sp_pub(-1),
_actuators_0_pub(-1),
+ _controller_status_pub(-1),
_rates_sp_id(0),
_actuators_id(0),
@@ -320,6 +332,8 @@ MulticopterAttitudeControl::MulticopterAttitudeControl() :
memset(&_actuators, 0, sizeof(_actuators));
memset(&_armed, 0, sizeof(_armed));
memset(&_vehicle_status, 0, sizeof(_vehicle_status));
+ memset(&_motor_limits, 0, sizeof(_motor_limits));
+ memset(&_controller_status,0,sizeof(_controller_status));
_vehicle_status.is_rotary_wing = true;
_params.att_p.zero();
@@ -570,6 +584,18 @@ MulticopterAttitudeControl::vehicle_status_poll()
}
}
+void
+MulticopterAttitudeControl::vehicle_motor_limits_poll()
+{
+ /* check if there is a new message */
+ bool updated;
+ orb_check(_motor_limits_sub, &updated);
+
+ if (updated) {
+ orb_copy(ORB_ID(multirotor_motor_limits), _motor_limits_sub, &_motor_limits);
+ }
+}
+
/*
* Attitude controller.
* Input: 'manual_control_setpoint' and 'vehicle_attitude_setpoint' topics (depending on mode)
@@ -689,8 +715,8 @@ MulticopterAttitudeControl::control_attitude_rates(float dt)
_att_control = _params.rate_p.emult(rates_err) + _params.rate_d.emult(_rates_prev - rates) / dt + _rates_int + _params.rate_ff.emult(_rates_sp);
_rates_prev = rates;
- /* update integral only if not saturated on low limit */
- if (_thrust_sp > MIN_TAKEOFF_THRUST) {
+ /* update integral only if not saturated on low limit and if motor commands are not saturated */
+ if (_thrust_sp > MIN_TAKEOFF_THRUST && !_motor_limits.lower_limit && !_motor_limits.upper_limit ) {
for (int i = 0; i < 3; i++) {
if (fabsf(_att_control(i)) < _thrust_sp) {
float rate_i = _rates_int(i) + _params.rate_i(i) * rates_err(i) * dt;
@@ -725,6 +751,7 @@ MulticopterAttitudeControl::task_main()
_manual_control_sp_sub = orb_subscribe(ORB_ID(manual_control_setpoint));
_armed_sub = orb_subscribe(ORB_ID(actuator_armed));
_vehicle_status_sub = orb_subscribe(ORB_ID(vehicle_status));
+ _motor_limits_sub = orb_subscribe(ORB_ID(multirotor_motor_limits));
/* initialize parameters cache */
parameters_update();
@@ -777,6 +804,7 @@ MulticopterAttitudeControl::task_main()
arming_status_poll();
vehicle_manual_poll();
vehicle_status_poll();
+ vehicle_motor_limits_poll();
if (_v_control_mode.flag_control_attitude_enabled) {
control_attitude(dt);
@@ -837,6 +865,11 @@ MulticopterAttitudeControl::task_main()
_actuators.timestamp = hrt_absolute_time();
_actuators.timestamp_sample = _v_att.timestamp;
+ _controller_status.roll_rate_integ = _rates_int(0);
+ _controller_status.pitch_rate_integ = _rates_int(1);
+ _controller_status.yaw_rate_integ = _rates_int(2);
+ _controller_status.timestamp = hrt_absolute_time();
+
if (!_actuators_0_circuit_breaker_enabled) {
if (_actuators_0_pub > 0) {
orb_publish(_actuators_id, _actuators_0_pub, &_actuators);
@@ -847,6 +880,13 @@ MulticopterAttitudeControl::task_main()
}
}
+
+ /* publish controller status */
+ if(_controller_status_pub > 0) {
+ orb_publish(ORB_ID(mc_att_ctrl_status),_controller_status_pub, &_controller_status);
+ } else {
+ _controller_status_pub = orb_advertise(ORB_ID(mc_att_ctrl_status), &_controller_status);
+ }
}
}
@@ -868,7 +908,7 @@ MulticopterAttitudeControl::start()
_control_task = task_spawn_cmd("mc_att_control",
SCHED_DEFAULT,
SCHED_PRIORITY_MAX - 5,
- 1600,
+ 1500,
(main_t)&MulticopterAttitudeControl::task_main_trampoline,
nullptr);
@@ -882,8 +922,9 @@ MulticopterAttitudeControl::start()
int mc_att_control_main(int argc, char *argv[])
{
- if (argc < 1)
+ if (argc < 2) {
errx(1, "usage: mc_att_control {start|stop|status}");
+ }
if (!strcmp(argv[1], "start")) {
diff --git a/src/modules/mc_att_control_multiplatform/mc_att_control_start_nuttx.cpp b/src/modules/mc_att_control_multiplatform/mc_att_control_start_nuttx.cpp
index 40eb498b4..dec1e1745 100644
--- a/src/modules/mc_att_control_multiplatform/mc_att_control_start_nuttx.cpp
+++ b/src/modules/mc_att_control_multiplatform/mc_att_control_start_nuttx.cpp
@@ -54,7 +54,7 @@ extern int main(int argc, char **argv);
extern "C" __EXPORT int mc_att_control_m_main(int argc, char *argv[]);
int mc_att_control_m_main(int argc, char *argv[])
{
- if (argc < 1) {
+ if (argc < 2) {
errx(1, "usage: mc_att_control_m {start|stop|status}");
}
diff --git a/src/modules/mc_pos_control/mc_pos_control_main.cpp b/src/modules/mc_pos_control/mc_pos_control_main.cpp
index 4910454bd..6ffb37d97 100644
--- a/src/modules/mc_pos_control/mc_pos_control_main.cpp
+++ b/src/modules/mc_pos_control/mc_pos_control_main.cpp
@@ -1426,7 +1426,7 @@ MulticopterPositionControl::start()
_control_task = task_spawn_cmd("mc_pos_control",
SCHED_DEFAULT,
SCHED_PRIORITY_MAX - 5,
- 1600,
+ 1500,
(main_t)&MulticopterPositionControl::task_main_trampoline,
nullptr);
@@ -1440,7 +1440,7 @@ MulticopterPositionControl::start()
int mc_pos_control_main(int argc, char *argv[])
{
- if (argc < 1) {
+ if (argc < 2) {
errx(1, "usage: mc_pos_control {start|stop|status}");
}
diff --git a/src/modules/mc_pos_control_multiplatform/mc_pos_control_start_nuttx.cpp b/src/modules/mc_pos_control_multiplatform/mc_pos_control_start_nuttx.cpp
index 1082061f6..0db67d83f 100644
--- a/src/modules/mc_pos_control_multiplatform/mc_pos_control_start_nuttx.cpp
+++ b/src/modules/mc_pos_control_multiplatform/mc_pos_control_start_nuttx.cpp
@@ -54,7 +54,7 @@ extern int main(int argc, char **argv);
extern "C" __EXPORT int mc_pos_control_m_main(int argc, char *argv[]);
int mc_pos_control_m_main(int argc, char *argv[])
{
- if (argc < 1) {
+ if (argc < 2) {
errx(1, "usage: mc_pos_control_m {start|stop|status}");
}
diff --git a/src/modules/navigator/datalinkloss.cpp b/src/modules/navigator/datalinkloss.cpp
index 87a6e023a..7925809f1 100644
--- a/src/modules/navigator/datalinkloss.cpp
+++ b/src/modules/navigator/datalinkloss.cpp
@@ -186,7 +186,7 @@ DataLinkLoss::advance_dll()
if (_navigator->get_vstatus()->data_link_lost_counter > _param_numberdatalinklosses.get()) {
warnx("%d data link losses, limit is %d, fly to airfield home",
_navigator->get_vstatus()->data_link_lost_counter, _param_numberdatalinklosses.get());
- mavlink_log_info(_navigator->get_mavlink_fd(), "#audio: too many DL losses, fly to airfield home");
+ mavlink_log_critical(_navigator->get_mavlink_fd(), "too many DL losses, fly to airfield home");
_navigator->get_mission_result()->stay_in_failsafe = true;
_navigator->set_mission_result_updated();
reset_mission_item_reached();
@@ -194,19 +194,19 @@ DataLinkLoss::advance_dll()
} else {
if (!_param_skipcommshold.get()) {
warnx("fly to comms hold, datalink loss counter: %d", _navigator->get_vstatus()->data_link_lost_counter);
- mavlink_log_info(_navigator->get_mavlink_fd(), "#audio: fly to comms hold");
+ mavlink_log_critical(_navigator->get_mavlink_fd(), "fly to comms hold");
_dll_state = DLL_STATE_FLYTOCOMMSHOLDWP;
} else {
/* comms hold wp not active, fly to airfield home directly */
warnx("Skipping comms hold wp. Flying directly to airfield home");
- mavlink_log_info(_navigator->get_mavlink_fd(), "#audio: fly to airfield home, comms hold skipped");
+ mavlink_log_critical(_navigator->get_mavlink_fd(), "fly to airfield home, comms hold skipped");
_dll_state = DLL_STATE_FLYTOAIRFIELDHOMEWP;
}
}
break;
case DLL_STATE_FLYTOCOMMSHOLDWP:
warnx("fly to airfield home");
- mavlink_log_info(_navigator->get_mavlink_fd(), "#audio: fly to airfield home");
+ mavlink_log_critical(_navigator->get_mavlink_fd(), "fly to airfield home");
_dll_state = DLL_STATE_FLYTOAIRFIELDHOMEWP;
_navigator->get_mission_result()->stay_in_failsafe = true;
_navigator->set_mission_result_updated();
@@ -215,7 +215,7 @@ DataLinkLoss::advance_dll()
case DLL_STATE_FLYTOAIRFIELDHOMEWP:
_dll_state = DLL_STATE_TERMINATE;
warnx("time is up, state should have been changed manually by now");
- mavlink_log_info(_navigator->get_mavlink_fd(), "#audio: no manual control, terminating");
+ mavlink_log_critical(_navigator->get_mavlink_fd(), "no manual control, terminating");
_navigator->get_mission_result()->stay_in_failsafe = true;
_navigator->set_mission_result_updated();
reset_mission_item_reached();
diff --git a/src/modules/navigator/datalinkloss_params.c b/src/modules/navigator/datalinkloss_params.c
index 6780c0c88..9abc012cf 100644
--- a/src/modules/navigator/datalinkloss_params.c
+++ b/src/modules/navigator/datalinkloss_params.c
@@ -54,7 +54,7 @@
*
* @unit seconds
* @min 0.0
- * @group DLL
+ * @group Data Link Loss
*/
PARAM_DEFINE_FLOAT(NAV_DLL_CH_T, 120.0f);
@@ -64,8 +64,8 @@ PARAM_DEFINE_FLOAT(NAV_DLL_CH_T, 120.0f);
* Latitude of comms hold waypoint
*
* @unit degrees * 1e7
- * @min 0.0
- * @group DLL
+ * @min 0
+ * @group Data Link Loss
*/
PARAM_DEFINE_INT32(NAV_DLL_CH_LAT, -266072120);
@@ -75,8 +75,8 @@ PARAM_DEFINE_INT32(NAV_DLL_CH_LAT, -266072120);
* Longitude of comms hold waypoint
*
* @unit degrees * 1e7
- * @min 0.0
- * @group DLL
+ * @min 0
+ * @group Data Link Loss
*/
PARAM_DEFINE_INT32(NAV_DLL_CH_LON, 1518453890);
@@ -87,7 +87,7 @@ PARAM_DEFINE_INT32(NAV_DLL_CH_LON, 1518453890);
*
* @unit m
* @min 0.0
- * @group DLL
+ * @group Data Link Loss
*/
PARAM_DEFINE_FLOAT(NAV_DLL_CH_ALT, 600.0f);
@@ -98,7 +98,7 @@ PARAM_DEFINE_FLOAT(NAV_DLL_CH_ALT, 600.0f);
*
* @unit seconds
* @min 0.0
- * @group DLL
+ * @group Data Link Loss
*/
PARAM_DEFINE_FLOAT(NAV_DLL_AH_T, 120.0f);
@@ -107,7 +107,7 @@ PARAM_DEFINE_FLOAT(NAV_DLL_AH_T, 120.0f);
*
* After more than this number of data link timeouts the aircraft returns home directly
*
- * @group DLL
+ * @group Data Link Loss
* @min 0
* @max 1000
*/
@@ -119,7 +119,7 @@ PARAM_DEFINE_INT32(NAV_DLL_N, 2);
* If set to 1 the system will skip the comms hold wp on data link loss and will directly fly to
* airfield home
*
- * @group DLL
+ * @group Data Link Loss
* @min 0
* @max 1
*/
diff --git a/src/modules/navigator/enginefailure.cpp b/src/modules/navigator/enginefailure.cpp
index e007b208b..b0130a1f5 100644
--- a/src/modules/navigator/enginefailure.cpp
+++ b/src/modules/navigator/enginefailure.cpp
@@ -140,7 +140,7 @@ EngineFailure::advance_ef()
{
switch (_ef_state) {
case EF_STATE_NONE:
- mavlink_log_info(_navigator->get_mavlink_fd(), "#audio: Engine failure. Loitering down");
+ mavlink_log_emergency(_navigator->get_mavlink_fd(), "Engine failure. Loitering down");
_ef_state = EF_STATE_LOITERDOWN;
break;
default:
diff --git a/src/modules/navigator/geofence.cpp b/src/modules/navigator/geofence.cpp
index 9bc9be245..1b6610734 100644
--- a/src/modules/navigator/geofence.cpp
+++ b/src/modules/navigator/geofence.cpp
@@ -39,6 +39,7 @@
*/
#include "geofence.h"
+#include <uORB/topics/home_position.h>
#include <uORB/topics/vehicle_global_position.h>
#include <string.h>
#include <dataman/dataman.h>
@@ -49,6 +50,15 @@
#include <nuttx/config.h>
#include <unistd.h>
#include <mavlink/mavlink_log.h>
+#include <geo/geo.h>
+#include <drivers/drv_hrt.h>
+
+#define GEOFENCE_OFF 0
+#define GEOFENCE_FILE_ONLY 1
+#define GEOFENCE_MAX_DISTANCES_ONLY 2
+#define GEOFENCE_FILE_AND_MAX_DISTANCES 3
+
+#define GEOFENCE_RANGE_WARNING_LIMIT 3000000
/* Oddly, ERROR is not defined for C++ */
@@ -60,13 +70,19 @@ static const int ERROR = -1;
Geofence::Geofence() :
SuperBlock(NULL, "GF"),
_fence_pub(-1),
+ _home_pos{},
+ _home_pos_set(false),
+ _last_horizontal_range_warning(0),
+ _last_vertical_range_warning(0),
_altitude_min(0),
_altitude_max(0),
_verticesCount(0),
- _param_geofence_on(this, "ON"),
+ _param_geofence_mode(this, "MODE"),
_param_altitude_mode(this, "ALTMODE"),
_param_source(this, "SOURCE"),
_param_counter_threshold(this, "COUNT"),
+ _param_max_hor_distance(this, "MAX_HOR_DIST"),
+ _param_max_ver_distance(this, "MAX_VER_DIST"),
_outside_counter(0),
_mavlinkFd(-1)
{
@@ -92,10 +108,14 @@ bool Geofence::inside(const struct vehicle_global_position_s &global_position, f
bool Geofence::inside(const struct vehicle_global_position_s &global_position,
- const struct vehicle_gps_position_s &gps_position, float baro_altitude_amsl)
+ const struct vehicle_gps_position_s &gps_position, float baro_altitude_amsl,
+ const struct home_position_s home_pos, bool home_position_set)
{
updateParams();
+ _home_pos = home_pos;
+ _home_pos_set = home_position_set;
+
if (getAltitudeMode() == Geofence::GF_ALT_MODE_WGS84) {
if (getSource() == Geofence::GF_SOURCE_GLOBALPOS) {
return inside(global_position);
@@ -118,13 +138,48 @@ bool Geofence::inside(const struct vehicle_global_position_s &global_position,
bool Geofence::inside(double lat, double lon, float altitude)
{
+ if (_param_geofence_mode.get() >= GEOFENCE_MAX_DISTANCES_ONLY) {
+ int32_t max_horizontal_distance = _param_max_hor_distance.get();
+ int32_t max_vertical_distance = _param_max_ver_distance.get();
+
+ if (max_horizontal_distance > 0 || max_vertical_distance > 0) {
+ if (_home_pos_set) {
+ float dist_xy = -1.0f;
+ float dist_z = -1.0f;
+ get_distance_to_point_global_wgs84(lat, lon, altitude,
+ _home_pos.lat, _home_pos.lon, _home_pos.alt,
+ &dist_xy, &dist_z);
+
+ if (max_vertical_distance > 0 && (dist_z > max_vertical_distance)) {
+ if (hrt_elapsed_time(&_last_vertical_range_warning) > GEOFENCE_RANGE_WARNING_LIMIT) {
+ mavlink_log_critical(_mavlinkFd, "Geofence exceeded max vertical distance by %.1f m",
+ (double)(dist_z - max_vertical_distance));
+ _last_vertical_range_warning = hrt_absolute_time();
+ }
+
+ return false;
+ }
+
+ if (max_horizontal_distance > 0 && (dist_xy > max_horizontal_distance)) {
+ if (hrt_elapsed_time(&_last_horizontal_range_warning) > GEOFENCE_RANGE_WARNING_LIMIT) {
+ mavlink_log_critical(_mavlinkFd, "Geofence exceeded max horizontal distance by %.1f m",
+ (double)(dist_xy - max_horizontal_distance));
+ _last_horizontal_range_warning = hrt_absolute_time();
+ }
+
+ return false;
+ }
+ }
+ }
+ }
+
bool inside_fence = inside_polygon(lat, lon, altitude);
if (inside_fence) {
_outside_counter = 0;
return inside_fence;
- } {
+ } else {
_outside_counter++;
if (_outside_counter > _param_counter_threshold.get()) {
@@ -139,8 +194,9 @@ bool Geofence::inside(double lat, double lon, float altitude)
bool Geofence::inside_polygon(double lat, double lon, float altitude)
{
- /* Return true if geofence is disabled */
- if (_param_geofence_on.get() != 1) {
+ /* Return true if geofence is disabled or only checking max distances */
+ if ((_param_geofence_mode.get() == GEOFENCE_OFF)
+ || (_param_geofence_mode.get() == GEOFENCE_MAX_DISTANCES_ONLY)) {
return true;
}
@@ -366,7 +422,7 @@ Geofence::loadFromFile(const char *filename)
} else {
warnx("Geofence: import error");
- mavlink_log_critical(_mavlinkFd, "#audio: Geofence import error");
+ mavlink_log_critical(_mavlinkFd, "Geofence import error");
}
error:
diff --git a/src/modules/navigator/geofence.h b/src/modules/navigator/geofence.h
index 37a41b68a..96764cc97 100644
--- a/src/modules/navigator/geofence.h
+++ b/src/modules/navigator/geofence.h
@@ -45,8 +45,10 @@
#include <uORB/topics/vehicle_global_position.h>
#include <uORB/topics/vehicle_gps_position.h>
#include <uORB/topics/sensor_combined.h>
+#include <uORB/topics/home_position.h>
#include <controllib/blocks.hpp>
#include <controllib/block/BlockParam.hpp>
+#include <drivers/drv_hrt.h>
#define GEOFENCE_FILENAME "/fs/microsd/etc/geofence.txt"
@@ -76,7 +78,9 @@ public:
* @return true: system is inside fence, false: system is outside fence
*/
bool inside(const struct vehicle_global_position_s &global_position,
- const struct vehicle_gps_position_s &gps_position, float baro_altitude_amsl);
+ const struct vehicle_gps_position_s &gps_position, float baro_altitude_amsl,
+ const struct home_position_s home_pos, bool home_position_set);
+
bool inside_polygon(double lat, double lon, float altitude);
int clearDm();
@@ -103,16 +107,24 @@ public:
private:
orb_advert_t _fence_pub; /**< publish fence topic */
+ home_position_s _home_pos;
+ bool _home_pos_set;
+
+ hrt_abstime _last_horizontal_range_warning;
+ hrt_abstime _last_vertical_range_warning;
+
float _altitude_min;
float _altitude_max;
unsigned _verticesCount;
/* Params */
- control::BlockParamInt _param_geofence_on;
+ control::BlockParamInt _param_geofence_mode;
control::BlockParamInt _param_altitude_mode;
control::BlockParamInt _param_source;
control::BlockParamInt _param_counter_threshold;
+ control::BlockParamInt _param_max_hor_distance;
+ control::BlockParamInt _param_max_ver_distance;
uint8_t _outside_counter;
diff --git a/src/modules/navigator/geofence_params.c b/src/modules/navigator/geofence_params.c
index fca3918e1..f3e7d4c84 100644
--- a/src/modules/navigator/geofence_params.c
+++ b/src/modules/navigator/geofence_params.c
@@ -48,16 +48,15 @@
*/
/**
- * Enable geofence.
+ * Geofence mode.
*
- * Set to 1 to enable geofence.
- * Defaults to 1 because geofence is only enabled when the geofence.txt file is present.
+ * 0 = disabled, 1 = geofence file only, 2 = max horizontal (GF_MAX_HOR_DIST) and vertical (GF_MAX_VER_DIST) distances, 3 = both
*
* @min 0
- * @max 1
+ * @max 3
* @group Geofence
*/
-PARAM_DEFINE_INT32(GF_ON, 1);
+PARAM_DEFINE_INT32(GF_MODE, 0);
/**
* Geofence altitude mode
@@ -94,3 +93,21 @@ PARAM_DEFINE_INT32(GF_SOURCE, 0);
* @group Geofence
*/
PARAM_DEFINE_INT32(GF_COUNT, -1);
+
+/**
+ * Max horizontal distance in meters.
+ *
+ * Set to > 0 to activate RTL if horizontal distance to home exceeds this value.
+ *
+ * @group Geofence
+ */
+PARAM_DEFINE_INT32(GF_MAX_HOR_DIST, -1);
+
+/**
+ * Max vertical distance in meters.
+ *
+ * Set to > 0 to activate RTL if vertical distance to home exceeds this value.
+ *
+ * @group Geofence
+ */
+PARAM_DEFINE_INT32(GF_MAX_VER_DIST, -1);
diff --git a/src/modules/navigator/gpsfailure.cpp b/src/modules/navigator/gpsfailure.cpp
index e370796c0..0ca69f0f7 100644
--- a/src/modules/navigator/gpsfailure.cpp
+++ b/src/modules/navigator/gpsfailure.cpp
@@ -161,12 +161,12 @@ GpsFailure::advance_gpsf()
case GPSF_STATE_NONE:
_gpsf_state = GPSF_STATE_LOITER;
warnx("gpsf loiter");
- mavlink_log_info(_navigator->get_mavlink_fd(), "#audio: open loop loiter");
+ mavlink_log_critical(_navigator->get_mavlink_fd(), "GPS failed: open loop loiter");
break;
case GPSF_STATE_LOITER:
_gpsf_state = GPSF_STATE_TERMINATE;
warnx("gpsf terminate");
- mavlink_log_info(_navigator->get_mavlink_fd(), "#audio: no gps recovery, termination");
+ mavlink_log_emergency(_navigator->get_mavlink_fd(), "no gps recovery, termination");
warnx("mavlink sent");
break;
case GPSF_STATE_TERMINATE:
diff --git a/src/modules/navigator/gpsfailure_params.c b/src/modules/navigator/gpsfailure_params.c
index 39d179eed..98104af29 100644
--- a/src/modules/navigator/gpsfailure_params.c
+++ b/src/modules/navigator/gpsfailure_params.c
@@ -55,7 +55,7 @@
*
* @unit seconds
* @min 0.0
- * @group GPSF
+ * @group GPS Failure Navigation
*/
PARAM_DEFINE_FLOAT(NAV_GPSF_LT, 30.0f);
@@ -67,7 +67,7 @@ PARAM_DEFINE_FLOAT(NAV_GPSF_LT, 30.0f);
* @unit deg
* @min 0.0
* @max 30.0
- * @group GPSF
+ * @group GPS Failure Navigation
*/
PARAM_DEFINE_FLOAT(NAV_GPSF_R, 15.0f);
@@ -79,7 +79,7 @@ PARAM_DEFINE_FLOAT(NAV_GPSF_R, 15.0f);
* @unit deg
* @min -30.0
* @max 30.0
- * @group GPSF
+ * @group GPS Failure Navigation
*/
PARAM_DEFINE_FLOAT(NAV_GPSF_P, 0.0f);
@@ -90,7 +90,7 @@ PARAM_DEFINE_FLOAT(NAV_GPSF_P, 0.0f);
*
* @min 0.0
* @max 1.0
- * @group GPSF
+ * @group GPS Failure Navigation
*/
PARAM_DEFINE_FLOAT(NAV_GPSF_TR, 0.7f);
diff --git a/src/modules/navigator/mission.cpp b/src/modules/navigator/mission.cpp
index a94082d6f..c1763ba93 100644
--- a/src/modules/navigator/mission.cpp
+++ b/src/modules/navigator/mission.cpp
@@ -449,7 +449,7 @@ Mission::set_mission_items()
}
/* check if we already above takeoff altitude */
- if (_navigator->get_global_position()->alt < takeoff_alt - _navigator->get_acceptance_radius()) {
+ if (_navigator->get_global_position()->alt < takeoff_alt) {
mavlink_log_critical(_navigator->get_mavlink_fd(), "takeoff to %.1f meters above home", (double)(takeoff_alt - _navigator->get_home_position()->alt));
_mission_item.nav_cmd = NAV_CMD_TAKEOFF;
diff --git a/src/modules/navigator/mission_block.cpp b/src/modules/navigator/mission_block.cpp
index 52ccebac9..dce7d4517 100644
--- a/src/modules/navigator/mission_block.cpp
+++ b/src/modules/navigator/mission_block.cpp
@@ -159,7 +159,7 @@ MissionBlock::is_mission_item_reached()
_time_first_inside_orbit = now;
// if (_mission_item.time_inside > 0.01f) {
- // mavlink_log_info(_mavlink_fd, "#audio: waypoint reached, wait for %.1fs",
+ // mavlink_log_critical(_mavlink_fd, "waypoint reached, wait for %.1fs",
// (double)_mission_item.time_inside);
// }
}
diff --git a/src/modules/navigator/mission_feasibility_checker.cpp b/src/modules/navigator/mission_feasibility_checker.cpp
index 389cdd0d2..949231b15 100644
--- a/src/modules/navigator/mission_feasibility_checker.cpp
+++ b/src/modules/navigator/mission_feasibility_checker.cpp
@@ -121,7 +121,7 @@ bool MissionFeasibilityChecker::checkGeofence(dm_item_t dm_current, size_t nMiss
}
if (!geofence.inside_polygon(missionitem.lat, missionitem.lon, missionitem.altitude)) {
- mavlink_log_info(_mavlink_fd, "#audio: Geofence violation waypoint %d", i);
+ mavlink_log_critical(_mavlink_fd, "Geofence violation waypoint %d", i);
return false;
}
}
@@ -134,7 +134,7 @@ bool MissionFeasibilityChecker::checkHomePositionAltitude(dm_item_t dm_current,
{
/* 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;
+ struct mission_item_s missionitem;
const ssize_t len = sizeof(struct mission_item_s);
if (dm_read(dm_current, i, &missionitem, len) != len) {
@@ -203,25 +203,25 @@ bool MissionFeasibilityChecker::checkFixedWingLanding(dm_item_t dm_current, size
return true;
} else {
/* Landing waypoint is above altitude of slope at the given waypoint distance */
- mavlink_log_info(_mavlink_fd, "#audio: Landing: last waypoint too high/too close");
- mavlink_log_info(_mavlink_fd, "Move down to %.1fm or move further away by %.1fm",
+ mavlink_log_critical(_mavlink_fd, "Landing: last waypoint too high/too close");
+ mavlink_log_critical(_mavlink_fd, "Move down to %.1fm or move further away by %.1fm",
(double)(slope_alt_req),
(double)(wp_distance_req - wp_distance));
return false;
}
} else {
/* Landing waypoint is above last waypoint */
- mavlink_log_info(_mavlink_fd, "#audio: Landing waypoint above last nav waypoint");
+ mavlink_log_critical(_mavlink_fd, "Landing waypoint above last nav waypoint");
return false;
}
} else {
/* Last wp is in flare region */
//xxx give recommendations
- mavlink_log_info(_mavlink_fd, "#audio: Warning: Landing: last waypoint in flare region");
+ mavlink_log_critical(_mavlink_fd, "Warning: Landing: last waypoint in flare region");
return false;
}
} else {
- mavlink_log_info(_mavlink_fd, "#audio: Warning: starting with land waypoint");
+ mavlink_log_critical(_mavlink_fd, "Warning: starting with land waypoint");
return false;
}
}
diff --git a/src/modules/navigator/navigator.h b/src/modules/navigator/navigator.h
index d9d911d9c..d2acce789 100644
--- a/src/modules/navigator/navigator.h
+++ b/src/modules/navigator/navigator.h
@@ -186,6 +186,8 @@ private:
geofence_result_s _geofence_result;
vehicle_attitude_setpoint_s _att_sp;
+ bool _home_position_set;
+
bool _mission_item_valid; /**< flags if the current mission item is valid */
perf_counter_t _loop_perf; /**< loop performance counter */
diff --git a/src/modules/navigator/navigator_main.cpp b/src/modules/navigator/navigator_main.cpp
index ad2349c94..042f926d3 100644
--- a/src/modules/navigator/navigator_main.cpp
+++ b/src/modules/navigator/navigator_main.cpp
@@ -123,6 +123,7 @@ Navigator::Navigator() :
_pos_sp_triplet{},
_mission_result{},
_att_sp{},
+ _home_position_set(false),
_mission_item_valid(false),
_loop_perf(perf_alloc(PC_ELAPSED, "navigator")),
_geofence{},
@@ -203,7 +204,13 @@ Navigator::sensor_combined_update()
void
Navigator::home_position_update()
{
- orb_copy(ORB_ID(home_position), _home_pos_sub, &_home_pos);
+ bool updated = false;
+ orb_check(_home_pos_sub, &updated);
+
+ if (updated) {
+ orb_copy(ORB_ID(home_position), _home_pos_sub, &_home_pos);
+ _home_position_set = true;
+ }
}
void
@@ -392,7 +399,7 @@ Navigator::task_main()
/* Check geofence violation */
static hrt_abstime last_geofence_check = 0;
if (have_geofence_position_data && hrt_elapsed_time(&last_geofence_check) > GEOFENCE_CHECK_INTERVAL) {
- bool inside = _geofence.inside(_global_pos, _gps_pos, _sensor_combined.baro_alt_meter);
+ bool inside = _geofence.inside(_global_pos, _gps_pos, _sensor_combined.baro_alt_meter, _home_pos, _home_position_set);
last_geofence_check = hrt_absolute_time();
have_geofence_position_data = false;
if (!inside) {
@@ -402,7 +409,7 @@ Navigator::task_main()
/* Issue a warning about the geofence violation once */
if (!_geofence_violation_warning_sent) {
- mavlink_log_critical(_mavlink_fd, "#audio: Geofence violation");
+ mavlink_log_critical(_mavlink_fd, "Geofence violation");
_geofence_violation_warning_sent = true;
}
} else {
@@ -511,7 +518,7 @@ Navigator::start()
_navigator_task = task_spawn_cmd("navigator",
SCHED_DEFAULT,
SCHED_PRIORITY_DEFAULT + 20,
- 1800,
+ 1700,
(main_t)&Navigator::task_main_trampoline,
nullptr);
diff --git a/src/modules/navigator/navigator_params.c b/src/modules/navigator/navigator_params.c
index 5f8f8d02f..ef4a8dc0c 100644
--- a/src/modules/navigator/navigator_params.c
+++ b/src/modules/navigator/navigator_params.c
@@ -94,8 +94,8 @@ PARAM_DEFINE_INT32(NAV_RCL_OBC, 0);
* Latitude of airfield home waypoint
*
* @unit degrees * 1e7
- * @min 0.0
- * @group DLL
+ * @min 0
+ * @group Data Link Loss
*/
PARAM_DEFINE_INT32(NAV_AH_LAT, -265847810);
@@ -105,8 +105,8 @@ PARAM_DEFINE_INT32(NAV_AH_LAT, -265847810);
* Longitude of airfield home waypoint
*
* @unit degrees * 1e7
- * @min 0.0
- * @group DLL
+ * @min 0
+ * @group Data Link Loss
*/
PARAM_DEFINE_INT32(NAV_AH_LON, 1518423250);
@@ -117,6 +117,6 @@ PARAM_DEFINE_INT32(NAV_AH_LON, 1518423250);
*
* @unit m
* @min 0.0
- * @group DLL
+ * @group Data Link Loss
*/
PARAM_DEFINE_FLOAT(NAV_AH_ALT, 600.0f);
diff --git a/src/modules/navigator/rcloss.cpp b/src/modules/navigator/rcloss.cpp
index a7cde6325..40bf7f022 100644
--- a/src/modules/navigator/rcloss.cpp
+++ b/src/modules/navigator/rcloss.cpp
@@ -155,11 +155,11 @@ RCLoss::advance_rcl()
case RCL_STATE_NONE:
if (_param_loitertime.get() > 0.0f) {
warnx("RC loss, OBC mode, loiter");
- mavlink_log_info(_navigator->get_mavlink_fd(), "#audio: rc loss, loitering");
+ mavlink_log_critical(_navigator->get_mavlink_fd(), "rc loss, loitering");
_rcl_state = RCL_STATE_LOITER;
} else {
warnx("RC loss, OBC mode, slip loiter, terminate");
- mavlink_log_info(_navigator->get_mavlink_fd(), "#audio: rc loss, terminating");
+ mavlink_log_critical(_navigator->get_mavlink_fd(), "rc loss, terminating");
_rcl_state = RCL_STATE_TERMINATE;
_navigator->get_mission_result()->stay_in_failsafe = true;
_navigator->set_mission_result_updated();
@@ -169,7 +169,7 @@ RCLoss::advance_rcl()
case RCL_STATE_LOITER:
_rcl_state = RCL_STATE_TERMINATE;
warnx("time is up, no RC regain, terminating");
- mavlink_log_info(_navigator->get_mavlink_fd(), "#audio: RC not regained, terminating");
+ mavlink_log_critical(_navigator->get_mavlink_fd(), "RC not regained, terminating");
_navigator->get_mission_result()->stay_in_failsafe = true;
_navigator->set_mission_result_updated();
reset_mission_item_reached();
diff --git a/src/modules/navigator/rcloss_params.c b/src/modules/navigator/rcloss_params.c
index f1a01c73b..f48aabc80 100644
--- a/src/modules/navigator/rcloss_params.c
+++ b/src/modules/navigator/rcloss_params.c
@@ -55,6 +55,6 @@
*
* @unit seconds
* @min -1.0
- * @group RCL
+ * @group Radio Signal Loss
*/
PARAM_DEFINE_FLOAT(NAV_RCL_LT, 120.0f);
diff --git a/src/modules/navigator/rtl.cpp b/src/modules/navigator/rtl.cpp
index b6c4b8fdf..c1ed8cb7c 100644
--- a/src/modules/navigator/rtl.cpp
+++ b/src/modules/navigator/rtl.cpp
@@ -89,7 +89,7 @@ RTL::on_activation()
/* for safety reasons don't go into RTL if landed */
if (_navigator->get_vstatus()->condition_landed) {
_rtl_state = RTL_STATE_LANDED;
- mavlink_log_info(_navigator->get_mavlink_fd(), "#audio: no RTL when landed");
+ mavlink_log_critical(_navigator->get_mavlink_fd(), "no RTL when landed");
/* if lower than return altitude, climb up first */
} else if (_navigator->get_global_position()->alt < _navigator->get_home_position()->alt
@@ -146,7 +146,7 @@ RTL::set_rtl_item()
_mission_item.autocontinue = true;
_mission_item.origin = ORIGIN_ONBOARD;
- mavlink_log_info(_navigator->get_mavlink_fd(), "#audio: RTL: climb to %d meters above home",
+ mavlink_log_critical(_navigator->get_mavlink_fd(), "RTL: climb to %d meters above home",
(int)(climb_alt - _navigator->get_home_position()->alt));
break;
}
@@ -177,7 +177,7 @@ RTL::set_rtl_item()
_mission_item.autocontinue = true;
_mission_item.origin = ORIGIN_ONBOARD;
- mavlink_log_info(_navigator->get_mavlink_fd(), "#audio: RTL: return at %d meters above home",
+ mavlink_log_critical(_navigator->get_mavlink_fd(), "RTL: return at %d meters above home",
(int)(_mission_item.altitude - _navigator->get_home_position()->alt));
break;
}
@@ -197,7 +197,7 @@ RTL::set_rtl_item()
_mission_item.autocontinue = false;
_mission_item.origin = ORIGIN_ONBOARD;
- mavlink_log_info(_navigator->get_mavlink_fd(), "#audio: RTL: descend to %d meters above home",
+ mavlink_log_critical(_navigator->get_mavlink_fd(), "RTL: descend to %d meters above home",
(int)(_mission_item.altitude - _navigator->get_home_position()->alt));
break;
}
@@ -222,10 +222,10 @@ RTL::set_rtl_item()
_navigator->set_can_loiter_at_sp(true);
if (autoland) {
- mavlink_log_info(_navigator->get_mavlink_fd(), "#audio: RTL: loiter %.1fs", (double)_mission_item.time_inside);
+ mavlink_log_critical(_navigator->get_mavlink_fd(), "RTL: loiter %.1fs", (double)_mission_item.time_inside);
} else {
- mavlink_log_info(_navigator->get_mavlink_fd(), "#audio: RTL: completed, loiter");
+ mavlink_log_critical(_navigator->get_mavlink_fd(), "RTL: completed, loiter");
}
break;
}
@@ -245,7 +245,7 @@ RTL::set_rtl_item()
_mission_item.autocontinue = true;
_mission_item.origin = ORIGIN_ONBOARD;
- mavlink_log_info(_navigator->get_mavlink_fd(), "#audio: RTL: land at home");
+ mavlink_log_critical(_navigator->get_mavlink_fd(), "RTL: land at home");
break;
}
@@ -264,7 +264,7 @@ RTL::set_rtl_item()
_mission_item.autocontinue = true;
_mission_item.origin = ORIGIN_ONBOARD;
- mavlink_log_info(_navigator->get_mavlink_fd(), "#audio: RTL: completed, landed");
+ mavlink_log_critical(_navigator->get_mavlink_fd(), "RTL: completed, landed");
break;
}
diff --git a/src/modules/navigator/rtl_params.c b/src/modules/navigator/rtl_params.c
index 10394fed1..3d8c78cf1 100644
--- a/src/modules/navigator/rtl_params.c
+++ b/src/modules/navigator/rtl_params.c
@@ -48,18 +48,6 @@
*/
/**
- * Loiter radius after RTL (FW only)
- *
- * Default value of loiter radius after RTL (fixedwing only).
- *
- * @unit meters
- * @min 20
- * @max 200
- * @group RTL
- */
-PARAM_DEFINE_FLOAT(RTL_LOITER_RAD, 50.0f);
-
-/**
* RTL altitude
*
* Altitude to fly back in RTL in meters
@@ -67,7 +55,7 @@ PARAM_DEFINE_FLOAT(RTL_LOITER_RAD, 50.0f);
* @unit meters
* @min 0
* @max 150
- * @group RTL
+ * @group Return To Land
*/
PARAM_DEFINE_FLOAT(RTL_RETURN_ALT, 60);
@@ -81,7 +69,7 @@ PARAM_DEFINE_FLOAT(RTL_RETURN_ALT, 60);
* @unit meters
* @min 2
* @max 100
- * @group RTL
+ * @group Return To Land
*/
PARAM_DEFINE_FLOAT(RTL_DESCEND_ALT, 30);
@@ -94,6 +82,6 @@ PARAM_DEFINE_FLOAT(RTL_DESCEND_ALT, 30);
* @unit seconds
* @min -1
* @max 300
- * @group RTL
+ * @group Return To Land
*/
PARAM_DEFINE_FLOAT(RTL_LAND_DELAY, -1.0f);
diff --git a/src/modules/position_estimator_inav/position_estimator_inav_main.c b/src/modules/position_estimator_inav/position_estimator_inav_main.c
index ec297e7f0..437395b1f 100644
--- a/src/modules/position_estimator_inav/position_estimator_inav_main.c
+++ b/src/modules/position_estimator_inav/position_estimator_inav_main.c
@@ -134,7 +134,7 @@ static void usage(const char *reason)
*/
int position_estimator_inav_main(int argc, char *argv[])
{
- if (argc < 1) {
+ if (argc < 2) {
usage("missing command");
}
diff --git a/src/modules/position_estimator_inav/position_estimator_inav_params.c b/src/modules/position_estimator_inav/position_estimator_inav_params.c
index ed98e222e..aedb478fa 100644
--- a/src/modules/position_estimator_inav/position_estimator_inav_params.c
+++ b/src/modules/position_estimator_inav/position_estimator_inav_params.c
@@ -282,8 +282,8 @@ PARAM_DEFINE_FLOAT(INAV_DELAY_GPS, 0.2f);
*
* Set to the appropriate key (328754) to disable vision input.
*
- * @min 0.0
- * @max 1.0
+ * @min 0
+ * @max 1
* @group Position Estimator INAV
*/
PARAM_DEFINE_INT32(CBRK_NO_VISION, 0);
@@ -295,9 +295,8 @@ PARAM_DEFINE_INT32(CBRK_NO_VISION, 0);
* the system uses the combined attitude / position
* filter framework.
*
- * @min 0.0
- * @max 1.0
- * @unit s
+ * @min 0
+ * @max 1
* @group Position Estimator INAV
*/
PARAM_DEFINE_INT32(INAV_ENABLED, 1);
diff --git a/src/modules/px4iofirmware/controls.c b/src/modules/px4iofirmware/controls.c
index e04ffc940..ac004f212 100644
--- a/src/modules/px4iofirmware/controls.c
+++ b/src/modules/px4iofirmware/controls.c
@@ -99,6 +99,9 @@ bool dsm_port_input(uint16_t *rssi, bool *dsm_updated, bool *st24_updated, bool
if (*st24_updated) {
+ /* ensure ADC RSSI is disabled */
+ r_setup_features &= ~(PX4IO_P_SETUP_FEATURES_ADC_RSSI);
+
*rssi = st24_rssi;
r_raw_rc_count = st24_channel_count;
@@ -116,14 +119,14 @@ bool dsm_port_input(uint16_t *rssi, bool *dsm_updated, bool *st24_updated, bool
for (unsigned i = 0; i < n_bytes; i++) {
/* set updated flag if one complete packet was parsed */
- st24_rssi = RC_INPUT_RSSI_MAX;
+ sumd_rssi = RC_INPUT_RSSI_MAX;
*sumd_updated |= (OK == sumd_decode(bytes[i], &sumd_rssi, &sumd_rx_count,
&sumd_channel_count, r_raw_rc_values, PX4IO_RC_INPUT_CHANNELS));
}
if (*sumd_updated) {
- *rssi = sumd_rssi;
+ /* not setting RSSI since SUMD does not provide one */
r_raw_rc_count = sumd_channel_count;
r_status_flags |= PX4IO_P_STATUS_FLAGS_RC_SUMD;
@@ -187,12 +190,20 @@ controls_tick() {
/* use 1:1 scaling on 3.3V ADC input */
unsigned mV = counts * 3300 / 4096;
- /* scale to 0..253 */
- rssi = mV / 13;
+ /* scale to 0..253 and lowpass */
+ rssi = (rssi * 0.99f) + ((mV / (3300 / RC_INPUT_RSSI_MAX)) * 0.01f);
+ if (rssi > RC_INPUT_RSSI_MAX) {
+ rssi = RC_INPUT_RSSI_MAX;
+ }
}
}
#endif
+ /* zero RSSI if signal is lost */
+ if (!(r_raw_rc_flags & (PX4IO_P_RAW_RC_FLAGS_RC_OK))) {
+ rssi = 0;
+ }
+
perf_begin(c_gather_dsm);
bool dsm_updated, st24_updated, sumd_updated;
(void)dsm_port_input(&rssi, &dsm_updated, &st24_updated, &sumd_updated);
@@ -215,22 +226,26 @@ controls_tick() {
if (sbus_updated) {
r_status_flags |= PX4IO_P_STATUS_FLAGS_RC_SBUS;
- rssi = 255;
+ unsigned sbus_rssi = RC_INPUT_RSSI_MAX;
if (sbus_frame_drop) {
r_raw_rc_flags |= PX4IO_P_RAW_RC_FLAGS_FRAME_DROP;
- rssi = 100;
+ sbus_rssi = RC_INPUT_RSSI_MAX / 2;
} else {
r_raw_rc_flags &= ~(PX4IO_P_RAW_RC_FLAGS_FRAME_DROP);
}
if (sbus_failsafe) {
r_raw_rc_flags |= PX4IO_P_RAW_RC_FLAGS_FAILSAFE;
- rssi = 0;
} else {
r_raw_rc_flags &= ~(PX4IO_P_RAW_RC_FLAGS_FAILSAFE);
}
+ /* set RSSI to an emulated value if ADC RSSI is off */
+ if (!(r_setup_features & PX4IO_P_SETUP_FEATURES_ADC_RSSI)) {
+ rssi = sbus_rssi;
+ }
+
}
perf_end(c_gather_sbus);
diff --git a/src/modules/px4iofirmware/registers.c b/src/modules/px4iofirmware/registers.c
index 90e0fb10e..e7976446c 100644
--- a/src/modules/px4iofirmware/registers.c
+++ b/src/modules/px4iofirmware/registers.c
@@ -544,8 +544,8 @@ registers_set_one(uint8_t page, uint8_t offset, uint16_t value)
break;
case PX4IO_P_SETUP_PWM_DEFAULTRATE:
- if (value < 50) {
- value = 50;
+ if (value < 25) {
+ value = 25;
}
if (value > 400) {
value = 400;
@@ -554,8 +554,8 @@ registers_set_one(uint8_t page, uint8_t offset, uint16_t value)
break;
case PX4IO_P_SETUP_PWM_ALTRATE:
- if (value < 50) {
- value = 50;
+ if (value < 25) {
+ value = 25;
}
if (value > 400) {
value = 400;
diff --git a/src/modules/sdlog2/module.mk b/src/modules/sdlog2/module.mk
index 8fded0bdb..6964acf33 100644
--- a/src/modules/sdlog2/module.mk
+++ b/src/modules/sdlog2/module.mk
@@ -48,3 +48,4 @@ MAXOPTIMIZATION = -Os
EXTRACFLAGS = -Wframe-larger-than=1400
+EXTRADEFINES = -DGIT_VERSION='"$(GIT_DESC)"'
diff --git a/src/modules/sdlog2/sdlog2.c b/src/modules/sdlog2/sdlog2.c
index 0bfd356a1..ae4913559 100644
--- a/src/modules/sdlog2/sdlog2.c
+++ b/src/modules/sdlog2/sdlog2.c
@@ -51,7 +51,6 @@
#include <errno.h>
#include <unistd.h>
#include <stdio.h>
-#include <poll.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
@@ -99,6 +98,8 @@
#include <uORB/topics/wind_estimate.h>
#include <uORB/topics/encoders.h>
#include <uORB/topics/vtol_vehicle_status.h>
+#include <uORB/topics/time_offset.h>
+#include <uORB/topics/mc_att_ctrl_status.h>
#include <systemlib/systemlib.h>
#include <systemlib/param/param.h>
@@ -149,11 +150,6 @@ PARAM_DEFINE_INT32(SDLOG_EXT, -1);
log_msgs_skipped++; \
}
-#define LOG_ORB_SUBSCRIBE(_var, _topic) subs.##_var##_sub = orb_subscribe(ORB_ID(##_topic##)); \
- fds[fdsc_count].fd = subs.##_var##_sub; \
- fds[fdsc_count].events = POLLIN; \
- fdsc_count++;
-
#define MIN(X,Y) ((X) < (Y) ? (X) : (Y))
static bool main_thread_should_exit = false; /**< Deamon exit flag */
@@ -216,7 +212,7 @@ static void *logwriter_thread(void *arg);
*/
__EXPORT int sdlog2_main(int argc, char *argv[]);
-static bool copy_if_updated(orb_id_t topic, int handle, void *buffer);
+static bool copy_if_updated(orb_id_t topic, int *handle, void *buffer);
/**
* Mainloop of sd log deamon.
@@ -763,7 +759,7 @@ int write_version(int fd)
};
/* fill version message and write it */
- strncpy(log_msg_VER.body.fw_git, FW_GIT, sizeof(log_msg_VER.body.fw_git));
+ strncpy(log_msg_VER.body.fw_git, GIT_VERSION, sizeof(log_msg_VER.body.fw_git));
strncpy(log_msg_VER.body.arch, HW_ARCH, sizeof(log_msg_VER.body.arch));
return write(fd, &log_msg_VER, sizeof(log_msg_VER));
}
@@ -809,14 +805,25 @@ int write_parameters(int fd)
return written;
}
-bool copy_if_updated(orb_id_t topic, int handle, void *buffer)
+bool copy_if_updated(orb_id_t topic, int *handle, void *buffer)
{
- bool updated;
-
- orb_check(handle, &updated);
+ bool updated = false;
+
+ if (*handle < 0) {
+ if (OK == orb_exists(topic, 0)) {
+ *handle = orb_subscribe(topic);
+ /* copy first data */
+ if (*handle >= 0) {
+ orb_copy(topic, *handle, buffer);
+ updated = true;
+ }
+ }
+ } else {
+ orb_check(*handle, &updated);
- if (updated) {
- orb_copy(topic, handle, buffer);
+ if (updated) {
+ orb_copy(topic, *handle, buffer);
+ }
}
return updated;
@@ -1027,6 +1034,8 @@ int sdlog2_thread_main(int argc, char *argv[])
struct wind_estimate_s wind_estimate;
struct encoders_s encoders;
struct vtol_vehicle_status_s vtol_status;
+ struct time_offset_s time_offset;
+ struct mc_att_ctrl_status_s mc_att_ctrl_status;
} buf;
memset(&buf, 0, sizeof(buf));
@@ -1071,6 +1080,8 @@ int sdlog2_thread_main(int argc, char *argv[])
struct log_TECS_s log_TECS;
struct log_WIND_s log_WIND;
struct log_ENCD_s log_ENCD;
+ struct log_TSYN_s log_TSYN;
+ struct log_MACS_s log_MACS;
} body;
} log_msg = {
LOG_PACKET_HEADER_INIT(0)
@@ -1111,54 +1122,51 @@ int sdlog2_thread_main(int argc, char *argv[])
int servorail_status_sub;
int wind_sub;
int encoders_sub;
+ int tsync_sub;
+ int mc_att_ctrl_status_sub;
} subs;
- subs.cmd_sub = orb_subscribe(ORB_ID(vehicle_command));
- subs.status_sub = orb_subscribe(ORB_ID(vehicle_status));
- subs.vtol_status_sub = orb_subscribe(ORB_ID(vtol_vehicle_status));
- subs.gps_pos_sub = orb_subscribe(ORB_ID(vehicle_gps_position));
- subs.sensor_sub = orb_subscribe(ORB_ID(sensor_combined));
- subs.att_sub = orb_subscribe(ORB_ID(vehicle_attitude));
- subs.att_sp_sub = orb_subscribe(ORB_ID(vehicle_attitude_setpoint));
- subs.rates_sp_sub = orb_subscribe(ORB_ID(vehicle_rates_setpoint));
- subs.act_outputs_sub = orb_subscribe(ORB_ID(actuator_outputs));
- subs.act_controls_sub = orb_subscribe(ORB_ID_VEHICLE_ATTITUDE_CONTROLS);
- subs.act_controls_1_sub = orb_subscribe(ORB_ID(actuator_controls_1));
- subs.local_pos_sub = orb_subscribe(ORB_ID(vehicle_local_position));
- subs.local_pos_sp_sub = orb_subscribe(ORB_ID(vehicle_local_position_setpoint));
- subs.global_pos_sub = orb_subscribe(ORB_ID(vehicle_global_position));
- subs.triplet_sub = orb_subscribe(ORB_ID(position_setpoint_triplet));
- subs.vicon_pos_sub = orb_subscribe(ORB_ID(vehicle_vicon_position));
- subs.vision_pos_sub = orb_subscribe(ORB_ID(vision_position_estimate));
- subs.flow_sub = orb_subscribe(ORB_ID(optical_flow));
- subs.rc_sub = orb_subscribe(ORB_ID(rc_channels));
- subs.airspeed_sub = orb_subscribe(ORB_ID(airspeed));
- subs.esc_sub = orb_subscribe(ORB_ID(esc_status));
- subs.global_vel_sp_sub = orb_subscribe(ORB_ID(vehicle_global_velocity_setpoint));
- subs.battery_sub = orb_subscribe(ORB_ID(battery_status));
- subs.range_finder_sub = orb_subscribe(ORB_ID(sensor_range_finder));
- subs.estimator_status_sub = orb_subscribe(ORB_ID(estimator_status));
- subs.tecs_status_sub = orb_subscribe(ORB_ID(tecs_status));
- subs.system_power_sub = orb_subscribe(ORB_ID(system_power));
- subs.servorail_status_sub = orb_subscribe(ORB_ID(servorail_status));
- subs.wind_sub = orb_subscribe(ORB_ID(wind_estimate));
-
- /* we need to rate-limit wind, as we do not need the full update rate */
- orb_set_interval(subs.wind_sub, 90);
- subs.encoders_sub = orb_subscribe(ORB_ID(encoders));
+ subs.cmd_sub = -1;
+ subs.status_sub = -1;
+ subs.vtol_status_sub = -1;
+ subs.gps_pos_sub = -1;
+ subs.sensor_sub = -1;
+ subs.att_sub = -1;
+ subs.att_sp_sub = -1;
+ subs.rates_sp_sub = -1;
+ subs.act_outputs_sub = -1;
+ subs.act_controls_sub = -1;
+ subs.act_controls_1_sub = -1;
+ subs.local_pos_sub = -1;
+ subs.local_pos_sp_sub = -1;
+ subs.global_pos_sub = -1;
+ subs.triplet_sub = -1;
+ subs.vicon_pos_sub = -1;
+ subs.vision_pos_sub = -1;
+ subs.flow_sub = -1;
+ subs.rc_sub = -1;
+ subs.airspeed_sub = -1;
+ subs.esc_sub = -1;
+ subs.global_vel_sp_sub = -1;
+ subs.battery_sub = -1;
+ subs.range_finder_sub = -1;
+ subs.estimator_status_sub = -1;
+ subs.tecs_status_sub = -1;
+ subs.system_power_sub = -1;
+ subs.servorail_status_sub = -1;
+ subs.wind_sub = -1;
+ subs.tsync_sub = -1;
+ subs.mc_att_ctrl_status_sub = -1;
+ subs.encoders_sub = -1;
/* add new topics HERE */
- for (int i = 0; i < TELEMETRY_STATUS_ORB_ID_NUM; i++) {
- subs.telemetry_subs[i] = orb_subscribe(telemetry_status_orb_id[i]);
- }
-
- if (_extended_logging) {
- subs.sat_info_sub = orb_subscribe(ORB_ID(satellite_info));
- } else {
- subs.sat_info_sub = 0;
+ for (unsigned i = 0; i < TELEMETRY_STATUS_ORB_ID_NUM; i++) {
+ subs.telemetry_subs[i] = -1;
}
+
+ subs.sat_info_sub = -1;
/* close non-needed fd's */
@@ -1206,12 +1214,12 @@ int sdlog2_thread_main(int argc, char *argv[])
usleep(sleep_delay);
/* --- VEHICLE COMMAND - LOG MANAGEMENT --- */
- if (copy_if_updated(ORB_ID(vehicle_command), subs.cmd_sub, &buf.cmd)) {
+ if (copy_if_updated(ORB_ID(vehicle_command), &subs.cmd_sub, &buf.cmd)) {
handle_command(&buf.cmd);
}
/* --- VEHICLE STATUS - LOG MANAGEMENT --- */
- bool status_updated = copy_if_updated(ORB_ID(vehicle_status), subs.status_sub, &buf_status);
+ bool status_updated = copy_if_updated(ORB_ID(vehicle_status), &subs.status_sub, &buf_status);
if (status_updated) {
if (log_when_armed) {
@@ -1220,7 +1228,7 @@ int sdlog2_thread_main(int argc, char *argv[])
}
/* --- GPS POSITION - LOG MANAGEMENT --- */
- bool gps_pos_updated = copy_if_updated(ORB_ID(vehicle_gps_position), subs.gps_pos_sub, &buf_gps_pos);
+ bool gps_pos_updated = copy_if_updated(ORB_ID(vehicle_gps_position), &subs.gps_pos_sub, &buf_gps_pos);
if (gps_pos_updated && log_name_timestamp) {
gps_time = buf_gps_pos.time_utc_usec;
@@ -1251,7 +1259,7 @@ int sdlog2_thread_main(int argc, char *argv[])
}
/* --- VTOL VEHICLE STATUS --- */
- if(copy_if_updated(ORB_ID(vtol_vehicle_status), subs.vtol_status_sub, &buf.vtol_status)) {
+ if(copy_if_updated(ORB_ID(vtol_vehicle_status), &subs.vtol_status_sub, &buf.vtol_status)) {
log_msg.msg_type = LOG_VTOL_MSG;
log_msg.body.log_VTOL.airspeed_tot = buf.vtol_status.airspeed_tot;
LOGBUFFER_WRITE_AND_COUNT(VTOL);
@@ -1282,7 +1290,7 @@ int sdlog2_thread_main(int argc, char *argv[])
/* --- SATELLITE INFO - UNIT #1 --- */
if (_extended_logging) {
- if (copy_if_updated(ORB_ID(satellite_info), subs.sat_info_sub, &buf.sat_info)) {
+ if (copy_if_updated(ORB_ID(satellite_info), &subs.sat_info_sub, &buf.sat_info)) {
/* log the SNR of each satellite for a detailed view of signal quality */
unsigned sat_info_count = MIN(buf.sat_info.count, sizeof(buf.sat_info.snr) / sizeof(buf.sat_info.snr[0]));
@@ -1328,7 +1336,7 @@ int sdlog2_thread_main(int argc, char *argv[])
}
/* --- SENSOR COMBINED --- */
- if (copy_if_updated(ORB_ID(sensor_combined), subs.sensor_sub, &buf.sensor)) {
+ if (copy_if_updated(ORB_ID(sensor_combined), &subs.sensor_sub, &buf.sensor)) {
bool write_IMU = false;
bool write_IMU1 = false;
bool write_IMU2 = false;
@@ -1470,7 +1478,7 @@ int sdlog2_thread_main(int argc, char *argv[])
}
/* --- ATTITUDE --- */
- if (copy_if_updated(ORB_ID(vehicle_attitude), subs.att_sub, &buf.att)) {
+ if (copy_if_updated(ORB_ID(vehicle_attitude), &subs.att_sub, &buf.att)) {
log_msg.msg_type = LOG_ATT_MSG;
log_msg.body.log_ATT.q_w = buf.att.q[0];
log_msg.body.log_ATT.q_x = buf.att.q[1];
@@ -1489,7 +1497,7 @@ int sdlog2_thread_main(int argc, char *argv[])
}
/* --- ATTITUDE SETPOINT --- */
- if (copy_if_updated(ORB_ID(vehicle_attitude_setpoint), subs.att_sp_sub, &buf.att_sp)) {
+ if (copy_if_updated(ORB_ID(vehicle_attitude_setpoint), &subs.att_sp_sub, &buf.att_sp)) {
log_msg.msg_type = LOG_ATSP_MSG;
log_msg.body.log_ATSP.roll_sp = buf.att_sp.roll_body;
log_msg.body.log_ATSP.pitch_sp = buf.att_sp.pitch_body;
@@ -1503,7 +1511,7 @@ int sdlog2_thread_main(int argc, char *argv[])
}
/* --- RATES SETPOINT --- */
- if (copy_if_updated(ORB_ID(vehicle_rates_setpoint), subs.rates_sp_sub, &buf.rates_sp)) {
+ if (copy_if_updated(ORB_ID(vehicle_rates_setpoint), &subs.rates_sp_sub, &buf.rates_sp)) {
log_msg.msg_type = LOG_ARSP_MSG;
log_msg.body.log_ARSP.roll_rate_sp = buf.rates_sp.roll;
log_msg.body.log_ARSP.pitch_rate_sp = buf.rates_sp.pitch;
@@ -1512,14 +1520,14 @@ int sdlog2_thread_main(int argc, char *argv[])
}
/* --- ACTUATOR OUTPUTS --- */
- if (copy_if_updated(ORB_ID(actuator_outputs), subs.act_outputs_sub, &buf.act_outputs)) {
+ if (copy_if_updated(ORB_ID(actuator_outputs), &subs.act_outputs_sub, &buf.act_outputs)) {
log_msg.msg_type = LOG_OUT0_MSG;
memcpy(log_msg.body.log_OUT0.output, buf.act_outputs.output, sizeof(log_msg.body.log_OUT0.output));
LOGBUFFER_WRITE_AND_COUNT(OUT0);
}
/* --- ACTUATOR CONTROL --- */
- if (copy_if_updated(ORB_ID_VEHICLE_ATTITUDE_CONTROLS, subs.act_controls_sub, &buf.act_controls)) {
+ if (copy_if_updated(ORB_ID_VEHICLE_ATTITUDE_CONTROLS, &subs.act_controls_sub, &buf.act_controls)) {
log_msg.msg_type = LOG_ATTC_MSG;
log_msg.body.log_ATTC.roll = buf.act_controls.control[0];
log_msg.body.log_ATTC.pitch = buf.act_controls.control[1];
@@ -1529,7 +1537,7 @@ int sdlog2_thread_main(int argc, char *argv[])
}
/* --- ACTUATOR CONTROL FW VTOL --- */
- if(copy_if_updated(ORB_ID(actuator_controls_1),subs.act_controls_1_sub,&buf.act_controls)) {
+ if(copy_if_updated(ORB_ID(actuator_controls_1), &subs.act_controls_1_sub,&buf.act_controls)) {
log_msg.msg_type = LOG_ATC1_MSG;
log_msg.body.log_ATTC.roll = buf.act_controls.control[0];
log_msg.body.log_ATTC.pitch = buf.act_controls.control[1];
@@ -1539,7 +1547,7 @@ int sdlog2_thread_main(int argc, char *argv[])
}
/* --- LOCAL POSITION --- */
- if (copy_if_updated(ORB_ID(vehicle_local_position), subs.local_pos_sub, &buf.local_pos)) {
+ if (copy_if_updated(ORB_ID(vehicle_local_position), &subs.local_pos_sub, &buf.local_pos)) {
log_msg.msg_type = LOG_LPOS_MSG;
log_msg.body.log_LPOS.x = buf.local_pos.x;
log_msg.body.log_LPOS.y = buf.local_pos.y;
@@ -1565,7 +1573,7 @@ int sdlog2_thread_main(int argc, char *argv[])
}
/* --- LOCAL POSITION SETPOINT --- */
- if (copy_if_updated(ORB_ID(vehicle_local_position_setpoint), subs.local_pos_sp_sub, &buf.local_pos_sp)) {
+ if (copy_if_updated(ORB_ID(vehicle_local_position_setpoint), &subs.local_pos_sp_sub, &buf.local_pos_sp)) {
log_msg.msg_type = LOG_LPSP_MSG;
log_msg.body.log_LPSP.x = buf.local_pos_sp.x;
log_msg.body.log_LPSP.y = buf.local_pos_sp.y;
@@ -1581,7 +1589,7 @@ int sdlog2_thread_main(int argc, char *argv[])
}
/* --- GLOBAL POSITION --- */
- if (copy_if_updated(ORB_ID(vehicle_global_position), subs.global_pos_sub, &buf.global_pos)) {
+ if (copy_if_updated(ORB_ID(vehicle_global_position), &subs.global_pos_sub, &buf.global_pos)) {
log_msg.msg_type = LOG_GPOS_MSG;
log_msg.body.log_GPOS.lat = buf.global_pos.lat * 1e7;
log_msg.body.log_GPOS.lon = buf.global_pos.lon * 1e7;
@@ -1600,7 +1608,7 @@ int sdlog2_thread_main(int argc, char *argv[])
}
/* --- GLOBAL POSITION SETPOINT --- */
- if (copy_if_updated(ORB_ID(position_setpoint_triplet), subs.triplet_sub, &buf.triplet)) {
+ if (copy_if_updated(ORB_ID(position_setpoint_triplet), &subs.triplet_sub, &buf.triplet)) {
if (buf.triplet.current.valid) {
log_msg.msg_type = LOG_GPSP_MSG;
@@ -1618,7 +1626,7 @@ int sdlog2_thread_main(int argc, char *argv[])
}
/* --- VICON POSITION --- */
- if (copy_if_updated(ORB_ID(vehicle_vicon_position), subs.vicon_pos_sub, &buf.vicon_pos)) {
+ if (copy_if_updated(ORB_ID(vehicle_vicon_position), &subs.vicon_pos_sub, &buf.vicon_pos)) {
log_msg.msg_type = LOG_VICN_MSG;
log_msg.body.log_VICN.x = buf.vicon_pos.x;
log_msg.body.log_VICN.y = buf.vicon_pos.y;
@@ -1630,7 +1638,7 @@ int sdlog2_thread_main(int argc, char *argv[])
}
/* --- VISION POSITION --- */
- if (copy_if_updated(ORB_ID(vision_position_estimate), subs.vision_pos_sub, &buf.vision_pos)) {
+ if (copy_if_updated(ORB_ID(vision_position_estimate), &subs.vision_pos_sub, &buf.vision_pos)) {
log_msg.msg_type = LOG_VISN_MSG;
log_msg.body.log_VISN.x = buf.vision_pos.x;
log_msg.body.log_VISN.y = buf.vision_pos.y;
@@ -1638,15 +1646,15 @@ int sdlog2_thread_main(int argc, char *argv[])
log_msg.body.log_VISN.vx = buf.vision_pos.vx;
log_msg.body.log_VISN.vy = buf.vision_pos.vy;
log_msg.body.log_VISN.vz = buf.vision_pos.vz;
- log_msg.body.log_VISN.qx = buf.vision_pos.q[0];
- log_msg.body.log_VISN.qy = buf.vision_pos.q[1];
- log_msg.body.log_VISN.qz = buf.vision_pos.q[2];
- log_msg.body.log_VISN.qw = buf.vision_pos.q[3];
+ log_msg.body.log_VISN.qw = buf.vision_pos.q[0]; // vision_position_estimate uses [w,x,y,z] convention
+ log_msg.body.log_VISN.qx = buf.vision_pos.q[1];
+ log_msg.body.log_VISN.qy = buf.vision_pos.q[2];
+ log_msg.body.log_VISN.qz = buf.vision_pos.q[3];
LOGBUFFER_WRITE_AND_COUNT(VISN);
}
/* --- FLOW --- */
- if (copy_if_updated(ORB_ID(optical_flow), subs.flow_sub, &buf.flow)) {
+ if (copy_if_updated(ORB_ID(optical_flow), &subs.flow_sub, &buf.flow)) {
log_msg.msg_type = LOG_FLOW_MSG;
log_msg.body.log_FLOW.ground_distance_m = buf.flow.ground_distance_m;
log_msg.body.log_FLOW.gyro_temperature = buf.flow.gyro_temperature;
@@ -1662,7 +1670,7 @@ int sdlog2_thread_main(int argc, char *argv[])
}
/* --- RC CHANNELS --- */
- if (copy_if_updated(ORB_ID(rc_channels), subs.rc_sub, &buf.rc)) {
+ if (copy_if_updated(ORB_ID(rc_channels), &subs.rc_sub, &buf.rc)) {
log_msg.msg_type = LOG_RC_MSG;
/* Copy only the first 8 channels of 14 */
memcpy(log_msg.body.log_RC.channel, buf.rc.channels, sizeof(log_msg.body.log_RC.channel));
@@ -1672,7 +1680,7 @@ int sdlog2_thread_main(int argc, char *argv[])
}
/* --- AIRSPEED --- */
- if (copy_if_updated(ORB_ID(airspeed), subs.airspeed_sub, &buf.airspeed)) {
+ if (copy_if_updated(ORB_ID(airspeed), &subs.airspeed_sub, &buf.airspeed)) {
log_msg.msg_type = LOG_AIRS_MSG;
log_msg.body.log_AIRS.indicated_airspeed = buf.airspeed.indicated_airspeed_m_s;
log_msg.body.log_AIRS.true_airspeed = buf.airspeed.true_airspeed_m_s;
@@ -1681,7 +1689,7 @@ int sdlog2_thread_main(int argc, char *argv[])
}
/* --- ESCs --- */
- if (copy_if_updated(ORB_ID(esc_status), subs.esc_sub, &buf.esc)) {
+ if (copy_if_updated(ORB_ID(esc_status), &subs.esc_sub, &buf.esc)) {
for (uint8_t i = 0; i < buf.esc.esc_count; i++) {
log_msg.msg_type = LOG_ESC_MSG;
log_msg.body.log_ESC.counter = buf.esc.counter;
@@ -1701,7 +1709,7 @@ int sdlog2_thread_main(int argc, char *argv[])
}
/* --- GLOBAL VELOCITY SETPOINT --- */
- if (copy_if_updated(ORB_ID(vehicle_global_velocity_setpoint), subs.global_vel_sp_sub, &buf.global_vel_sp)) {
+ if (copy_if_updated(ORB_ID(vehicle_global_velocity_setpoint), &subs.global_vel_sp_sub, &buf.global_vel_sp)) {
log_msg.msg_type = LOG_GVSP_MSG;
log_msg.body.log_GVSP.vx = buf.global_vel_sp.vx;
log_msg.body.log_GVSP.vy = buf.global_vel_sp.vy;
@@ -1710,7 +1718,7 @@ int sdlog2_thread_main(int argc, char *argv[])
}
/* --- BATTERY --- */
- if (copy_if_updated(ORB_ID(battery_status), subs.battery_sub, &buf.battery)) {
+ if (copy_if_updated(ORB_ID(battery_status), &subs.battery_sub, &buf.battery)) {
log_msg.msg_type = LOG_BATT_MSG;
log_msg.body.log_BATT.voltage = buf.battery.voltage_v;
log_msg.body.log_BATT.voltage_filtered = buf.battery.voltage_filtered_v;
@@ -1720,7 +1728,7 @@ int sdlog2_thread_main(int argc, char *argv[])
}
/* --- SYSTEM POWER RAILS --- */
- if (copy_if_updated(ORB_ID(system_power), subs.system_power_sub, &buf.system_power)) {
+ if (copy_if_updated(ORB_ID(system_power), &subs.system_power_sub, &buf.system_power)) {
log_msg.msg_type = LOG_PWR_MSG;
log_msg.body.log_PWR.peripherals_5v = buf.system_power.voltage5V_v;
log_msg.body.log_PWR.usb_ok = buf.system_power.usb_connected;
@@ -1738,8 +1746,8 @@ int sdlog2_thread_main(int argc, char *argv[])
}
/* --- TELEMETRY --- */
- for (int i = 0; i < TELEMETRY_STATUS_ORB_ID_NUM; i++) {
- if (copy_if_updated(telemetry_status_orb_id[i], subs.telemetry_subs[i], &buf.telemetry)) {
+ for (unsigned i = 0; i < TELEMETRY_STATUS_ORB_ID_NUM; i++) {
+ if (copy_if_updated(telemetry_status_orb_id[i], &subs.telemetry_subs[i], &buf.telemetry)) {
log_msg.msg_type = LOG_TEL0_MSG + i;
log_msg.body.log_TEL.rssi = buf.telemetry.rssi;
log_msg.body.log_TEL.remote_rssi = buf.telemetry.remote_rssi;
@@ -1754,7 +1762,7 @@ int sdlog2_thread_main(int argc, char *argv[])
}
/* --- BOTTOM DISTANCE --- */
- if (copy_if_updated(ORB_ID(sensor_range_finder), subs.range_finder_sub, &buf.range_finder)) {
+ if (copy_if_updated(ORB_ID(sensor_range_finder), &subs.range_finder_sub, &buf.range_finder)) {
log_msg.msg_type = LOG_DIST_MSG;
log_msg.body.log_DIST.bottom = buf.range_finder.distance;
log_msg.body.log_DIST.bottom_rate = 0.0f;
@@ -1763,7 +1771,7 @@ int sdlog2_thread_main(int argc, char *argv[])
}
/* --- ESTIMATOR STATUS --- */
- if (copy_if_updated(ORB_ID(estimator_status), subs.estimator_status_sub, &buf.estimator_status)) {
+ if (copy_if_updated(ORB_ID(estimator_status), &subs.estimator_status_sub, &buf.estimator_status)) {
log_msg.msg_type = LOG_EST0_MSG;
unsigned maxcopy0 = (sizeof(buf.estimator_status.states) < sizeof(log_msg.body.log_EST0.s)) ? sizeof(buf.estimator_status.states) : sizeof(log_msg.body.log_EST0.s);
memset(&(log_msg.body.log_EST0.s), 0, sizeof(log_msg.body.log_EST0.s));
@@ -1782,7 +1790,7 @@ int sdlog2_thread_main(int argc, char *argv[])
}
/* --- TECS STATUS --- */
- if (copy_if_updated(ORB_ID(tecs_status), subs.tecs_status_sub, &buf.tecs_status)) {
+ if (copy_if_updated(ORB_ID(tecs_status), &subs.tecs_status_sub, &buf.tecs_status)) {
log_msg.msg_type = LOG_TECS_MSG;
log_msg.body.log_TECS.altitudeSp = buf.tecs_status.altitudeSp;
log_msg.body.log_TECS.altitudeFiltered = buf.tecs_status.altitude_filtered;
@@ -1802,7 +1810,7 @@ int sdlog2_thread_main(int argc, char *argv[])
}
/* --- WIND ESTIMATE --- */
- if (copy_if_updated(ORB_ID(wind_estimate), subs.wind_sub, &buf.wind_estimate)) {
+ if (copy_if_updated(ORB_ID(wind_estimate), &subs.wind_sub, &buf.wind_estimate)) {
log_msg.msg_type = LOG_WIND_MSG;
log_msg.body.log_WIND.x = buf.wind_estimate.windspeed_north;
log_msg.body.log_WIND.y = buf.wind_estimate.windspeed_east;
@@ -1812,7 +1820,7 @@ int sdlog2_thread_main(int argc, char *argv[])
}
/* --- ENCODERS --- */
- if (copy_if_updated(ORB_ID(encoders), subs.encoders_sub, &buf.encoders)) {
+ if (copy_if_updated(ORB_ID(encoders), &subs.encoders_sub, &buf.encoders)) {
log_msg.msg_type = LOG_ENCD_MSG;
log_msg.body.log_ENCD.cnt0 = buf.encoders.counts[0];
log_msg.body.log_ENCD.vel0 = buf.encoders.velocity[0];
@@ -1821,6 +1829,22 @@ int sdlog2_thread_main(int argc, char *argv[])
LOGBUFFER_WRITE_AND_COUNT(ENCD);
}
+ /* --- TIMESYNC OFFSET --- */
+ if (copy_if_updated(ORB_ID(time_offset), &subs.tsync_sub, &buf.time_offset)) {
+ log_msg.msg_type = LOG_TSYN_MSG;
+ log_msg.body.log_TSYN.time_offset = buf.time_offset.offset_ns;
+ LOGBUFFER_WRITE_AND_COUNT(TSYN);
+ }
+
+ /* --- MULTIROTOR ATTITUDE CONTROLLER STATUS --- */
+ if (copy_if_updated(ORB_ID(mc_att_ctrl_status), &subs.mc_att_ctrl_status_sub, &buf.mc_att_ctrl_status)) {
+ log_msg.msg_type = LOG_MACS_MSG;
+ log_msg.body.log_MACS.roll_rate_integ = buf.mc_att_ctrl_status.roll_rate_integ;
+ log_msg.body.log_MACS.pitch_rate_integ = buf.mc_att_ctrl_status.pitch_rate_integ;
+ log_msg.body.log_MACS.yaw_rate_integ = buf.mc_att_ctrl_status.yaw_rate_integ;
+ LOGBUFFER_WRITE_AND_COUNT(MACS);
+ }
+
/* signal the other thread new data, but not yet unlock */
if (logbuffer_count(&lb) > MIN_BYTES_TO_WRITE) {
/* only request write if several packets can be written at once */
diff --git a/src/modules/sdlog2/sdlog2_messages.h b/src/modules/sdlog2/sdlog2_messages.h
index a1fe2c95d..abdf518c5 100644
--- a/src/modules/sdlog2/sdlog2_messages.h
+++ b/src/modules/sdlog2/sdlog2_messages.h
@@ -441,7 +441,7 @@ struct log_ENCD_s {
};
/* --- AIR SPEED SENSORS - DIFF. PRESSURE --- */
-#define LOG_AIR1_MSG 40
+#define LOG_AIR1_MSG 41
/* --- VTOL - VTOL VEHICLE STATUS */
#define LOG_VTOL_MSG 42
@@ -449,6 +449,20 @@ struct log_VTOL_s {
float airspeed_tot;
};
+/* --- TIMESYNC - TIME SYNCHRONISATION OFFSET */
+#define LOG_TSYN_MSG 43
+struct log_TSYN_s {
+ uint64_t time_offset;
+};
+
+/* --- MACS - MULTIROTOR ATTITUDE CONTROLLER STATUS */
+#define LOG_MACS_MSG 44
+struct log_MACS_s {
+ float roll_rate_integ;
+ float pitch_rate_integ;
+ float yaw_rate_integ;
+};
+
/********** SYSTEM MESSAGES, ID > 0x80 **********/
/* --- TIME - TIME STAMP --- */
@@ -517,6 +531,8 @@ static const struct log_format_s log_formats[] = {
LOG_FORMAT(TECS, "fffffffffffffB", "ASP,AF,FSP,F,FF,AsSP,AsF,AsDSP,AsD,TERSP,TER,EDRSP,EDR,M"),
LOG_FORMAT(WIND, "ffff", "X,Y,CovX,CovY"),
LOG_FORMAT(ENCD, "qfqf", "cnt0,vel0,cnt1,vel1"),
+ LOG_FORMAT(TSYN, "Q", "TimeOffset"),
+ LOG_FORMAT(MACS, "fff", "RRint,PRint,YRint"),
/* system-level messages, ID >= 0x80 */
/* FMT: don't write format of format message, it's useless */
diff --git a/src/modules/segway/segway_main.cpp b/src/modules/segway/segway_main.cpp
index ee492f85a..b36d56d6d 100644
--- a/src/modules/segway/segway_main.cpp
+++ b/src/modules/segway/segway_main.cpp
@@ -92,8 +92,9 @@ usage(const char *reason)
int segway_main(int argc, char *argv[])
{
- if (argc < 1)
+ if (argc < 2) {
usage("missing command");
+ }
if (!strcmp(argv[1], "start")) {
diff --git a/src/modules/sensors/sensor_params.c b/src/modules/sensors/sensor_params.c
index 1acc14fc6..1bebea206 100644
--- a/src/modules/sensors/sensor_params.c
+++ b/src/modules/sensors/sensor_params.c
@@ -960,6 +960,7 @@ PARAM_DEFINE_INT32(BAT_V_SCALE_IO, 10000);
/**
* Scaling factor for battery voltage sensor on FMU v2.
*
+ * @board CONFIG_ARCH_BOARD_PX4FMU_V2
* @group Battery Calibration
*/
PARAM_DEFINE_FLOAT(BAT_V_SCALING, 0.0082f);
@@ -969,6 +970,7 @@ PARAM_DEFINE_FLOAT(BAT_V_SCALING, 0.0082f);
*
* For R70 = 133K, R71 = 10K --> scale = 1.8 * 143 / (4096*10) = 0.0063
*
+ * @board CONFIG_ARCH_BOARD_AEROCORE
* @group Battery Calibration
*/
PARAM_DEFINE_FLOAT(BAT_V_SCALING, 0.0063f);
@@ -1099,7 +1101,7 @@ PARAM_DEFINE_INT32(RC_MAP_YAW, 4);
*
* @min 0
* @max 18
- * @group Radio Calibration
+ * @group Radio Switches
*/
PARAM_DEFINE_INT32(RC_MAP_MODE_SW, 0);
@@ -1108,7 +1110,7 @@ PARAM_DEFINE_INT32(RC_MAP_MODE_SW, 0);
*
* @min 0
* @max 18
- * @group Radio Calibration
+ * @group Radio Switches
*/
PARAM_DEFINE_INT32(RC_MAP_RETURN_SW, 0);
@@ -1117,7 +1119,7 @@ PARAM_DEFINE_INT32(RC_MAP_RETURN_SW, 0);
*
* @min 0
* @max 18
- * @group Radio Calibration
+ * @group Radio Switches
*/
PARAM_DEFINE_INT32(RC_MAP_POSCTL_SW, 0);
@@ -1126,7 +1128,7 @@ PARAM_DEFINE_INT32(RC_MAP_POSCTL_SW, 0);
*
* @min 0
* @max 18
- * @group Radio Calibration
+ * @group Radio Switches
*/
PARAM_DEFINE_INT32(RC_MAP_LOITER_SW, 0);
@@ -1135,7 +1137,7 @@ PARAM_DEFINE_INT32(RC_MAP_LOITER_SW, 0);
*
* @min 0
* @max 18
- * @group Radio Calibration
+ * @group Radio Switches
*/
PARAM_DEFINE_INT32(RC_MAP_ACRO_SW, 0);
@@ -1144,7 +1146,7 @@ PARAM_DEFINE_INT32(RC_MAP_ACRO_SW, 0);
*
* @min 0
* @max 18
- * @group Radio Calibration
+ * @group Radio Switches
*/
PARAM_DEFINE_INT32(RC_MAP_OFFB_SW, 0);
@@ -1153,7 +1155,7 @@ PARAM_DEFINE_INT32(RC_MAP_OFFB_SW, 0);
*
* @min 0
* @max 18
- * @group Radio Calibration
+ * @group Radio Switches
*/
PARAM_DEFINE_INT32(RC_MAP_FLAPS, 0);
@@ -1238,9 +1240,6 @@ PARAM_DEFINE_INT32(RC_FAILS_THR, 0);
/**
* Threshold for selecting assist mode
*
- * min:-1
- * max:+1
- *
* 0-1 indicate where in the full channel range the threshold sits
* 0 : min
* 1 : max
@@ -1248,15 +1247,17 @@ PARAM_DEFINE_INT32(RC_FAILS_THR, 0);
* positive : true when channel>th
* negative : true when channel<th
*
+ * @min -1
+ * @max 1
+ * @group Radio Switches
+ *
+ *
*/
PARAM_DEFINE_FLOAT(RC_ASSIST_TH, 0.25f);
/**
* Threshold for selecting auto mode
*
- * min:-1
- * max:+1
- *
* 0-1 indicate where in the full channel range the threshold sits
* 0 : min
* 1 : max
@@ -1264,15 +1265,17 @@ PARAM_DEFINE_FLOAT(RC_ASSIST_TH, 0.25f);
* positive : true when channel>th
* negative : true when channel<th
*
+ * @min -1
+ * @max 1
+ * @group Radio Switches
+ *
+ *
*/
PARAM_DEFINE_FLOAT(RC_AUTO_TH, 0.75f);
/**
* Threshold for selecting posctl mode
*
- * min:-1
- * max:+1
- *
* 0-1 indicate where in the full channel range the threshold sits
* 0 : min
* 1 : max
@@ -1280,15 +1283,16 @@ PARAM_DEFINE_FLOAT(RC_AUTO_TH, 0.75f);
* positive : true when channel>th
* negative : true when channel<th
*
+ * @min -1
+ * @max 1
+ *
+ *
*/
PARAM_DEFINE_FLOAT(RC_POSCTL_TH, 0.5f);
/**
* Threshold for selecting return to launch mode
*
- * min:-1
- * max:+1
- *
* 0-1 indicate where in the full channel range the threshold sits
* 0 : min
* 1 : max
@@ -1296,15 +1300,17 @@ PARAM_DEFINE_FLOAT(RC_POSCTL_TH, 0.5f);
* positive : true when channel>th
* negative : true when channel<th
*
+ * @min -1
+ * @max 1
+ * @group Radio Switches
+ *
+ *
*/
PARAM_DEFINE_FLOAT(RC_RETURN_TH, 0.5f);
/**
* Threshold for selecting loiter mode
*
- * min:-1
- * max:+1
- *
* 0-1 indicate where in the full channel range the threshold sits
* 0 : min
* 1 : max
@@ -1312,15 +1318,17 @@ PARAM_DEFINE_FLOAT(RC_RETURN_TH, 0.5f);
* positive : true when channel>th
* negative : true when channel<th
*
+ * @min -1
+ * @max 1
+ * @group Radio Switches
+ *
+ *
*/
PARAM_DEFINE_FLOAT(RC_LOITER_TH, 0.5f);
/**
* Threshold for selecting acro mode
*
- * min:-1
- * max:+1
- *
* 0-1 indicate where in the full channel range the threshold sits
* 0 : min
* 1 : max
@@ -1328,6 +1336,11 @@ PARAM_DEFINE_FLOAT(RC_LOITER_TH, 0.5f);
* positive : true when channel>th
* negative : true when channel<th
*
+ * @min -1
+ * @max 1
+ * @group Radio Switches
+ *
+ *
*/
PARAM_DEFINE_FLOAT(RC_ACRO_TH, 0.5f);
@@ -1335,9 +1348,6 @@ PARAM_DEFINE_FLOAT(RC_ACRO_TH, 0.5f);
/**
* Threshold for selecting offboard mode
*
- * min:-1
- * max:+1
- *
* 0-1 indicate where in the full channel range the threshold sits
* 0 : min
* 1 : max
@@ -1345,5 +1355,49 @@ PARAM_DEFINE_FLOAT(RC_ACRO_TH, 0.5f);
* positive : true when channel>th
* negative : true when channel<th
*
+ * @min -1
+ * @max 1
+ * @group Radio Switches
+ *
+ *
*/
PARAM_DEFINE_FLOAT(RC_OFFB_TH, 0.5f);
+
+/**
+ * PWM input channel that provides RSSI.
+ *
+ * 0: do not read RSSI from input channel
+ * 1-18: read RSSI from specified input channel
+ *
+ * Specify the range for RSSI input with RC_RSSI_PWM_MIN and RC_RSSI_PWM_MAX parameters.
+ *
+ * @min 0
+ * @max 18
+ * @group Radio Calibration
+ *
+ */
+PARAM_DEFINE_INT32(RC_RSSI_PWM_CHAN, 0);
+
+/**
+ * Max input value for RSSI reading.
+ *
+ * Only used if RC_RSSI_PWM_CHAN > 0
+ *
+ * @min 0
+ * @max 2000
+ * @group Radio Calibration
+ *
+ */
+PARAM_DEFINE_INT32(RC_RSSI_PWM_MAX, 1000);
+
+/**
+ * Min input value for RSSI reading.
+ *
+ * Only used if RC_RSSI_PWM_CHAN > 0
+ *
+ * @min 0
+ * @max 2000
+ * @group Radio Calibration
+ *
+ */
+PARAM_DEFINE_INT32(RC_RSSI_PWM_MIN, 2000);
diff --git a/src/modules/sensors/sensors.cpp b/src/modules/sensors/sensors.cpp
index 259361be6..4fbc0416e 100644
--- a/src/modules/sensors/sensors.cpp
+++ b/src/modules/sensors/sensors.cpp
@@ -145,7 +145,7 @@
#endif
static const int ERROR = -1;
-#define CAL_FAILED_APPLY_CAL_MSG "FAILED APPLYING %s CAL #%u"
+#define CAL_ERROR_APPLY_CAL_MSG "FAILED APPLYING %s CAL #%u"
/**
* Sensor app start / stop handling function
@@ -246,6 +246,7 @@ private:
struct differential_pressure_s _diff_pres;
struct airspeed_s _airspeed;
struct rc_parameter_map_s _rc_parameter_map;
+ float _param_rc_values[RC_PARAM_MAP_NCHAN]; /**< parameter values for RC control */
math::Matrix<3, 3> _board_rotation; /**< rotation matrix for the orientation that the board is mounted */
math::Matrix<3, 3> _mag_rotation[3]; /**< rotation matrix for the orientation that the external mag0 is mounted */
@@ -523,6 +524,7 @@ Sensors::Sensors() :
/* performance counters */
_loop_perf(perf_alloc(PC_ELAPSED, "sensor task update")),
+ _param_rc_values{},
_board_rotation{},
_mag_rotation{},
@@ -620,6 +622,18 @@ Sensors::Sensors() :
/* Barometer QNH */
_parameter_handles.baro_qnh = param_find("SENS_BARO_QNH");
+ // These are parameters for which QGroundControl always expects to be returned in a list request.
+ // We do a param_find here to force them into the list.
+ (void)param_find("RC_CHAN_CNT");
+ (void)param_find("RC_TH_USER");
+ (void)param_find("CAL_MAG0_ID");
+ (void)param_find("CAL_MAG1_ID");
+ (void)param_find("CAL_MAG2_ID");
+ (void)param_find("CAL_MAG0_ROT");
+ (void)param_find("CAL_MAG1_ROT");
+ (void)param_find("CAL_MAG2_ROT");
+ (void)param_find("SYS_PARAM_VER");
+
/* fetch initial parameter values */
parameters_update();
}
@@ -1382,14 +1396,13 @@ Sensors::parameter_update_poll(bool forced)
failed = failed || (OK != param_get(param_find(str), &gscale.z_scale));
if (failed) {
- warnx(CAL_FAILED_APPLY_CAL_MSG, "gyro", i);
+ warnx(CAL_ERROR_APPLY_CAL_MSG, "gyro", i);
} else {
/* apply new scaling and offsets */
res = ioctl(fd, GYROIOCSSCALE, (long unsigned int)&gscale);
if (res) {
- warnx(CAL_FAILED_APPLY_CAL_MSG, "gyro", i);
+ warnx(CAL_ERROR_APPLY_CAL_MSG, "gyro", i);
} else {
- gyro_count++;
config_ok = true;
}
}
@@ -1397,11 +1410,11 @@ Sensors::parameter_update_poll(bool forced)
}
}
- close(fd);
-
- if (!config_ok) {
- warnx("NO CONFIG FOR GYRO #%u", s);
+ if (config_ok) {
+ gyro_count++;
}
+
+ close(fd);
}
/* run through all accel sensors */
@@ -1449,14 +1462,13 @@ Sensors::parameter_update_poll(bool forced)
failed = failed || (OK != param_get(param_find(str), &gscale.z_scale));
if (failed) {
- warnx(CAL_FAILED_APPLY_CAL_MSG, "accel", i);
+ warnx(CAL_ERROR_APPLY_CAL_MSG, "accel", i);
} else {
/* apply new scaling and offsets */
res = ioctl(fd, ACCELIOCSSCALE, (long unsigned int)&gscale);
if (res) {
- warnx(CAL_FAILED_APPLY_CAL_MSG, "accel", i);
+ warnx(CAL_ERROR_APPLY_CAL_MSG, "accel", i);
} else {
- accel_count++;
config_ok = true;
}
}
@@ -1464,11 +1476,11 @@ Sensors::parameter_update_poll(bool forced)
}
}
- close(fd);
-
- if (!config_ok) {
- warnx("NO CONFIG FOR ACCEL #%u", s);
+ if (config_ok) {
+ accel_count++;
}
+
+ close(fd);
}
/* run through all mag sensors */
@@ -1480,9 +1492,16 @@ Sensors::parameter_update_poll(bool forced)
int fd = open(str, 0);
if (fd < 0) {
+ /* the driver is not running, abort */
continue;
}
+ /* set a valid default rotation (same as board).
+ * if the mag is configured, this might be replaced
+ * in the section below.
+ */
+ _mag_rotation[s] = _board_rotation;
+
bool config_ok = false;
/* run through all stored calibrations */
@@ -1566,14 +1585,13 @@ Sensors::parameter_update_poll(bool forced)
}
if (failed) {
- warnx(CAL_FAILED_APPLY_CAL_MSG, "mag", i);
+ warnx(CAL_ERROR_APPLY_CAL_MSG, "mag", i);
} else {
/* apply new scaling and offsets */
res = ioctl(fd, MAGIOCSSCALE, (long unsigned int)&gscale);
if (res) {
- warnx(CAL_FAILED_APPLY_CAL_MSG, "mag", i);
+ warnx(CAL_ERROR_APPLY_CAL_MSG, "mag", i);
} else {
- mag_count++;
config_ok = true;
}
}
@@ -1581,11 +1599,11 @@ Sensors::parameter_update_poll(bool forced)
}
}
- close(fd);
-
- if (!config_ok) {
- warnx("NO CONFIG FOR MAG #%u", s);
+ if (config_ok) {
+ mag_count++;
}
+
+ close(fd);
}
int fd = open(AIRSPEED0_DEVICE_PATH, 0);
@@ -1605,7 +1623,8 @@ Sensors::parameter_update_poll(bool forced)
close(fd);
}
- warnx("config: %u gyros, %u mags, %u accels", gyro_count, mag_count, accel_count);
+ /* do not output this for now, as its covered in preflight checks */
+ // warnx("valid configs: %u gyros, %u mags, %u accels", gyro_count, mag_count, accel_count);
}
}
@@ -1629,7 +1648,7 @@ Sensors::rc_parameter_map_poll(bool forced)
/* Set the handle by index if the index is set, otherwise use the id */
if (_rc_parameter_map.param_index[i] >= 0) {
- _parameter_handles.rc_param[i] = param_for_index((unsigned)_rc_parameter_map.param_index[i]);
+ _parameter_handles.rc_param[i] = param_for_used_index((unsigned)_rc_parameter_map.param_index[i]);
} else {
_parameter_handles.rc_param[i] = param_find(_rc_parameter_map.param_id[i]);
@@ -1834,8 +1853,6 @@ Sensors::get_rc_sw2pos_position(uint8_t func, float on_th, bool on_inv)
void
Sensors::set_params_from_rc()
{
- static float param_rc_values[RC_PARAM_MAP_NCHAN] = {};
-
for (int i = 0; i < RC_PARAM_MAP_NCHAN; i++) {
if (_rc.function[rc_channels_s::RC_CHANNELS_FUNCTION_PARAM_1 + i] < 0 || !_rc_parameter_map.valid[i]) {
/* This RC channel is not mapped to a RC-Parameter Channel (e.g. RC_MAP_PARAM1 == 0)
@@ -1847,8 +1864,8 @@ Sensors::set_params_from_rc()
float rc_val = get_rc_value((rc_channels_s::RC_CHANNELS_FUNCTION_PARAM_1 + i), -1.0, 1.0);
/* Check if the value has changed,
* maybe we need to introduce a more aggressive limit here */
- if (rc_val > param_rc_values[i] + FLT_EPSILON || rc_val < param_rc_values[i] - FLT_EPSILON) {
- param_rc_values[i] = rc_val;
+ if (rc_val > _param_rc_values[i] + FLT_EPSILON || rc_val < _param_rc_values[i] - FLT_EPSILON) {
+ _param_rc_values[i] = rc_val;
float param_val = math::constrain(
_rc_parameter_map.value0[i] + _rc_parameter_map.scale[i] * rc_val,
_rc_parameter_map.value_min[i], _rc_parameter_map.value_max[i]);
@@ -2252,7 +2269,7 @@ Sensors::start()
int sensors_main(int argc, char *argv[])
{
- if (argc < 1) {
+ if (argc < 2) {
errx(1, "usage: sensors {start|stop|status}");
}
diff --git a/src/modules/systemlib/circuit_breaker_params.c b/src/modules/systemlib/circuit_breaker_params.c
index e499ae27a..e5cc034bc 100644
--- a/src/modules/systemlib/circuit_breaker_params.c
+++ b/src/modules/systemlib/circuit_breaker_params.c
@@ -43,7 +43,6 @@
*/
#include <px4.h>
-#include <systemlib/circuit_breaker_params.h>
/**
* Circuit breaker for power supply check
@@ -56,7 +55,7 @@
* @max 894281
* @group Circuit Breaker
*/
-PX4_PARAM_DEFINE_INT32(CBRK_SUPPLY_CHK);
+PARAM_DEFINE_INT32(CBRK_SUPPLY_CHK, 0);
/**
* Circuit breaker for rate controller output
@@ -69,7 +68,7 @@ PX4_PARAM_DEFINE_INT32(CBRK_SUPPLY_CHK);
* @max 140253
* @group Circuit Breaker
*/
-PX4_PARAM_DEFINE_INT32(CBRK_RATE_CTRL);
+PARAM_DEFINE_INT32(CBRK_RATE_CTRL, 0);
/**
* Circuit breaker for IO safety
@@ -81,7 +80,7 @@ PX4_PARAM_DEFINE_INT32(CBRK_RATE_CTRL);
* @max 22027
* @group Circuit Breaker
*/
-PX4_PARAM_DEFINE_INT32(CBRK_IO_SAFETY);
+PARAM_DEFINE_INT32(CBRK_IO_SAFETY, 0);
/**
* Circuit breaker for airspeed sensor
@@ -93,7 +92,7 @@ PX4_PARAM_DEFINE_INT32(CBRK_IO_SAFETY);
* @max 162128
* @group Circuit Breaker
*/
-PX4_PARAM_DEFINE_INT32(CBRK_AIRSPD_CHK);
+PARAM_DEFINE_INT32(CBRK_AIRSPD_CHK, 0);
/**
* Circuit breaker for flight termination
@@ -106,7 +105,7 @@ PX4_PARAM_DEFINE_INT32(CBRK_AIRSPD_CHK);
* @max 121212
* @group Circuit Breaker
*/
-PX4_PARAM_DEFINE_INT32(CBRK_FLIGHTTERM);
+PARAM_DEFINE_INT32(CBRK_FLIGHTTERM, 121212);
/**
* Circuit breaker for engine failure detection
@@ -120,4 +119,4 @@ PX4_PARAM_DEFINE_INT32(CBRK_FLIGHTTERM);
* @max 284953
* @group Circuit Breaker
*/
-PX4_PARAM_DEFINE_INT32(CBRK_ENGINEFAIL);
+PARAM_DEFINE_INT32(CBRK_ENGINEFAIL, 284953);
diff --git a/src/modules/systemlib/circuit_breaker_params.h b/src/modules/systemlib/circuit_breaker_params.h
deleted file mode 100644
index 768bf7f53..000000000
--- a/src/modules/systemlib/circuit_breaker_params.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#define PARAM_CBRK_SUPPLY_CHK_DEFAULT 0
-#define PARAM_CBRK_RATE_CTRL_DEFAULT 0
-#define PARAM_CBRK_IO_SAFETY_DEFAULT 0
-#define PARAM_CBRK_AIRSPD_CHK_DEFAULT 0
-#define PARAM_CBRK_FLIGHTTERM_DEFAULT 121212
-#define PARAM_CBRK_ENGINEFAIL_DEFAULT 284953
-#define PARAM_CBRK_GPSFAIL_DEFAULT 240024
diff --git a/src/modules/systemlib/param/param.c b/src/modules/systemlib/param/param.c
index 8dea6e6cc..4ec885ab3 100644
--- a/src/modules/systemlib/param/param.c
+++ b/src/modules/systemlib/param/param.c
@@ -92,7 +92,7 @@ struct param_wbuf_s {
};
// XXX this should be param_info_count, but need to work out linking
-uint8_t param_changed_storage[(600 / sizeof(uint8_t)) + 1] = {};
+uint8_t param_changed_storage[(700 / sizeof(uint8_t)) + 1] = {};
/** flexible array holding modified parameter values */
UT_array *param_values;
@@ -265,8 +265,37 @@ param_count_used(void)
param_t
param_for_index(unsigned index)
{
- if (index < param_info_count)
+ if (index < param_info_count) {
return (param_t)index;
+ }
+
+ return PARAM_INVALID;
+}
+
+param_t
+param_for_used_index(unsigned index)
+{
+ if (index < param_info_count) {
+
+ /* walk all params and count */
+ int count = 0;
+
+ for (unsigned i = 0; i < (unsigned)param_info_count + 1; i++) {
+ for (unsigned j = 0; j < 8; j++) {
+ if (param_changed_storage[i] & (1 << j)) {
+
+ /* we found the right used count,
+ * return the param value
+ */
+ if (index == count) {
+ return (param_t)i;
+ }
+
+ count++;
+ }
+ }
+ }
+ }
return PARAM_INVALID;
}
@@ -274,8 +303,9 @@ param_for_index(unsigned index)
int
param_get_index(param_t param)
{
- if (handle_in_range(param))
+ if (handle_in_range(param)) {
return (unsigned)param;
+ }
return -1;
}
@@ -283,7 +313,9 @@ param_get_index(param_t param)
int
param_get_used_index(param_t param)
{
- if (!handle_in_range(param)) {
+ int param_storage_index = param_get_index(param);
+
+ if (param_storage_index < 0) {
return -1;
}
@@ -293,12 +325,17 @@ param_get_used_index(param_t param)
for (unsigned i = 0; i < (unsigned)param + 1; i++) {
for (unsigned j = 0; j < 8; j++) {
if (param_changed_storage[i] & (1 << j)) {
+
+ if (param_storage_index == i) {
+ return count;
+ }
+
count++;
}
}
}
- return count;
+ return -1;
}
const char *
diff --git a/src/modules/systemlib/param/param.h b/src/modules/systemlib/param/param.h
index b29a7e51d..9cbe3570b 100644
--- a/src/modules/systemlib/param/param.h
+++ b/src/modules/systemlib/param/param.h
@@ -130,6 +130,14 @@ __EXPORT bool param_used(param_t param);
__EXPORT param_t param_for_index(unsigned index);
/**
+ * Look up an used parameter by index.
+ *
+ * @param param The parameter to obtain the index for.
+ * @return The index of the parameter in use, or -1 if the parameter does not exist.
+ */
+__EXPORT param_t param_for_used_index(unsigned index);
+
+/**
* Look up the index of a parameter.
*
* @param param The parameter to obtain the index for.
diff --git a/src/modules/uORB/objects_common.cpp b/src/modules/uORB/objects_common.cpp
index dbed29774..1a38b981e 100644
--- a/src/modules/uORB/objects_common.cpp
+++ b/src/modules/uORB/objects_common.cpp
@@ -250,3 +250,9 @@ ORB_DEFINE(wind_estimate, struct wind_estimate_s);
#include "topics/rc_parameter_map.h"
ORB_DEFINE(rc_parameter_map, struct rc_parameter_map_s);
+
+#include "topics/time_offset.h"
+ORB_DEFINE(time_offset, struct time_offset_s);
+
+#include "topics/mc_att_ctrl_status.h"
+ORB_DEFINE(mc_att_ctrl_status, struct mc_att_ctrl_status_s);
diff --git a/src/modules/uORB/topics/time_offset.h b/src/modules/uORB/topics/time_offset.h
new file mode 100644
index 000000000..99e526c76
--- /dev/null
+++ b/src/modules/uORB/topics/time_offset.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+ *
+ * Copyright (c) 2015 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 time_offset.h
+ * Time synchronisation offset
+ */
+
+#ifndef TOPIC_TIME_OFFSET_H_
+#define TOPIC_TIME_OFFSET_H_
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "../uORB.h"
+
+/**
+ * @addtogroup topics
+ * @{
+ */
+
+/**
+ * Timesync offset for synchronisation with companion computer, GCS, etc.
+ */
+struct time_offset_s {
+
+ uint64_t offset_ns; /**< time offset between companion system and PX4, in nanoseconds */
+
+};
+
+/**
+ * @}
+ */
+
+/* register this as object request broker structure */
+ORB_DECLARE(time_offset);
+
+#endif /* TOPIC_TIME_OFFSET_H_ */
diff --git a/src/modules/uORB/uORB.cpp b/src/modules/uORB/uORB.cpp
index b4f81d429..d531c6b0b 100644
--- a/src/modules/uORB/uORB.cpp
+++ b/src/modules/uORB/uORB.cpp
@@ -41,6 +41,7 @@
#include <drivers/device/device.h>
#include <sys/types.h>
+#include <sys/stat.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
@@ -1196,6 +1197,25 @@ node_open(Flavor f, const struct orb_metadata *meta, const void *data, bool adve
} // namespace
+int
+orb_exists(const struct orb_metadata *meta, int instance)
+{
+ /*
+ * Generate the path to the node and try to open it.
+ */
+ char path[orb_maxpath];
+ int inst = instance;
+ int ret = node_mkpath(path, PUBSUB, meta, &inst);
+
+ if (ret != OK) {
+ errno = -ret;
+ return ERROR;
+ }
+
+ struct stat buffer;
+ return stat(path, &buffer);
+}
+
orb_advert_t
orb_advertise(const struct orb_metadata *meta, const void *data)
{
diff --git a/src/modules/uORB/uORB.h b/src/modules/uORB/uORB.h
index 44dc6614f..a8b19d91f 100644
--- a/src/modules/uORB/uORB.h
+++ b/src/modules/uORB/uORB.h
@@ -319,6 +319,15 @@ extern int orb_check(int handle, bool *updated) __EXPORT;
extern int orb_stat(int handle, uint64_t *time) __EXPORT;
/**
+ * Check if a topic has already been created.
+ *
+ * @param meta ORB topic metadata.
+ * @param instance ORB instance
+ * @return OK if the topic exists, ERROR otherwise with errno set accordingly.
+ */
+extern int orb_exists(const struct orb_metadata *meta, int instance) __EXPORT;
+
+/**
* Return the priority of the topic
*
* @param handle A handle returned from orb_subscribe.
diff --git a/src/modules/uavcan/module.mk b/src/modules/uavcan/module.mk
index 4f63629a0..437feb301 100644
--- a/src/modules/uavcan/module.mk
+++ b/src/modules/uavcan/module.mk
@@ -58,17 +58,20 @@ SRCS += sensors/sensor_bridge.cpp \
# libuavcan
#
include $(PX4_LIB_DIR)uavcan/libuavcan/include.mk
-SRCS += $(LIBUAVCAN_SRC)
+# Use the relitive path to keep the genrated files in the BUILD_DIR
+SRCS += $(subst $(PX4_MODULE_SRC),../../,$(LIBUAVCAN_SRC))
INCLUDE_DIRS += $(LIBUAVCAN_INC)
# Since actual compiler mode is C++11, the library will default to UAVCAN_CPP11, but it will fail to compile
# because this platform lacks most of the standard library and STL. Hence we need to force C++03 mode.
-override EXTRADEFINES := $(EXTRADEFINES) -DUAVCAN_CPP_VERSION=UAVCAN_CPP03 -DUAVCAN_NO_ASSERTIONS
+override EXTRADEFINES := $(EXTRADEFINES) -DGIT_VERSION='"$(GIT_DESC)"' -DUAVCAN_CPP_VERSION=UAVCAN_CPP03 -DUAVCAN_NO_ASSERTIONS
+
#
# libuavcan drivers for STM32
#
include $(PX4_LIB_DIR)uavcan/libuavcan_drivers/stm32/driver/include.mk
-SRCS += $(LIBUAVCAN_STM32_SRC)
+# Use the relitive path to keep the genrated files in the BUILD_DIR
+SRCS += $(subst $(PX4_MODULE_SRC),../../,$(LIBUAVCAN_STM32_SRC))
INCLUDE_DIRS += $(LIBUAVCAN_STM32_INC)
override EXTRADEFINES := $(EXTRADEFINES) -DUAVCAN_STM32_NUTTX -DUAVCAN_STM32_NUM_IFACES=2
diff --git a/src/modules/uavcan/uavcan_main.cpp b/src/modules/uavcan/uavcan_main.cpp
index 02cde9656..f04ab9f17 100644
--- a/src/modules/uavcan/uavcan_main.cpp
+++ b/src/modules/uavcan/uavcan_main.cpp
@@ -210,9 +210,9 @@ void UavcanNode::fill_node_info()
/* software version */
uavcan::protocol::SoftwareVersion swver;
- // Extracting the first 8 hex digits of FW_GIT and converting them to int
+ // Extracting the first 8 hex digits of GIT_VERSION and converting them to int
char fw_git_short[9] = {};
- std::memmove(fw_git_short, FW_GIT, 8);
+ std::memmove(fw_git_short, GIT_VERSION, 8);
assert(fw_git_short[8] == '\0');
char *end = nullptr;
swver.vcs_commit = std::strtol(fw_git_short, &end, 16);
@@ -698,7 +698,9 @@ int uavcan_main(int argc, char *argv[])
if (!std::strcmp(argv[1], "start")) {
if (UavcanNode::instance()) {
- errx(1, "already started");
+ // Already running, no error
+ warnx("already started");
+ ::exit(0);
}
// Node ID
diff --git a/src/modules/vtol_att_control/vtol_att_control_main.cpp b/src/modules/vtol_att_control/vtol_att_control_main.cpp
index 74e1efd6c..2ae10bd27 100644
--- a/src/modules/vtol_att_control/vtol_att_control_main.cpp
+++ b/src/modules/vtol_att_control/vtol_att_control_main.cpp
@@ -176,7 +176,7 @@ private:
bool flag_idle_mc; //false = "idle is set for fixed wing mode"; true = "idle is set for multicopter mode"
unsigned _motor_count; // number of motors
float _airspeed_tot;
-
+ float _tilt_control;
//*****************Member functions***********************************************************************
void task_main(); //main task
@@ -241,6 +241,7 @@ VtolAttitudeControl::VtolAttitudeControl() :
flag_idle_mc = true;
_airspeed_tot = 0.0f;
+ _tilt_control = 0.0f;
memset(& _vtol_vehicle_status, 0, sizeof(_vtol_vehicle_status));
_vtol_vehicle_status.vtol_in_rw_mode = true; /* start vtol in rotary wing mode*/
@@ -521,6 +522,7 @@ void VtolAttitudeControl::fill_mc_att_control_output()
//set neutral position for elevons
_actuators_out_1.control[0] = _actuators_mc_in.control[2]; //roll elevon
_actuators_out_1.control[1] = _actuators_mc_in.control[1];; //pitch elevon
+ _actuators_out_1.control[4] = _tilt_control; // for tilt-rotor control
}
/**
@@ -763,7 +765,7 @@ void VtolAttitudeControl::task_main()
vehicle_battery_poll();
- if (_manual_control_sp.aux1 <= 0.0f) { /* vehicle is in mc mode */
+ if (_manual_control_sp.aux1 < 0.0f) { /* vehicle is in mc mode */
_vtol_vehicle_status.vtol_in_rw_mode = true;
if (!flag_idle_mc) { /* we want to adjust idle speed for mc mode */
@@ -877,7 +879,7 @@ VtolAttitudeControl::start()
int vtol_att_control_main(int argc, char *argv[])
{
- if (argc < 1) {
+ if (argc < 2) {
errx(1, "usage: vtol_att_control {start|stop|status}");
}
diff --git a/src/modules/vtol_att_control/vtol_att_control_params.c b/src/modules/vtol_att_control/vtol_att_control_params.c
index 33752b2c4..6da28b130 100644
--- a/src/modules/vtol_att_control/vtol_att_control_params.c
+++ b/src/modules/vtol_att_control/vtol_att_control_params.c
@@ -43,7 +43,7 @@
/**
* VTOL number of engines
*
- * @min 1.0
+ * @min 1
* @group VTOL Attitude Control
*/
PARAM_DEFINE_INT32(VT_MOT_COUNT,0);
@@ -92,8 +92,8 @@ PARAM_DEFINE_FLOAT(VT_MC_ARSPD_TRIM,10.0f);
* If set to one this parameter will cause permanent attitude stabilization in fw mode.
* This parameter has been introduced for pure convenience sake.
*
- * @min 0.0
- * @max 1.0
+ * @min 0
+ * @max 1
* @group VTOL Attitude Control
*/
PARAM_DEFINE_INT32(VT_FW_PERM_STAB,0);
diff --git a/src/systemcmds/param/param.c b/src/systemcmds/param/param.c
index 6b855cf58..98443e716 100644
--- a/src/systemcmds/param/param.c
+++ b/src/systemcmds/param/param.c
@@ -284,9 +284,9 @@ do_show_print(void *arg, param_t param)
}
}
- printf("%c %c %s: ", (param_used(param) ? 'x' : ' '),
+ printf("%c %c %s [%d,%d] : ", (param_used(param) ? 'x' : ' '),
param_value_unsaved(param) ? '*' : (param_value_is_default(param) ? ' ' : '+'),
- param_name(param));
+ param_name(param), param_get_used_index(param), param_get_index(param));
/*
* This case can be expanded to handle printing common structure types.
diff --git a/src/systemcmds/preflight_check/preflight_check.c b/src/systemcmds/preflight_check/preflight_check.c
deleted file mode 100644
index 361ca6754..000000000
--- a/src/systemcmds/preflight_check/preflight_check.c
+++ /dev/null
@@ -1,286 +0,0 @@
-/****************************************************************************
- *
- * Copyright (c) 2012, 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
- * 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 preflight_check.c
- *
- * Preflight check for main system components
- *
- * @author Lorenz Meier <lorenz@px4.io>
- */
-
-#include <nuttx/config.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <math.h>
-
-#include <systemlib/err.h>
-#include <systemlib/param/param.h>
-
-#include <drivers/drv_led.h>
-#include <drivers/drv_hrt.h>
-#include <drivers/drv_tone_alarm.h>
-#include <drivers/drv_mag.h>
-#include <drivers/drv_gyro.h>
-#include <drivers/drv_accel.h>
-#include <drivers/drv_baro.h>
-
-#include <mavlink/mavlink_log.h>
-#include <systemlib/rc_check.h>
-
-__EXPORT int preflight_check_main(int argc, char *argv[]);
-static int led_toggle(int leds, int led);
-static int led_on(int leds, int led);
-static int led_off(int leds, int led);
-
-int preflight_check_main(int argc, char *argv[])
-{
- bool fail_on_error = false;
-
- if (argc > 1 && !strcmp(argv[1], "--help")) {
- warnx("usage: preflight_check [--fail-on-error]\n\tif fail on error is enabled, will return 1 on error");
- exit(1);
- }
-
- if (argc > 1 && !strcmp(argv[1], "--fail-on-error")) {
- fail_on_error = true;
- }
-
- bool system_ok = true;
-
- int fd;
- /* open text message output path */
- int mavlink_fd = open(MAVLINK_LOG_DEVICE, 0);
- int ret;
- int32_t devid, calibration_devid;
-
- /* give the system some time to sample the sensors in the background */
- usleep(150000);
-
- /* ---- MAG ---- */
- fd = open(MAG0_DEVICE_PATH, 0);
- if (fd < 0) {
- warn("failed to open magnetometer - start with 'hmc5883 start' or 'lsm303d start'");
- mavlink_log_critical(mavlink_fd, "SENSOR FAIL: NO MAG");
- system_ok = false;
- goto system_eval;
- }
-
- devid = ioctl(fd, DEVIOCGDEVICEID,0);
- param_get(param_find("CAL_MAG0_ID"), &(calibration_devid));
- if (devid != calibration_devid){
- warnx("magnetometer calibration is for a different device - calibrate magnetometer first");
- mavlink_log_critical(mavlink_fd, "SENSOR FAIL: MAG CAL ID");
- system_ok = false;
- goto system_eval;
- }
-
- ret = ioctl(fd, MAGIOCSELFTEST, 0);
-
- if (ret != OK) {
- warnx("magnetometer calibration missing or bad - calibrate magnetometer first");
- mavlink_log_critical(mavlink_fd, "SENSOR FAIL: MAG CHECK/CAL");
- system_ok = false;
- goto system_eval;
- }
-
- /* ---- ACCEL ---- */
-
- close(fd);
- fd = open(ACCEL0_DEVICE_PATH, O_RDONLY);
-
- devid = ioctl(fd, DEVIOCGDEVICEID,0);
- param_get(param_find("CAL_ACC0_ID"), &(calibration_devid));
- if (devid != calibration_devid){
- warnx("accelerometer calibration is for a different device - calibrate accelerometer first");
- mavlink_log_critical(mavlink_fd, "SENSOR FAIL: ACC CAL ID");
- system_ok = false;
- goto system_eval;
- }
-
- ret = ioctl(fd, ACCELIOCSELFTEST, 0);
-
- if (ret != OK) {
- warnx("accel self test failed");
- mavlink_log_critical(mavlink_fd, "SENSOR FAIL: ACCEL CHECK/CAL");
- system_ok = false;
- goto system_eval;
- }
-
- /* check measurement result range */
- struct accel_report acc;
- ret = read(fd, &acc, sizeof(acc));
-
- if (ret == sizeof(acc)) {
- /* evaluate values */
- if (sqrtf(acc.x * acc.x + acc.y * acc.y + acc.z * acc.z) > 30.0f /* m/s^2 */) {
- warnx("accel with spurious values");
- mavlink_log_critical(mavlink_fd, "SENSOR FAIL: |ACCEL| > 30 m/s^2");
- /* this is frickin' fatal */
- fail_on_error = true;
- system_ok = false;
- goto system_eval;
- }
- } else {
- warnx("accel read failed");
- mavlink_log_critical(mavlink_fd, "SENSOR FAIL: ACCEL READ");
- /* this is frickin' fatal */
- fail_on_error = true;
- system_ok = false;
- goto system_eval;
- }
-
- /* ---- GYRO ---- */
-
- close(fd);
- fd = open(GYRO0_DEVICE_PATH, 0);
-
- devid = ioctl(fd, DEVIOCGDEVICEID,0);
- param_get(param_find("CAL_GYRO0_ID"), &(calibration_devid));
- if (devid != calibration_devid){
- warnx("gyro calibration is for a different device - calibrate gyro first");
- mavlink_log_critical(mavlink_fd, "SENSOR FAIL: GYRO CAL ID");
- system_ok = false;
- goto system_eval;
- }
-
- ret = ioctl(fd, GYROIOCSELFTEST, 0);
-
- if (ret != OK) {
- warnx("gyro self test failed");
- mavlink_log_critical(mavlink_fd, "SENSOR FAIL: GYRO CHECK/CAL");
- system_ok = false;
- goto system_eval;
- }
-
- /* ---- BARO ---- */
-
- close(fd);
- fd = open(BARO0_DEVICE_PATH, 0);
- close(fd);
-
- /* ---- RC CALIBRATION ---- */
-
- bool rc_ok = (OK == rc_calibration_check(mavlink_fd));
-
- /* warn */
- if (!rc_ok)
- warnx("rc calibration test failed");
-
- /* require RC ok to keep system_ok */
- system_ok &= rc_ok;
-
-
-
-
-system_eval:
-
- if (system_ok) {
- /* all good, exit silently */
- exit(0);
- } else {
- fflush(stdout);
-
- warnx("PREFLIGHT CHECK ERROR! TRIGGERING ALARM");
- fflush(stderr);
-
- int buzzer = open(TONEALARM0_DEVICE_PATH, O_WRONLY);
- int leds = open(LED0_DEVICE_PATH, 0);
-
- if (leds < 0) {
- close(buzzer);
- errx(1, "failed to open leds, aborting");
- }
-
- /* flip blue led into alternating amber */
- led_off(leds, LED_BLUE);
- led_off(leds, LED_AMBER);
- led_toggle(leds, LED_BLUE);
-
- /* display and sound error */
- for (int i = 0; i < 14; i++)
- {
- led_toggle(leds, LED_BLUE);
- led_toggle(leds, LED_AMBER);
-
- if (i % 10 == 0) {
- ioctl(buzzer, TONE_SET_ALARM, TONE_NOTIFY_NEUTRAL_TUNE);
- } else if (i % 5 == 0) {
- ioctl(buzzer, TONE_SET_ALARM, TONE_ERROR_TUNE);
- }
- usleep(100000);
- }
-
- /* stop alarm */
- ioctl(buzzer, TONE_SET_ALARM, TONE_STOP_TUNE);
-
- /* switch off leds */
- led_on(leds, LED_BLUE);
- led_on(leds, LED_AMBER);
- close(leds);
-
- if (fail_on_error) {
- /* exit with error message */
- exit(1);
- } else {
- /* do not emit an error code to make sure system still boots */
- exit(0);
- }
- }
-}
-
-static int led_toggle(int leds, int led)
-{
- static int last_blue = LED_ON;
- static int last_amber = LED_ON;
-
- if (led == LED_BLUE) last_blue = (last_blue == LED_ON) ? LED_OFF : LED_ON;
-
- if (led == LED_AMBER) last_amber = (last_amber == LED_ON) ? LED_OFF : LED_ON;
-
- return ioctl(leds, ((led == LED_BLUE) ? last_blue : last_amber), led);
-}
-
-static int led_off(int leds, int led)
-{
- return ioctl(leds, LED_OFF, led);
-}
-
-static int led_on(int leds, int led)
-{
- return ioctl(leds, LED_ON, led);
-}
diff --git a/src/systemcmds/tests/test_gpio.c b/src/systemcmds/tests/test_gpio.c
index 62a873270..82c122550 100644
--- a/src/systemcmds/tests/test_gpio.c
+++ b/src/systemcmds/tests/test_gpio.c
@@ -89,10 +89,11 @@
int test_gpio(int argc, char *argv[])
{
- int fd;
int ret = 0;
- fd = open(PX4IO_DEVICE_PATH, 0);
+#ifdef PX4IO_DEVICE_PATH
+
+ int fd = open(PX4IO_DEVICE_PATH, 0);
if (fd < 0) {
printf("GPIO: open fail\n");
@@ -109,7 +110,11 @@ int test_gpio(int argc, char *argv[])
/* Go back to default */
ioctl(fd, GPIO_RESET, ~0);
+ close(fd);
printf("\t GPIO test successful.\n");
+#endif
+
+
return ret;
}
diff --git a/src/systemcmds/ver/module.mk b/src/systemcmds/ver/module.mk
index 2eeb80b61..4597b5f11 100644
--- a/src/systemcmds/ver/module.mk
+++ b/src/systemcmds/ver/module.mk
@@ -42,3 +42,5 @@ SRCS = ver.c
MODULE_STACKSIZE = 1024
MAXOPTIMIZATION = -Os
+
+EXTRADEFINES = -DGIT_VERSION='"$(GIT_DESC)"'
diff --git a/src/systemcmds/ver/ver.c b/src/systemcmds/ver/ver.c
index 087eb52e3..b794e8b2f 100644
--- a/src/systemcmds/ver/ver.c
+++ b/src/systemcmds/ver/ver.c
@@ -101,7 +101,7 @@ int ver_main(int argc, char *argv[])
}
if (show_all || !strncmp(argv[1], sz_ver_git_str, sizeof(sz_ver_git_str))) {
- printf("FW git-hash: %s\n", FW_GIT);
+ printf("FW git-hash: %s\n", GIT_VERSION);
ret = 0;
}