Compare commits

...

254 Commits

Author SHA1 Message Date
Bill Bonney
03373d35c2 AutoTest: Add ability to run AC3.2.1 in screen 2015-04-18 12:41:42 +09:00
Randy Mackay
36b405fb0b Copter: version to AC3.2.1 2015-02-11 12:13:19 +09:00
Randy Mackay
dde418477c Copter: AC3.2.1 release notes
No changes from AC3.2.1-rc2
2015-02-11 12:13:14 +09:00
Randy Mackay
5f118b2936 Copter: update AC3.2.1-rc2 release notes 2015-02-03 09:55:44 +09:00
Randy Mackay
375b9a5bb1 AC_PosControl: move alt limit to set_alt_target_from_climb_rate
The alt limit is instead enforced when the target is set using the
set_alt_target_from_climb_rate function
Also updated comments
2015-02-03 09:50:45 +09:00
Robert Lefebvre
e28b7c3abe Copter: update pos_control alt_max from fence at 1hz 2015-02-03 09:50:43 +09:00
Robert Lefebvre
b32081fae6 AC_PosControl: Enable altitude limit checking. 2015-02-03 09:50:40 +09:00
Randy Mackay
90961bb104 Copter: protect against multiple arming messages
Protect against the GCS sending multiple arming messages close together
which disrupts the gyro calibration
2015-02-03 09:46:46 +09:00
Randy Mackay
a067a5e623 Copter: land detector requires desired climb rate be < -20cm/s 2015-01-31 17:28:19 +09:00
Randy Mackay
ef4ca821c5 Copter: AC3.2.1-rc2 release notes 2015-01-30 16:21:33 +09:00
Randy Mackay
fee41beb59 Copter: version to AC3.2.1-rc2 2015-01-30 16:21:06 +09:00
Andrew Tridgell
b010556f37 AP_Mission: prevent infinite loop with linked jump commands
this prevents a "jump loop" from causing a firmware lockup. Thanks to
dellarb for reporting this!
2015-01-23 11:18:38 +09:00
Randy Mackay
0c3f43b2d7 AutoTest: reduce copter throttle when in stabilize
Simulated copter is flying too high and causing the land to timeout
2015-01-14 16:06:31 +09:00
Randy Mackay
3fd38edc4a Copter: restore baro climb rate check to land_detector 2015-01-14 16:06:27 +09:00
Randy Mackay
651a0182a7 Copter: move land_detector to separate file 2015-01-14 16:06:22 +09:00
Jonathan Challinger
ca68a9a8a3 Copter: clean up land detector and modify to use desired velocity 2015-01-14 16:06:19 +09:00
Jonathan Challinger
2d82672893 AC_PosControl: Fill _vel_desired.z for reporting 2015-01-14 16:06:16 +09:00
Jonathan Challinger
79975b1309 AP_Math: change ROTATION_YAW_293_PITCH_68_ROLL_180 to ROLL_90 2015-01-12 15:19:57 +09:00
Andrew Tridgell
eb9b2bf4e9 AP_Math: fixed build warning 2015-01-12 15:19:47 +09:00
Randy Mackay
4b5411e86a AP_Math: add new rotation to example rotation sketch 2015-01-12 15:18:32 +09:00
Randy Mackay
6b0e636abf AP_Math: add yaw 293, pitch 68, roll 180 rotation 2015-01-12 15:16:53 +09:00
Randy Mackay
343dd16779 Copter: fix typo in AC3.2.1 Release Notes 2015-01-10 22:30:21 +09:00
Randy Mackay
f1207e019d Copter: update AC3.2.1-rc1 Release Notes 2015-01-09 04:58:34 +09:00
Randy Mackay
43762c9fa4 Copter: increase GPS_HDOP_GOOD default to 2.3 2015-01-09 04:54:08 +09:00
Randy Mackay
688088829b Copter: update version to AC3.2.1-rc1 2015-01-08 21:17:53 +09:00
Randy Mackay
c0f5b548e0 Copter: AC3.2.1-rc1 Release Notes 2015-01-08 21:17:20 +09:00
Andrew Tridgell
113475b158 autotest: use small INS offsets so INS is recognised as being calibrated 2015-01-08 20:52:17 +09:00
Andrew Tridgell
18b6c013dd PX4: added px4_common.mk 2015-01-08 20:51:20 +09:00
Andrew Tridgell
b058f3fdce AP_InertialSensor: added missing files 2015-01-08 20:51:17 +09:00
Andrew Tridgell
3761870544 build: update to build rules from master 2015-01-08 20:51:13 +09:00
Andrew Tridgell
e7dcb43407 PX4: update to new PX4 config 2015-01-08 20:51:11 +09:00
Andrew Tridgell
712b95bf8e AP_HAL: added micros64() method 2015-01-08 20:51:08 +09:00
Andrew Tridgell
8da5716ea7 Travis: don't build Linux for travis in copter-3.2 2015-01-08 20:51:05 +09:00
Andrew Tridgell
f053af5312 Travis: only build copter in copter-3.2 branch 2015-01-08 20:51:03 +09:00
Andrew Tridgell
9b9665153e Travis: update to latest prereqs script from master 2015-01-08 20:51:00 +09:00
Andrew Tridgell
fbef07c08d Travis: added build script from master 2015-01-08 20:50:57 +09:00
Andrew Tridgell
7b178efd25 Copter: fixes for AP_InertialSensor API changes 2015-01-08 20:50:54 +09:00
Andrew Tridgell
94f3c64df9 HAL_SITL: fixed for changes in AP_InertialSensor API 2015-01-08 20:50:51 +09:00
Andrew Tridgell
827e60f948 AP_InertialSensor: roll up to latest AP_InertialSensor from master 2015-01-08 20:50:48 +09:00
Andrew Tridgell
0ad7a39db2 Copter: import new travis config 2015-01-08 20:49:30 +09:00
Randy Mackay
f5fb21b1d7 Copter: run_nav_updates at 50hz on Pixhawk, 25hz on APM2
Based on work by Jon Challinger (see earlier commit)
2015-01-08 20:33:58 +09:00
Jonathan Challinger
aa1b0da254 Copter: run_nav_updates at 100hz on pixhawk 2015-01-08 20:33:55 +09:00
Randy Mackay
105e2e19ac Copter: skip pre-arm checks when already armed 2015-01-08 15:17:48 +09:00
Randy Mackay
4033f11a3c Copter: report NAV_CONTROLLER_OUTPUT in RTL, Guided
This allows the GCS to display to the user where the vehicle is flying
to in RTL and Guided flight modes
2015-01-06 16:39:39 +09:00
Randy Mackay
1266a31631 Rally: reduce distance limit to 300m for copter
This reduces the chance that a forgotten rally point will cause the
vehicle to RTL to a distant location because instead it will RTL to
home.
2015-01-06 15:56:34 +09:00
Robert Lefebvre
152a3a2828 ArduCopter: Bug fix, int8t should be uint16t. 2015-01-06 15:52:36 +09:00
Randy Mackay
6b236eb7ea Copter: set pre_arm_gps_check flag 2014-12-26 15:10:34 +09:00
Randy Mackay
44c5fdffdf Notify: add pre_arm_gps_check flag
RGB LED will remain flashing blue when vehicle is disarmed and this
check has failed (i.e. false).
2014-12-26 15:10:31 +09:00
Randy Mackay
59350821a3 AC_PosControl: fix to default force_descend param 2014-12-24 14:44:56 +09:00
Jonathan Challinger
f3e9e9cc6f Copter: use force_descend option on auto landings 2014-12-24 14:44:55 +09:00
Jonathan Challinger
77bbd2532b AC_PosControl: add force_descend option to set_alt_target_from_climb_rate 2014-12-24 14:44:54 +09:00
Randy Mackay
6327f4adf1 Copter: allow arming in GUIDED only from GCS
Also changed mode_allows_arming function to accept arming_from_gcs param
Also remove AUTOTUNE from arming list
2014-12-24 14:44:53 +09:00
Jonathan Challinger
c65cb45c07 Copter: move all arm check logic into arm_checks 2014-12-24 14:44:53 +09:00
Jonathan Challinger
e05f8d3087 Copter: add mode_allows_arming function 2014-12-24 14:44:52 +09:00
Jonathan Challinger
7ea5e69f9c Copter: auto-disarm if land complete regardless of mode 2014-12-24 14:44:51 +09:00
Jonathan Challinger
9fc62b5db2 Copter: use ap.throttle_zero instead of rc_3.control_in in auto_disarm_check 2014-12-24 14:44:50 +09:00
Jonathan Challinger
f64f155c3a Copter: add land_complete to fence disarm check 2014-12-24 14:44:49 +09:00
Randy Mackay
9ced648479 Copter: throttle zero debounce to separate function
Also initialise throttle_zero  to true on startup
Treat throttle less than zero as zero
2014-12-24 14:44:48 +09:00
Jonathan Challinger
8d63a65793 Copter: Change all zero throttle checks that should be conservative to use ap.throttle_zero 2014-12-24 14:44:48 +09:00
Jonathan Challinger
506c7661a4 Copter: add throttle_zero state 2014-12-24 14:44:47 +09:00
Andrew Tridgell
0c371f1b98 DataFlash: don't try and open logfile on failure more than once
this prevents a corrupted microSD card from causing a continuous
attempt to open a log file while in flight, which can cause large
scheduler delays

Pair-Programmed-With: Grant Morphett <grant@gmorph.com>
2014-12-23 16:03:02 +09:00
Andrew Tridgell
60ded486c2 DataFlash: don't write out parameters if log open fails 2014-12-23 16:02:59 +09:00
Andrew Tridgell
d5108195da HAL_PX4: FRAM does not support fsync
the fsync just wastes time reopening /fs/mtd
2014-12-19 09:18:31 +09:00
Emile Castelnuovo
412de3cf76 AP_Compass: VRBRAIN add #if !defined() for VRBRAIN 4.5 boards. 2014-11-11 11:14:13 -08:00
LukeMike
45e3b0e9cd VRBRAIN: added script for build all VirtualRobotix binaries 2014-11-11 11:14:10 -08:00
LukeMike
f50d48f409 VRBRAIN: added new board VR Brain 5 PRO 2014-11-11 11:14:06 -08:00
LukeMike
12ade1e65c VRBRAIN: added flag for to build versions with different kind of RC Inputs 2014-11-11 11:13:58 -08:00
LukeMike
1455d700d4 VRBRAIN: defined AirSpeed inputs for ArduPlane on VR Micro Brain 5 2014-11-11 11:13:54 -08:00
Emile Castelnuovo
2de18f844b AP_Compass: VRBRAIN. Deal with external mag connected on internal I2C on VRBRAIN 4.5
This enables user to set the external parameter to true even if only one compass is connected
2014-11-11 11:13:49 -08:00
LukeMike
0a3ef32649 VRBRAIN: modified target clean 2014-11-11 11:13:40 -08:00
Randy Mackay
c8e0f3e13a Copter: update version to AC3.2 2014-11-07 13:49:50 +09:00
Randy Mackay
f8de0ecc9e Copter: update AC3.2 ReleaseNotes 2014-11-07 13:49:25 +09:00
Randy Mackay
bd69290e5a Copter: minor update to AC3.2-rc14 ReleaseNotes 2014-10-31 10:56:46 +09:00
Randy Mackay
3a292db7f1 Copter: update AC3.2-rc14 ReleaseNotes 2014-10-29 18:09:11 +09:00
priseborough
fecad46336 AP_NavEKF : add INIT_GYRO_BIAS_UNCERTAINTY definition 2014-10-29 17:42:10 +09:00
Randy Mackay
ddb8796d2c Copter: return false when arming fails 2014-10-29 15:59:54 +09:00
Randy Mackay
683f3a55c4 Copter: re-enable CPU failsafe if arming fails 2014-10-29 15:59:22 +09:00
Randy Mackay
dc3509ef55 Copter: fail to arm if gyro cal fails 2014-10-29 15:45:56 +09:00
priseborough
a7caa91cef AP_NavEKF : Add public method to reset gyro bias states 2014-10-29 15:42:34 +09:00
priseborough
d04a740bcb AP_AHRS : Add reset of EKF gyro bias states 2014-10-29 15:42:31 +09:00
Randy Mackay
1ab5d71927 GPS: init primary_instance to zero 2014-10-29 15:42:28 +09:00
Benoit PEREIRA DA SILVA
a8a6368f05 GPS: use primary for Notification 2014-10-29 15:42:26 +09:00
Randy Mackay
7b4cd9ee37 Copter: reset ahrs gyro drift after gyro calibration 2014-10-29 15:42:22 +09:00
Randy Mackay
95538d2992 AHRS: add reset_gyro_drift method 2014-10-29 15:42:20 +09:00
Jonathan Challinger
ef0b934b10 Copter: don't stop logging on disarm when LOG_WHEN_DISARMED is set 2014-10-29 15:42:16 +09:00
Randy Mackay
a9e6c06f1a Copter: update version to AC3.2-rc14 2014-10-27 22:27:27 +09:00
Randy Mackay
1921e22265 Copter: ReleaseNotes for AC3.2-rc14 2014-10-27 22:27:14 +09:00
Andrew Tridgell
fae45b29fa AP_InertialSensor: fixed timer bug in HIL sensors 2014-10-27 21:10:55 +09:00
Randy Mackay
3a8d4cdcda Copter: fix to dcm-check to be continuous
dcm-check was triggering after 10 bad headings but these did not need to
be continuous meaning if the vehicle was flown long enough it would
almost certainly trigger a dcm-check failure and land
2014-10-27 12:39:24 +09:00
Randy Mackay
8041613c06 RangeFinder: PulsedLight I2C addr to 0x62 2014-10-24 15:00:47 +09:00
Andrew Tridgell
7ad0b6177f AP_RangeFinder: auto-update PX4 ll40ls max/min distance
this allows the range of the Lidar to be set by the user using
RNGFND_MAX_CM and RNGFND_MIN_CM
2014-10-24 13:48:38 +09:00
Randy Mackay
83a5102ec5 Copter: version to AC3.2-rc13 2014-10-23 22:20:10 +09:00
Randy Mackay
4bd3f593ef Copter: ReleaseNotes for AC3.2-rc13 2014-10-23 22:20:07 +09:00
Randy Mackay
bafd9fd53f RangeFinder: reduce num instances to 1 2014-10-23 22:20:05 +09:00
Randy Mackay
47418b78d6 Relay: reduce num relays to 2 2014-10-23 22:20:01 +09:00
Randy Mackay
fdf6aa5492 Copter: shorten ESC calibration message 2014-10-23 22:19:58 +09:00
Randy Mackay
8b87a407ed Copter: remove debug 2014-10-23 22:19:55 +09:00
Randy Mackay
a4da667e2b Mount: remove CMD_DO_MOUNT_CONFIGURE support 2014-10-23 22:19:52 +09:00
Randy Mackay
00f9882241 Copter: remove DO_MOUNT_CONFIGURE support
The functions in the mount lib didn't work anyway
2014-10-23 22:19:48 +09:00
Randy Mackay
43c5a70424 Copter: completely disable vel controller 2014-10-23 22:19:44 +09:00
Randy Mackay
5cbcbf9b37 DataFlash: log baro climbrate 2014-10-22 17:40:55 +09:00
Randy Mackay
0d2954b5a4 Copter: landing detector checks baro climb rate
Barometer climb rate must be -150cm/s ~ +150cm/s
This threshold is generous because we already use the inertial
navigation climb rate so this is just to catch cases where inertial nav
is very incorrect in it's climbrate estimates
2014-10-22 17:40:53 +09:00
Jonathan Challinger
0335138683 Copter: print frame type in log headers 2014-10-22 14:57:31 +09:00
Randy Mackay
ba5e368175 AC_WPNav: bug fix sanity check of set_speed_xy
This corrects a bug that allowed the waypoint speed to be set to zero
2014-10-21 22:11:26 +09:00
Randy Mackay
65472eaf62 AHRS_DCM: sanity check AHRS_RP_P and AHRS_YAW_P 2014-10-21 22:11:23 +09:00
Randy Mackay
3638bfb614 AC_PosControl: bug fix dt calculation
fixes issue in which now could be earlier than _last_update_xy_ms
leading to a large dt value and a sudden lean on takeoff
2014-10-21 11:41:55 +09:00
priseborough
d37c788394 AP_NavEKF: Track baro alt when pre-armed
This will help prevent spurious alt disparity warning messages for copter
2014-10-20 17:13:37 +09:00
Randy Mackay
8da15cb409 Copter: check target of set-mode request from GCS
Issue discovered and fix contributed by Deadolous
2014-10-20 13:57:21 +09:00
Randy Mackay
d71b08af0c AP_Motors: reduce slow-start increment for fast CPUs 2014-10-18 20:54:59 +09:00
Randy Mackay
9d76d3b423 Copter: log DCM reported roll-pitch and yaw error 2014-10-18 20:14:32 +09:00
Randy Mackay
cd35293a7b Parachute: set servo or relay to off position on every update
This resolves the issue of the parachute servo's position not being
initialised to the off position due to an ordering problem of the
auxiliary servos being initialised after the parachute object.
2014-10-18 17:27:12 +09:00
Andrew Tridgell
bbb6471277 Replay: fixed loading of users parameters and parameter override
use compass.set_offsets() to avoid trying to write to storage
2014-10-17 21:34:07 +09:00
Andrew Tridgell
820b4e2bed AP_Compass: added set_offsets() interface
this will be used by Replay to prevent the need for saving parameters
2014-10-17 21:34:05 +09:00
Randy Mackay
92225dc5db Copter: add NearlyAll-AC315 LOG_BITMASK description 2014-10-17 21:34:02 +09:00
Randy Mackay
d58f7ada62 Copter: remove extra in_mavlink_delay from should_log function
Also return false when logging disabled
2014-10-17 21:33:58 +09:00
Andrew Tridgell
c093160ea9 Copter: support logging while disarmed 2014-10-17 21:33:52 +09:00
Randy Mackay
7e1c975c54 Copter: add DCM check of yaw error
Triggers an "ekf" failsafe if the DCM yaw error is > 60deg
2014-10-16 17:28:42 +09:00
Randy Mackay
470fcc2077 Copter: add DCM_CHECK_THRESH parameter 2014-10-16 17:27:15 +09:00
Andrew Tridgell
ed30c0938e AP_AHRS: use a common function for updating the CD values
this ensures the wrapping of yaw is consistent between the 3 use cases
2014-10-15 11:28:30 +09:00
Andrew Tridgell
f61ae9e9e5 AP_AHRS: restore DCM attitude before update()
The DCM drift correction code uses the current attitude to calculate
error values to update its gyro drift correction. If we were using EKF
then without this patch the DCM code running as an alternative AHRS
source would be using the EKF attitude for calculating the error
value, leading to very bad gyro drift estimation
2014-10-15 11:28:25 +09:00
Andrew Tridgell
0dcf501766 AP_AHRS: fixed calls to DCM in parent class
use_compass() and reset() are common to AP_AHRS_DCM and
AP_AHRS_NavEKF. As AP_AHRS_NavEKF is a child of AP_AHRS_DCM, when we
call use_compass() from within AP_AHRS_DCM we actually end up calling
AP_AHRS_NavEKF::use_compass().

This has the effect of disabling the compass in DCM when EKF is active
and EKF has decided not to use the compass. That means that the DCM
yaw (and in fact the whole attitude) can get badly off while EKF is
enabled, making DCM an ineffective fallback if EKF fails.

The fix is to call the specific class versions of use_compass() and
reset()
2014-10-15 11:28:23 +09:00
Jonathan Challinger
71722d2e49 Copter: remove DRIFT and SPORT from manual_flight_mode function 2014-10-11 15:28:28 +09:00
Jonathan Challinger
4f427c6215 AC_PosControl: Protect from divide-by-zero in get_stopping_point_xy 2014-10-10 21:19:45 +09:00
Randy Mackay
6537432b50 Copter: auto-trim start delays auto-disarm by 15sec
Fixes issue in which user only had 5 seconds after starting auto-trim to
raise the throttle before the auto-disarm would kick-in.
2014-10-09 22:42:47 +09:00
Randy Mackay
74e86a3cd7 Copter: version to AC3.2-rc12 2014-10-09 20:18:06 +09:00
Randy Mackay
01a4ad24af Copter: AC3.2-rc12 release notes 2014-10-09 20:17:55 +09:00
Randy Mackay
31c256bdd8 AP_InertialNav: fixed use of ahrs.get_velocity with EKF disabled 2014-10-09 20:13:40 +09:00
Andrew Tridgell
811e8571f1 AP_InertialNav: fixed use of _ahrs.get_relative_position_NED() with EKF disabled
this prevents a floating point error caused by using an uninitialised
vector3 when switching between DCM and EKF control in AP_InertialNav

Pair-Programmed-With: Randy Mackay <rmackay9@yahoo.com>
2014-10-09 20:13:37 +09:00
Randy Mackay
7f8a68d44a Copter: support pre-flight calibration of gyro 2014-10-09 10:26:05 +09:00
Randy Mackay
661755e05a Copter: report gyro unhealthy if failed calibration 2014-10-09 10:25:52 +09:00
Randy Mackay
eb594775b7 Copter: pre-arm check that gyro cal succeeded 2014-10-09 10:25:47 +09:00
Randy Mackay
d309ecb587 INS: add gyro_calibrated_ok_all method
This returns true if the gyros have been calibrated successfully
2014-10-09 10:25:42 +09:00
Randy Mackay
a95b8f1b0e Copter: Rate Pitch IMAX default to 1000
Spotted by Jonathan Challinger, thanks!
2014-10-07 21:07:40 +09:00
Randy Mackay
5891cd3078 Copter: disable sonar on APM1 and TradHeli on APM2 2014-10-07 14:13:35 +09:00
Randy Mackay
a1e707b7f9 Copter: cleanup enabling of cli and frsky telem for APM 2014-10-07 12:57:09 +09:00
Randy Mackay
26b5321130 Copter: version to AC3.2-rc11 2014-10-06 11:48:13 +09:00
Randy Mackay
95b2b45a7b Copter: ReleaseNotes for AC3.2-rc11 2014-10-06 11:48:00 +09:00
Randy Mackay
51de79c2f8 MotorsMatrix: _min_throttle interpreted as 0 ~ 1000 range for throttle_lower flag
Also trigger throttle_upper flag when throttle in reaches 1000
2014-10-04 23:51:04 +09:00
Randy Mackay
55173cc340 Tri: _min_throttle interpreted as 0~1000 range for throttle_lower flag
limit.throttle_lower flag becomes true when the throttle passed into the
motors lib (which is in the 0 ~ 1000 range) is below _min throttle.
This makes the interpretation of the THR_MIN parameter consistent
between the main code (which uses 0 ~ 1000 range) and the motors lib
(which previously used the RC3_MIN ~ RC3_MAX range).
The remaining problem however is that the output of the motors continues
to use THR_MIN as if it were a pwm.  I don't believe this is a dangerous
problem however.
2014-10-04 23:51:01 +09:00
lthall
e836832595 Copter: increase autotune limits
Rate D max to 0.020 (was 0.015)
Rate P max to 0.35 (was 0.25)
Stab P max to 20 (was 15)
2014-10-03 12:37:40 +09:00
priseborough
6cbb9d635a AP_NavEKF : Fix bug in reset of GPS glitch offset
The GPS glitch offset was being zeroed during position resets. This caused the filter to reject subsequent GPS measurements if the GPS error persisted long enough to invoke a timeout and a position reset.
2014-10-03 09:20:05 +09:00
Randy Mackay
400dd94ec5 TradHeli: remove overall throttle level from landing check 2014-10-02 16:14:08 +09:00
Randy Mackay
3b0a308ed2 Copter: only report ahrs unhealthy after initialisation 2014-10-02 15:02:55 +09:00
Randy Mackay
29c704fecc AHRS: rename ekfNotStarted method to initialised
Also created default implementation in AP_AHRS class so AP_AHRS_DCM does
not need to implement it.
2014-10-02 15:02:52 +09:00
priseborough
b51d01f979 AP_AHRS : add method to report if EKF is waiting to start 2014-10-02 15:02:50 +09:00
Andrew Tridgell
89755c2bb5 AP_NavEKF: make it clear that all sat counts are covered 2014-10-01 13:12:48 +09:00
Andrew Tridgell
468ebd811c AP_NavEKF: simplify variable handling in EKF
use named state variables instead of states[] array where possible.
2014-10-01 13:12:46 +09:00
Randy Mackay
c338b1675f GPS: fix SIRF set-binary message
This fixes an issue in which the the update rate for the mediatek, which
uses a similar protocol, was not being set correctly
2014-10-01 11:43:24 +09:00
Randy Mackay
da2a463f18 Copter: shift pos targets to current location before takeoff 2014-09-29 15:28:16 +09:00
Randy Mackay
2d7f819e1d AC_WPNav: add shift_wp_origin_to_current_pos for takeoff
This shifts the origin to the vehicle's current position and should be
called just before take-off to ensure there are no sudden roll or pitch
moves on takeoff.
2014-09-29 15:28:14 +09:00
priseborough
a6cd04ca4c AP_NavEKF : Fix bug in GPS innovation variance growth calculation
The uncertainty in acceleration is currently only scaled using horizontal accelerations, however during vertical plane aerobatics and high g pullups, misalignment in angles can cause significant horizontal acceleration error.
The scaling now uses the 3D acceleration vector length to better work during vertical plane high g maneouvres.
This error was found during flight testing with 8g pullups
2014-09-27 10:34:54 +09:00
priseborough
1f1670279b AP_NavEKF : Fix bug in reset of position, height and velocity states
If the inertial solution velocity or position needs to be reset to the GPS or baro, the stored state history for the corresponding states should also be reset.
Otherwise the next GPS or baro measurement will be compared to an invalid previous state and will be rejected. This is particularly a problem if IMU saturation or timeout has occurred because the previous states could be out by a large amount
The position state should be reset to a GPS position corrected for velocity and measurement latency. This will make a noticeable difference for high speed flight vehicles, eg 11m at 50m/s.
2014-09-27 10:34:51 +09:00
Randy Mackay
20d35b4bd1 Copter: bugfix to condition-yaw for relative angles
Thanks to roque-canales for raising the issue and paradisephil for finding
the specific piece of code that went wrong and suggesting the fix.
2014-09-26 12:26:05 +09:00
Randy Mackay
eb89b53714 Copter: version to AC3.2-rc10 2014-09-24 14:29:15 +09:00
Randy Mackay
56242176da Copter: update AC3.2-rc10 release notes 2014-09-24 14:29:14 +09:00
priseborough
9c1b4e2332 AP_NavEKF : Explicitly initialise gpsNoiseScaler to default value 2014-09-24 14:29:12 +09:00
Randy Mackay
a0cb4301a1 Copter: allow passthru for ch 9 ~ 14
Based on work by Emile Castelnuovo
2014-09-24 10:28:41 +09:00
priseborough
3233416e43 AP_NavEKF : Reduce weighting on GPS when not enough satellites
GPS measurement variance is doubled if only 5 satellites, and quadrupled if 4 or less.
The GPS glitch rejection thresholds remain the same
This will reduce the impact of GPS glitches on attitude.
2014-09-23 20:39:50 +09:00
priseborough
62339c217c AP_AHRS : Prevent EKF starting if GPS sats less than AHRS_GPS_MINSATS 2014-09-23 20:39:48 +09:00
Randy Mackay
9c3379ff48 Compass: always default devid to zero 2014-09-23 20:36:54 +09:00
Randy Mackay
d66ffd5b07 Copter: use disparity threshold define for pre-arm checks
There are two duplicate checks, one in the pre-arm checks (i.e. checks
run every 15 seconds or so before the vehicle is armed) and one in the
arming checks (run immediately before arming).  The definition in the
pre-arm checks was still using the old hardcoded value.
2014-09-23 19:33:53 +09:00
Randy Mackay
5e197407b9 AC_PosControl: 4hz filter on z-axis velocity error 2014-09-22 13:41:02 +09:00
Randy Mackay
e047093013 AC_PosControl: 2hz filter on accel error
Replaced hard-coded filter with LowPassFilter class allowing the
filter's to be 2hz on both APM and Pixhawk
2014-09-22 13:40:59 +09:00
Randy Mackay
9693ee0417 LowPassFilter: add div by zero check 2014-09-22 13:40:57 +09:00
Randy Mackay
1cf7f7eaa9 Copter: increase Alt Disparity check to 2m 2014-09-20 12:27:40 +09:00
Randy Mackay
93dbfd009e Copter: rename land_maybe_complete function 2014-09-19 22:41:41 +09:00
Randy Mackay
5f909f1a73 Copter: add land_complete_maybe flag 2014-09-19 22:41:38 +09:00
Randy Mackay
7f9709300c Copter: soften loiter target when maybe landed
Applies to auto's land, land, loiter, pos hold and rtl flight modes
2014-09-19 22:41:35 +09:00
Randy Mackay
ab4b545bb5 AC_WPNav: add loiter_soften_for_landing method
This resets the position target to the current location.
2014-09-19 22:41:30 +09:00
Randy Mackay
a1ea43461a Copter: typo fix for baro vs inav alt disparity definition 2014-09-19 22:41:28 +09:00
Randy Mackay
b8c74b7363 Copter: define limit for baro vs inav alt disparity 2014-09-19 22:41:25 +09:00
Andre Kjellstrup
be2f308802 Copter: reset battery_fs after dis/rearming 2014-09-19 22:41:20 +09:00
priseborough
bf1ccba742 AP_NavEKF : Reduce sensitivity on filter divergence check
Flying aerobatics with Trad Heli has shown that the divergence check can be false triggered when large magnetometer errors and GPS dropouts are present.
This can also happen with multi rotors if large yaw rates are present.
This was an unintended consequence of the ekfsmoothing patch which improved filter stability during high rate manoeuvres, but made the divergence test more sensitive.
2014-09-16 10:37:00 +09:00
Jonathan Challinger
3993927cb7 Copter: Log NTUN while in LAND mode with GPS 2014-09-16 10:35:43 +09:00
Randy Mackay
b212c02057 Copter: version to AC3.2-Iris
Interim release 3DRobotics's use with IRIS+ frames
2014-09-12 15:06:57 +09:00
Randy Mackay
0a3ec84e86 Copter: THR_ACCEL_IMAX default to 800 2014-09-12 15:04:29 +09:00
Randy Mackay
5fd39ce436 Copter: reduce throttle to min once landed in RTL
This catches the case where the vehicle lands but the user doesn't
immediately put the throttle to zero.  Before this check it would
continue to attempt to hold it's
2014-09-12 14:55:36 +09:00
Randy Mackay
64cc4986bd Copter: THR_ACCEL_IMAX param range increased 2014-09-12 14:55:33 +09:00
Randy Mackay
75a1e46d82 Copter: version to AC3.2-rc9 2014-09-11 20:28:43 +09:00
Randy Mackay
a7233c48be Copter: AC3.2-rc9 release notes 2014-09-11 20:28:35 +09:00
Andrew Tridgell
939df78a2f HAL_VRBRAIN: fixed storage bug in VRBRAIN too 2014-09-11 20:22:12 +09:00
Andrew Tridgell
d24159204e HAL_PX4: fixed dirty_mask calculation in FRAM storage
this could lead to a number of bytes on 512 byte boundaries not being
written when changed in ram, so they would revert on next boot
2014-09-11 20:21:02 +09:00
Randy Mackay
12f3e96cc1 Copter: version to AC3.2-rc8 2014-09-11 16:36:43 +09:00
Randy Mackay
1ed11c7c37 Copter: AC3.2-rc8 release notes 2014-09-11 16:35:29 +09:00
priseborough
058fb8f3ee AP_NavEKF : Reduce ripple in estimates that can cause copter motor 'pulsing'
This patch reduces the level of 5Hz and 10Hz 'pulsing' heard in motors due to GPS and altimeter fusion which cause a small 5Hz and 10Hz ripple on the output under some conditions. Attitude, velocity and position state corrections from GPS, altimeter and magnetometer measurements are applied incrementally in the interval from receiving the measurement to the predicted time of receipt of the next measurement. Averaging of attitude state corrections is not performed during periods of rapid rotation.
2014-09-11 16:35:27 +09:00
priseborough
01536e0c80 AP_NavEKF : Clean up time stamps
Time stamps are now explicitly initialised to the current IMU time to avoid unwanted activation of timeout logic on filter start and various calls to the hal.scheduler->millis() object have been consolidated.
2014-09-11 16:35:25 +09:00
Randy Mackay
cac10a3041 Copter: never send unhealthy terrain status
Copter does not yet rely on the terrain data (it's for informational
purposes only) so we will temporarily disable the failure flags to the
GCS to avoid support calls
2014-09-09 22:20:33 +09:00
Randy Mackay
e706c24542 Copter: send extended status to GCS only after initialisation 2014-09-09 22:20:31 +09:00
Andrew Tridgell
c8e652432d DataFlash: allow use of a smaller writebuf for PX4v1
this fixes logging on PX4v1
2014-09-09 16:45:13 +09:00
Randy Mackay
0aab3a024e TradHeli: update AttControl params to match multicopters 2014-09-09 16:45:12 +09:00
Randy Mackay
4b47a618a4 Copter: reduce alt hold defaults
Throttle Rate P to 5.0 (was 6.0)
Throttle Accel P to 0.5 (was 0.75)
Throttle Accel I to 1.0 (was 1.5)
2014-09-09 16:45:11 +09:00
Randy Mackay
62a4e66481 Copter: increase EKF_CHECK_THRESH default to 0.8
Also remove unused #define related to inertial nav check (now removed)
2014-09-09 15:18:15 +09:00
Randy Mackay
faf124771a Copter: version to AC3.2-rc7 2014-09-04 15:44:10 +09:00
Randy Mackay
fe07df5562 Cotper: AC3.2-rc7 release notes 2014-09-04 15:43:36 +09:00
Randy Mackay
cdc4038f27 Copter: pre-arm consistency check of gyros 2014-09-04 15:23:56 +09:00
Randy Mackay
dbb0283dba Copter: land check gets overall throttle and rotation rate check
add check that overall throttle level is below the non-takeoff throttle
instead of just checking that it's motors have hit their lower limits
because low limits can also be caused by high yaw rotation requests.
Absolute climb rate requirement reduced to 30cm/s
2014-09-04 15:23:53 +09:00
Randy Mackay
b214b8ba15 Copter: add short delay to arming to allow RC input
The short delay gives time for the RC inputs to be processed which
removes the chance of a false-positive on the "late frame" radio check.
A false positive could lead to an immediate disarm right after arming.
2014-09-04 15:23:51 +09:00
Randy Mackay
8e7b93d1b7 Copter: pre-arm consistency check of accels 2014-09-03 13:52:58 +09:00
Randy Mackay
8b91900b74 Copter: individual accel and gyro status to GCS 2014-09-03 11:38:47 +09:00
Randy Mackay
6c0b9a2cfc Copter: check all gyros and accels in pre-arm check 2014-09-03 11:38:45 +09:00
Randy Mackay
7fc5d693c2 INS: add get_accel_health_all and get_gyro_health_all
Returns true only if all available accels or gyros are healthy
2014-09-03 11:38:42 +09:00
Randy Mackay
5ead80994e InertialSensor: reorder .cpp file to match .h
No functional changes
2014-09-03 11:38:40 +09:00
Randy Mackay
1ee6481517 Copter: sanity check throttle deadzone 2014-09-02 12:40:55 +09:00
Emile Castelnuovo
0f2083a9b8 AP_HAL: added missing CONFIG_HAL_BOARD_SUBTYPE #define for HAL_BOARD_VRBRAIN 2014-09-01 10:48:14 +09:00
Randy Mackay
162d421e5d Copter: update AC3.2-rc6 release notes
forgot compass-not-calibrated bug fix
2014-08-31 12:05:33 +09:00
Randy Mackay
7236d0621a Copter: update AC3.2-rc6 release notes
Forgot to add GPS driver buffer overflow item
2014-08-31 12:02:33 +09:00
Randy Mackay
acecc78454 Copter: version to AC3.2-rc6 2014-08-31 11:56:58 +09:00
Randy Mackay
be2dabe58e Copter: AC3.2-rc6 release notes 2014-08-31 11:56:15 +09:00
Emile Castelnuovo
938f6f2c47 Build: VRBRAIN corrected order of MAG startup for 4.5 board 2014-08-31 11:40:22 +09:00
Emile Castelnuovo
4fa8f82c59 Build: VRBRAIN corrected order of MAG startup 2014-08-31 11:40:20 +09:00
Emile Castelnuovo
e995641e48 AP_HAL_VRBRAIN: enable 2nd GPS for VRBRAIN 5 2014-08-31 11:40:17 +09:00
Emile Castelnuovo
ada7be6ae1 AP_HAL: VRBRAIN corrected EEPROM size and added terrain folder on MicroSD 2014-08-31 11:40:15 +09:00
LukeMike
f6fada2d49 VRBRAIN: added startup of internal mag's driver for VR Brain Standard 5 2014-08-31 11:40:13 +09:00
Emile Castelnuovo
781f15ba59 AP_relay: added default relay pin for VRBRAIN 2014-08-31 11:40:11 +09:00
Emile Castelnuovo
5d7a2726e2 AP_HAL_VRBRAIN: added management for external relay 1 and 2 2014-08-31 11:40:09 +09:00
Randy Mackay
15508c49ef Copter: default LAND_REPOSITION to 1 2014-08-31 11:40:06 +09:00
Jason Short
515c0d8630 Copter: restore CLI set parameter feature
Added back the ability to set params from CLI
2014-08-31 11:40:04 +09:00
Randy Mackay
68df421484 Copter: throttle deadzone parameter
Allows increasing or decreasing the deadband size in AltHold, Loiter,
PosHold flight modes
2014-08-31 10:19:03 +09:00
Randy Mackay
ff94120fbd AC_WPNav: resolve twitch when passing spline waypoints
The target positions target velocity was being reset to zero as we
passed through a spline waypoint.
2014-08-28 17:03:14 +09:00
Randy Mackay
5759a69992 Mission: start next nav cmd immediately after prev completes 2014-08-28 17:03:11 +09:00
Randy Mackay
7802c85b5f Copter: pre-arm check of internal vs ext compass 2014-08-26 22:44:20 +09:00
Randy Mackay
4038cd2fbd Copter: remote arming check reference to compass learning 2014-08-26 22:44:18 +09:00
Randy Mackay
f78aff67c2 Copter: make landing detector more strict
Made more strict by requiring 50 consecutive iterations where the climb
rate is below +- 40cm/s.  Previously it was 50 cumulative.

Removed check of failsafe.radio when clearing the land flag because it
could result in the vehicle taking off if the user picked it up.
2014-08-26 11:23:18 +09:00
Andrew Tridgell
62d526a50d AP_AHRS: use EKF use_compass() if EKF enabled
this allows magfailed status to show on console via SYS_STATUS health
bits
2014-08-26 11:23:10 +09:00
Andrew Tridgell
6a654ff461 AP_NavEKF: make use_compass() public 2014-08-26 11:23:07 +09:00
Randy Mackay
ec2308bcd2 AC_AttControl: bug fix for ef target during acro 2014-08-23 22:22:03 +09:00
Randy Mackay
d7d90b4ff8 AC_AttControl: remove debug message 2014-08-22 22:59:53 +09:00
Randy Mackay
d242fcaae5 Copter: remove get_angle_targets_for_reporting fn
this saves a tiny amount of time by removing the memory copy of a
Vector3f
2014-08-22 22:59:50 +09:00
Randy Mackay
06e06438b3 AC_AttControlHeli: integrate div-by-zero check for bf-to-ef conversion 2014-08-22 22:59:47 +09:00
Randy Mackay
91817b0884 AC_AttControl: div-by-zero check for bf-to-ef conversion 2014-08-22 22:59:43 +09:00
Andrew Tridgell
f86de61d82 Copter: show firmware version on param fetch
fixes pull #1320

thanks Arthur!
2014-08-22 21:38:16 +09:00
Andrew Tridgell
f4483203ea Rover: show firmware version on param list 2014-08-22 21:37:30 +09:00
Randy Mackay
06880f5cfa TradHeli: update AttControlHeli constructor
reference to rc_1, rc2 are replaced with constant updates during
acro_run
2014-08-22 21:37:25 +09:00
Randy Mackay
c7d6b026b5 TradHeli: call passthrough_bf_roll_pitch_rate_yaw 2014-08-22 21:37:22 +09:00
Randy Mackay
440f4ebb95 AC_AttControlHeli: add passthrough_bf_roll_pitch_rate_yaw 2014-08-22 21:37:19 +09:00
Robert Lefebvre
8ac36892ee Logging: Fix comment error. 2014-08-22 21:37:17 +09:00
Robert Lefebvre
32cb2bbce1 TradHeli: Add yaw-only rate request function for flybar acro mode. 2014-08-22 21:37:15 +09:00
Robert Lefebvre
1becab3eed TradHeli: Reset flybar passthrough to false when exiting Acro mode. 2014-08-22 21:37:12 +09:00
Robert Lefebvre
184be135cd TradHeli: Set Flybar passthrough mode in Acro Initialization function. 2014-08-22 21:37:10 +09:00
Robert Lefebvre
9326d36e54 AC_AttitudeControl_Heli: Add use_flybar_passthrough accessor function. 2014-08-22 21:37:08 +09:00
Robert Lefebvre
244d38138e AC_AttitudeControl_Heli: Add passthrough_to_motor_roll_pitch function. 2014-08-22 21:37:06 +09:00
Robert Lefebvre
ede4b567f2 TradHeli: Add pointer for pilot roll/pitch inputs to attitude_control constructor. To be used for flybar passthrough. 2014-08-22 21:37:01 +09:00
Robert Lefebvre
deaffecbf5 AC_AttitudeControl_Heli: Create Flybar Passthrough flag which will be used for control pass-through. 2014-08-22 21:36:57 +09:00
Randy Mackay
2d02d8d15f Copter: remove inav check
the EKF check works reliably but attempts to check the inertial nav for
errors has not been successful.  I could not find a way to reliably
catch flyaways without also introducing false positives (and thus
unwanted LANDings)
2014-08-20 14:49:58 +09:00
Randy Mackay
9c79f9b38d Copter: add ACRO_EXPO param values 2014-08-20 14:49:54 +09:00
Andrew Tridgell
308c90f138 HAL_VRBrain: prevent read past end of buffer 2014-08-19 11:12:33 +09:00
Andrew Tridgell
54af047b87 HAL_PX4: prevent read past end of buffer 2014-08-19 11:12:30 +09:00
Andrew Tridgell
ecd73413db Copter: set GPS non-blocking
the new GPS driver only ever needs a non-blocking port
2014-08-19 11:12:14 +09:00
Andrew Tridgell
57956dbda2 AP_GPS: moved UBX log headers to DataFlash
headers were not always being written
2014-08-19 11:09:32 +09:00
Andrew Tridgell
c395a6657a DataFlash: moved UBX logging headers to DataFlash 2014-08-19 11:09:28 +09:00
NullVoxPopuli
2183d2f4f3 Copter: add A-Tail to FRAME parameter description 2014-08-18 14:31:56 +09:00
NullVoxPopuli
86abf82cc7 Copter: Added support for V-Shaped and A-Shaped VTail Quadcopter frames
Signed-off-by: NullVoxPopuli <LPSego3+dev@gmail.com>
2014-08-18 14:31:54 +09:00
priseborough
33432aa4a8 Copter : Distinguish between EKF and INAV errors 2014-08-18 14:31:52 +09:00
Randy Mackay
a31f30e6bd Copter: range check ACRO_EXPO to be no more than 1 2014-08-18 12:58:20 +09:00
160 changed files with 6307 additions and 2799 deletions

View File

@ -4,7 +4,12 @@ before_install:
- cd .. && ./ardupilot/Tools/scripts/install-prereqs-ubuntu.sh -y && . ~/.profile
script:
- cd ./ardupilot/ArduCopter && make configure && make && make px4-v2
- cd ../ArduPlane && make configure && make && make px4-v2
- cd ../APMrover2 && make configure && make && make px4-v2
- cd ../ArduCopter && make configure && make && make vrubrain-v51
- cd ./ardupilot && Tools/scripts/build_all_travis.sh
notifications:
webhooks:
urls:
- https://webhooks.gitter.im/e/e5e0b55e353e53945b4b
on_success: change # options: [always|never|change] default: always
on_failure: always # options: [always|never|change] default: always
on_start: false # default: false

View File

@ -958,6 +958,12 @@ void GCS_MAVLINK::handleMessage(mavlink_message_t* msg)
case MAVLINK_MSG_ID_PARAM_REQUEST_LIST:
{
// mark the firmware version in the tlog
send_text_P(SEVERITY_LOW, PSTR(FIRMWARE_STRING));
#if defined(PX4_GIT_VERSION) && defined(NUTTX_GIT_VERSION)
send_text_P(SEVERITY_LOW, PSTR("PX4: " PX4_GIT_VERSION " NuttX: " NUTTX_GIT_VERSION));
#endif
handle_param_request_list(msg);
break;
}

View File

@ -19,10 +19,6 @@
*/
// uncomment the lines below to save on flash space if compiling for the APM using Arduino IDE. Top items save the most flash space
#if (CONFIG_HAL_BOARD == HAL_BOARD_APM2 || CONFIG_HAL_BOARD == HAL_BOARD_APM1)
# define CLI_ENABLED DISABLED // disable the CLI (command-line-interface) to save 21K of flash space
# define FRSKY_TELEM_ENABLED DISABLED // disable the FRSKY TELEM
#endif
//#define LOGGING_ENABLED DISABLED // disable dataflash logging to save 11K of flash space
//#define MOUNT DISABLED // disable the camera gimbal to save 8K of flash space
//#define AUTOTUNE_ENABLED DISABLED // disable the auto tune functionality to save 7k of flash
@ -34,6 +30,7 @@
// features below are disabled by default on APM (but enabled on Pixhawk)
//#define AC_RALLY ENABLED // disable rally points to save 2k of flash, and also frees rally point EEPROM for more mission commands
//#define PARACHUTE ENABLED // enable parachute release at a cost of 1k of flash
//#define CLI_ENABLED ENABLED // enable the CLI (command-line-interface) at a cost of 21K of flash space
// features below are disabled by default on all boards
//#define OPTFLOW ENABLED // enable optical flow sensor and OF_LOITER flight mode at a cost of 5K of flash space

View File

@ -110,6 +110,21 @@ void set_land_complete(bool b)
// ---------------------------------------------
// set land complete maybe flag
void set_land_complete_maybe(bool b)
{
// if no change, exit immediately
if (ap.land_complete_maybe == b)
return;
if (b) {
Log_Write_Event(DATA_LAND_COMPLETE_MAYBE);
}
ap.land_complete_maybe = b;
}
// ---------------------------------------------
void set_pre_arm_check(bool b)
{
if(ap.pre_arm_check != b) {

View File

@ -1,6 +1,6 @@
/// -*- tab-width: 4; Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*-
#define THISFIRMWARE "ArduCopter V3.2-rc5"
#define THISFIRMWARE "ArduCopter V3.2.1"
/*
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -206,6 +206,9 @@ static AP_Notify notify;
// used to detect MAVLink acks from GCS to stop compassmot
static uint8_t command_ack_counter;
// has a log download started?
static bool in_log_download;
////////////////////////////////////////////////////////////////////////////////
// prototypes
////////////////////////////////////////////////////////////////////////////////
@ -288,25 +291,7 @@ static AP_Compass_HIL compass;
AP_ADC_ADS7844 apm1_adc;
#endif
#if CONFIG_INS_TYPE == HAL_INS_MPU6000
AP_InertialSensor_MPU6000 ins;
#elif CONFIG_INS_TYPE == HAL_INS_PX4
AP_InertialSensor_PX4 ins;
#elif CONFIG_INS_TYPE == HAL_INS_VRBRAIN
AP_InertialSensor_VRBRAIN ins;
#elif CONFIG_INS_TYPE == HAL_INS_HIL
AP_InertialSensor_HIL ins;
#elif CONFIG_INS_TYPE == HAL_INS_OILPAN
AP_InertialSensor_Oilpan ins( &apm1_adc );
#elif CONFIG_INS_TYPE == HAL_INS_FLYMAPLE
AP_InertialSensor_Flymaple ins;
#elif CONFIG_INS_TYPE == HAL_INS_L3G4200D
AP_InertialSensor_L3G4200D ins;
#elif CONFIG_INS_TYPE == HAL_INS_MPU9250
AP_InertialSensor_MPU9250 ins;
#else
#error Unrecognised CONFIG_INS_TYPE setting.
#endif // CONFIG_INS_TYPE
AP_InertialSensor ins;
// Inertial Navigation EKF
#if AP_AHRS_NAVEKF_AVAILABLE
@ -388,6 +373,9 @@ static union {
uint8_t rc_receiver_present : 1; // 14 // true if we have an rc receiver present (i.e. if we've ever received an update
uint8_t compass_mot : 1; // 15 // true if we are currently performing compassmot calibration
uint8_t motor_test : 1; // 16 // true if we are currently performing the motors test
uint8_t initialised : 1; // 17 // true once the init_ardupilot function has completed. Extended status to GCS is not sent until this completes
uint8_t land_complete_maybe : 1; // 18 // true if we may have landed (less strict version of land_complete)
uint8_t throttle_zero : 1; // 19 // true if the throttle stick is at zero, debounced
};
uint32_t value;
} ap;
@ -571,8 +559,8 @@ static int16_t climb_rate;
static int16_t sonar_alt;
static uint8_t sonar_alt_health; // true if we can trust the altitude from the sonar
static float target_sonar_alt; // desired altitude in cm above the ground
// The altitude as reported by Baro in cm - Values can be quite high
static int32_t baro_alt;
static int32_t baro_alt; // barometer altitude in cm above home
static float baro_climbrate; // barometer climbrate in cm/s
////////////////////////////////////////////////////////////////////////////////
@ -795,7 +783,7 @@ static const AP_Scheduler::Task scheduler_tasks[] PROGMEM = {
{ arm_motors_check, 40, 1 },
{ auto_trim, 40, 14 },
{ update_altitude, 40, 100 },
{ run_nav_updates, 40, 80 },
{ run_nav_updates, 8, 80 },
{ update_thr_cruise, 40, 10 },
{ three_hz_loop, 133, 9 },
{ compass_accumulate, 8, 42 },
@ -805,7 +793,7 @@ static const AP_Scheduler::Task scheduler_tasks[] PROGMEM = {
#endif
{ update_notify, 8, 10 },
{ one_hz_loop, 400, 42 },
{ ekf_check, 40, 2 },
{ ekf_dcm_check, 40, 2 },
{ crash_check, 40, 2 },
{ gcs_check_input, 8, 550 },
{ gcs_send_heartbeat, 400, 150 },
@ -863,7 +851,7 @@ static const AP_Scheduler::Task scheduler_tasks[] PROGMEM = {
{ arm_motors_check, 10, 10 },
{ auto_trim, 10, 140 },
{ update_altitude, 10, 1000 },
{ run_nav_updates, 10, 800 },
{ run_nav_updates, 4, 800 },
{ update_thr_cruise, 1, 50 },
{ three_hz_loop, 33, 90 },
{ compass_accumulate, 2, 420 },
@ -873,7 +861,7 @@ static const AP_Scheduler::Task scheduler_tasks[] PROGMEM = {
#endif
{ update_notify, 2, 100 },
{ one_hz_loop, 100, 420 },
{ ekf_check, 10, 20 },
{ ekf_dcm_check, 10, 20 },
{ crash_check, 10, 20 },
{ gcs_check_input, 2, 550 },
{ gcs_send_heartbeat, 100, 150 },
@ -942,7 +930,7 @@ static void barometer_accumulate(void)
static void perf_update(void)
{
if (g.log_bitmask & MASK_LOG_PM)
if (should_log(MASK_LOG_PM))
Log_Write_Performance();
if (scheduler.debug()) {
cliSerial->printf_P(PSTR("PERF: %u/%u %lu\n"),
@ -957,10 +945,7 @@ static void perf_update(void)
void loop()
{
// wait for an INS sample
if (!ins.wait_for_sample(1000)) {
Log_Write_Error(ERROR_SUBSYSTEM_MAIN, ERROR_CODE_MAIN_INS_DELAY);
return;
}
ins.wait_for_sample();
uint32_t timer = micros();
// check loop time
@ -1089,7 +1074,7 @@ static void update_batt_compass(void)
compass.set_throttle((float)g.rc_3.servo_out/1000.0f);
compass.read();
// log compass information
if (g.log_bitmask & MASK_LOG_COMPASS) {
if (should_log(MASK_LOG_COMPASS)) {
Log_Write_Compass();
}
}
@ -1102,16 +1087,16 @@ static void update_batt_compass(void)
// should be run at 10hz
static void ten_hz_logging_loop()
{
if (g.log_bitmask & MASK_LOG_ATTITUDE_MED) {
if (should_log(MASK_LOG_ATTITUDE_MED)) {
Log_Write_Attitude();
}
if (g.log_bitmask & MASK_LOG_RCIN) {
if (should_log(MASK_LOG_RCIN)) {
DataFlash.Log_Write_RCIN();
}
if (g.log_bitmask & MASK_LOG_RCOUT) {
if (should_log(MASK_LOG_RCOUT)) {
DataFlash.Log_Write_RCOUT();
}
if ((g.log_bitmask & MASK_LOG_NTUN) && mode_requires_GPS(control_mode)) {
if (should_log(MASK_LOG_NTUN) && (mode_requires_GPS(control_mode) || landing_with_GPS())) {
Log_Write_Nav_Tuning();
}
}
@ -1126,11 +1111,11 @@ static void fifty_hz_logging_loop()
#endif
#if HIL_MODE == HIL_MODE_DISABLED
if (g.log_bitmask & MASK_LOG_ATTITUDE_FAST) {
if (should_log(MASK_LOG_ATTITUDE_FAST)) {
Log_Write_Attitude();
}
if (g.log_bitmask & MASK_LOG_IMU) {
if (should_log(MASK_LOG_IMU)) {
DataFlash.Log_Write_IMU(ins);
}
#endif
@ -1160,12 +1145,12 @@ static void three_hz_loop()
// one_hz_loop - runs at 1Hz
static void one_hz_loop()
{
if (g.log_bitmask != 0) {
if (should_log(MASK_LOG_ANY)) {
Log_Write_Data(DATA_AP_STATE, ap.value);
}
// log battery info to the dataflash
if (g.log_bitmask & MASK_LOG_CURRENT) {
if (should_log(MASK_LOG_CURRENT)) {
Log_Write_Current();
}
@ -1206,6 +1191,13 @@ static void one_hz_loop()
#if AP_TERRAIN_AVAILABLE
terrain.update();
#endif
#if AC_FENCE == ENABLED
// set fence altitude limit in position controller
if ((fence.get_enabled_fences() & AC_FENCE_TYPE_ALT_MAX) != 0) {
pos_control.set_alt_max(fence.get_safe_alt()*100.0f);
}
#endif
}
// called at 100hz but data from sensor only arrives at 20 Hz
@ -1224,7 +1216,7 @@ static void update_optical_flow(void)
of_log_counter++;
if( of_log_counter >= 4 ) {
of_log_counter = 0;
if (g.log_bitmask & MASK_LOG_OPTFLOW) {
if (should_log(MASK_LOG_OPTFLOW)) {
Log_Write_Optflow();
}
}
@ -1248,7 +1240,7 @@ static void update_GPS(void)
last_gps_reading[i] = gps.last_message_time_ms(i);
// log GPS message
if (g.log_bitmask & MASK_LOG_GPS) {
if (should_log(MASK_LOG_GPS)) {
DataFlash.Log_Write_GPS(gps, i, current_loc.alt);
}
@ -1334,7 +1326,7 @@ init_simple_bearing()
super_simple_sin_yaw = simple_sin_yaw;
// log the simple bearing to dataflash
if (g.log_bitmask != 0) {
if (should_log(MASK_LOG_ANY)) {
Log_Write_Data(DATA_INIT_SIMPLE_BEARING, ahrs.yaw_sensor);
}
}
@ -1399,13 +1391,13 @@ static void read_AHRS(void)
static void update_altitude()
{
// read in baro altitude
baro_alt = read_barometer();
read_barometer();
// read in sonar altitude
sonar_alt = read_sonar();
// write altitude info to dataflash logs
if (g.log_bitmask & MASK_LOG_CTUN) {
if (should_log(MASK_LOG_CTUN)) {
Log_Write_Control_Tuning();
}
}

View File

@ -151,8 +151,8 @@ static int16_t get_pilot_desired_throttle(int16_t throttle_control)
// get_pilot_desired_climb_rate - transform pilot's throttle input to
// climb rate in cm/s. we use radio_in instead of control_in to get the full range
// without any deadzone at the bottom
#define THROTTLE_IN_DEADBAND_TOP (THROTTLE_IN_MIDDLE+THROTTLE_IN_DEADBAND) // top of the deadband
#define THROTTLE_IN_DEADBAND_BOTTOM (THROTTLE_IN_MIDDLE-THROTTLE_IN_DEADBAND) // bottom of the deadband
#define THROTTLE_IN_DEADBAND_TOP (THROTTLE_IN_MIDDLE+g.throttle_deadzone) // top of the deadband
#define THROTTLE_IN_DEADBAND_BOTTOM (THROTTLE_IN_MIDDLE-g.throttle_deadzone) // bottom of the deadband
static int16_t get_pilot_desired_climb_rate(int16_t throttle_control)
{
int16_t desired_rate = 0;
@ -165,13 +165,16 @@ static int16_t get_pilot_desired_climb_rate(int16_t throttle_control)
// ensure a reasonable throttle value
throttle_control = constrain_int16(throttle_control,0,1000);
// ensure a reasonable deadzone
g.throttle_deadzone = constrain_int16(g.throttle_deadzone, 0, 400);
// check throttle is above, below or in the deadband
if (throttle_control < THROTTLE_IN_DEADBAND_BOTTOM) {
// below the deadband
desired_rate = (int32_t)g.pilot_velocity_z_max * (throttle_control-THROTTLE_IN_DEADBAND_BOTTOM) / (THROTTLE_IN_MIDDLE - THROTTLE_IN_DEADBAND);
desired_rate = (int32_t)g.pilot_velocity_z_max * (throttle_control-THROTTLE_IN_DEADBAND_BOTTOM) / (THROTTLE_IN_MIDDLE - g.throttle_deadzone);
}else if (throttle_control > THROTTLE_IN_DEADBAND_TOP) {
// above the deadband
desired_rate = (int32_t)g.pilot_velocity_z_max * (throttle_control-THROTTLE_IN_DEADBAND_TOP) / (THROTTLE_IN_MIDDLE - THROTTLE_IN_DEADBAND);
desired_rate = (int32_t)g.pilot_velocity_z_max * (throttle_control-THROTTLE_IN_DEADBAND_TOP) / (THROTTLE_IN_MIDDLE - g.throttle_deadzone);
}else{
// must be in the deadband
desired_rate = 0;

View File

@ -199,11 +199,14 @@ static NOINLINE void send_extended_status1(mavlink_channel_t chan)
if (ap.rc_receiver_present && !failsafe.radio) {
control_sensors_health |= MAV_SYS_STATUS_SENSOR_RC_RECEIVER;
}
if (!ins.healthy()) {
control_sensors_health &= ~(MAV_SYS_STATUS_SENSOR_3D_GYRO | MAV_SYS_STATUS_SENSOR_3D_ACCEL);
if (!ins.get_gyro_health_all() || !ins.gyro_calibrated_ok_all()) {
control_sensors_health &= ~MAV_SYS_STATUS_SENSOR_3D_GYRO;
}
if (!ins.get_accel_health_all()) {
control_sensors_health &= ~MAV_SYS_STATUS_SENSOR_3D_ACCEL;
}
if (!ahrs.healthy()) {
if (ahrs.initialised() && !ahrs.healthy()) {
// AHRS subsystem is unhealthy
control_sensors_health &= ~MAV_SYS_STATUS_AHRS;
}
@ -221,9 +224,10 @@ static NOINLINE void send_extended_status1(mavlink_channel_t chan)
case AP_Terrain::TerrainStatusDisabled:
break;
case AP_Terrain::TerrainStatusUnhealthy:
control_sensors_present |= MAV_SYS_STATUS_TERRAIN;
control_sensors_enabled |= MAV_SYS_STATUS_TERRAIN;
break;
// To-Do: restore unhealthy terrain status reporting once terrain is used in copter
//control_sensors_present |= MAV_SYS_STATUS_TERRAIN;
//control_sensors_enabled |= MAV_SYS_STATUS_TERRAIN;
//break;
case AP_Terrain::TerrainStatusOK:
control_sensors_present |= MAV_SYS_STATUS_TERRAIN;
control_sensors_enabled |= MAV_SYS_STATUS_TERRAIN;
@ -276,8 +280,7 @@ static void NOINLINE send_location(mavlink_channel_t chan)
static void NOINLINE send_nav_controller_output(mavlink_channel_t chan)
{
Vector3f targets;
get_angle_targets_for_reporting(targets);
const Vector3f &targets = attitude_control.angle_ef_targets();
mavlink_msg_nav_controller_output_send(
chan,
targets.x / 1.0e2f,
@ -479,10 +482,14 @@ bool GCS_MAVLINK::try_send_message(enum ap_message id)
break;
case MSG_EXTENDED_STATUS1:
CHECK_PAYLOAD_SIZE(SYS_STATUS);
send_extended_status1(chan);
CHECK_PAYLOAD_SIZE(POWER_STATUS);
gcs[chan-MAVLINK_COMM_0].send_power_status();
// send extended status only once vehicle has been initialised
// to avoid unnecessary errors being reported to user
if (ap.initialised) {
CHECK_PAYLOAD_SIZE(SYS_STATUS);
send_extended_status1(chan);
CHECK_PAYLOAD_SIZE(POWER_STATUS);
gcs[chan-MAVLINK_COMM_0].send_power_status();
}
break;
case MSG_EXTENDED_STATUS2:
@ -877,6 +884,11 @@ void GCS_MAVLINK::handleMessage(mavlink_message_t* msg)
mavlink_set_mode_t packet;
mavlink_msg_set_mode_decode(msg, &packet);
// exit immediately if this command is not meant for this vehicle
if (mavlink_check_target(packet.target_system, 0)) {
break;
}
// only accept custom modes because there is no easy mapping from Mavlink flight modes to AC flight modes
if (packet.base_mode & MAV_MODE_FLAG_CUSTOM_MODE_ENABLED) {
if (set_mode(packet.custom_mode)) {
@ -897,6 +909,13 @@ void GCS_MAVLINK::handleMessage(mavlink_message_t* msg)
case MAVLINK_MSG_ID_PARAM_REQUEST_LIST: // MAV ID: 21
{
// mark the firmware version in the tlog
send_text_P(SEVERITY_LOW, PSTR(FIRMWARE_STRING));
#if defined(PX4_GIT_VERSION) && defined(NUTTX_GIT_VERSION)
send_text_P(SEVERITY_LOW, PSTR("PX4: " PX4_GIT_VERSION " NuttX: " NUTTX_GIT_VERSION));
#endif
send_text_P(SEVERITY_LOW, PSTR("Frame: " FRAME_CONFIG_STRING));
handle_param_request_list(msg);
break;
}
@ -1044,12 +1063,12 @@ void GCS_MAVLINK::handleMessage(mavlink_message_t* msg)
case MAV_CMD_CONDITION_YAW:
// param1 : target angle [0-360]
// param2 : speed during change [deg per second]
// param3 : direction (not supported)
// param3 : direction (-1:ccw, +1:cw)
// param4 : relative offset (1) or absolute angle (0)
if ((packet.param1 >= 0.0f) &&
(packet.param1 <= 360.0f) &&
((packet.param4 == 0) || (packet.param4 == 1))) {
set_auto_yaw_look_at_heading(packet.param1, packet.param2, (uint8_t)packet.param4);
set_auto_yaw_look_at_heading(packet.param1, packet.param2, (int8_t)packet.param3, (uint8_t)packet.param4);
result = MAV_RESULT_ACCEPTED;
} else {
result = MAV_RESULT_FAILED;
@ -1091,10 +1110,11 @@ void GCS_MAVLINK::handleMessage(mavlink_message_t* msg)
break;
case MAV_CMD_PREFLIGHT_CALIBRATION:
if (packet.param1 == 1 ||
packet.param2 == 1) {
ins.init_accel();
ahrs.set_trim(Vector3f(0,0,0)); // clear out saved trim
if (packet.param1 == 1) {
// gyro offset calibration
ins.init_gyro();
// reset ahrs gyro bias
ahrs.reset_gyro_drift();
result = MAV_RESULT_ACCEPTED;
}
if (packet.param3 == 1) {
@ -1138,14 +1158,18 @@ void GCS_MAVLINK::handleMessage(mavlink_message_t* msg)
if (packet.param1 == 1.0f) {
// run pre_arm_checks and arm_checks and display failures
pre_arm_checks(true);
if(ap.pre_arm_check && arm_checks(true)) {
init_arm_motors();
if(ap.pre_arm_check && arm_checks(true, true)) {
if (init_arm_motors()) {
result = MAV_RESULT_ACCEPTED;
} else {
AP_Notify::flags.arming_failed = true; // init_arm_motors function will reset flag back to false
result = MAV_RESULT_UNSUPPORTED;
}
}else{
AP_Notify::flags.arming_failed = true; // init_arm_motors function will reset flag back to false
result = MAV_RESULT_UNSUPPORTED;
}
} else if (packet.param1 == 0.0f) {
} else if (packet.param1 == 0.0f && (manual_flight_mode(control_mode) || ap.land_complete)) {
init_disarm_motors();
result = MAV_RESULT_ACCEPTED;
} else {
@ -1279,11 +1303,21 @@ void GCS_MAVLINK::handleMessage(mavlink_message_t* msg)
case MAVLINK_MSG_ID_RADIO:
case MAVLINK_MSG_ID_RADIO_STATUS: // MAV ID: 109
{
handle_radio_status(msg, DataFlash, (g.log_bitmask & MASK_LOG_PM) != 0);
handle_radio_status(msg, DataFlash, should_log(MASK_LOG_PM));
break;
}
case MAVLINK_MSG_ID_LOG_REQUEST_LIST ... MAVLINK_MSG_ID_LOG_REQUEST_END: // MAV ID: 117 ... 122
case MAVLINK_MSG_ID_LOG_REQUEST_DATA:
case MAVLINK_MSG_ID_LOG_ERASE:
in_log_download = true;
// fallthru
case MAVLINK_MSG_ID_LOG_REQUEST_LIST:
if (!in_mavlink_delay && !motors.armed()) {
handle_log_message(msg, DataFlash);
}
break;
case MAVLINK_MSG_ID_LOG_REQUEST_END:
in_log_download = false;
if (!in_mavlink_delay && !motors.armed()) {
handle_log_message(msg, DataFlash);
}

View File

@ -173,7 +173,7 @@ struct PACKED log_AutoTune {
float new_gain_sp; // newly calculated gain
};
// Write an Current data packet
// Write an Autotune data packet
static void Log_Write_AutoTune(uint8_t axis, uint8_t tune_step, float rate_min, float rate_max, float new_gain_rp, float new_gain_rd, float new_gain_sp)
{
struct log_AutoTune pkt = {
@ -195,7 +195,7 @@ struct PACKED log_AutoTuneDetails {
float rate_cds; // current rotation rate in centi-degrees / second
};
// Write an Current data packet
// Write an Autotune data packet
static void Log_Write_AutoTuneDetails(int16_t angle_cd, float rate_cds)
{
struct log_AutoTuneDetails pkt = {
@ -464,13 +464,14 @@ struct PACKED log_Attitude {
int16_t pitch;
uint16_t control_yaw;
uint16_t yaw;
uint16_t error_rp;
uint16_t error_yaw;
};
// Write an attitude packet
static void Log_Write_Attitude()
{
Vector3f targets;
get_angle_targets_for_reporting(targets);
const Vector3f &targets = attitude_control.angle_ef_targets();
struct log_Attitude pkt = {
LOG_PACKET_HEADER_INIT(LOG_ATTITUDE_MSG),
time_ms : hal.scheduler->millis(),
@ -479,7 +480,9 @@ static void Log_Write_Attitude()
control_pitch : (int16_t)targets.y,
pitch : (int16_t)ahrs.pitch_sensor,
control_yaw : (uint16_t)targets.z,
yaw : (uint16_t)ahrs.yaw_sensor
yaw : (uint16_t)ahrs.yaw_sensor,
error_rp : (uint16_t)(ahrs.get_error_rp() * 100),
error_yaw : (uint16_t)(ahrs.get_error_yaw() * 100)
};
DataFlash.WriteBlock(&pkt, sizeof(pkt));
@ -530,7 +533,7 @@ struct PACKED log_Event {
// Wrote an event packet
static void Log_Write_Event(uint8_t id)
{
if (g.log_bitmask != 0) {
if (should_log(MASK_LOG_ANY)) {
struct log_Event pkt = {
LOG_PACKET_HEADER_INIT(LOG_EVENT_MSG),
id : id
@ -548,7 +551,7 @@ struct PACKED log_Data_Int16t {
// Write an int16_t data packet
static void Log_Write_Data(uint8_t id, int16_t value)
{
if (g.log_bitmask != 0) {
if (should_log(MASK_LOG_ANY)) {
struct log_Data_Int16t pkt = {
LOG_PACKET_HEADER_INIT(LOG_DATA_INT16_MSG),
id : id,
@ -567,7 +570,7 @@ struct PACKED log_Data_UInt16t {
// Write an uint16_t data packet
static void Log_Write_Data(uint8_t id, uint16_t value)
{
if (g.log_bitmask != 0) {
if (should_log(MASK_LOG_ANY)) {
struct log_Data_UInt16t pkt = {
LOG_PACKET_HEADER_INIT(LOG_DATA_UINT16_MSG),
id : id,
@ -586,7 +589,7 @@ struct PACKED log_Data_Int32t {
// Write an int32_t data packet
static void Log_Write_Data(uint8_t id, int32_t value)
{
if (g.log_bitmask != 0) {
if (should_log(MASK_LOG_ANY)) {
struct log_Data_Int32t pkt = {
LOG_PACKET_HEADER_INIT(LOG_DATA_INT32_MSG),
id : id,
@ -605,7 +608,7 @@ struct PACKED log_Data_UInt32t {
// Write a uint32_t data packet
static void Log_Write_Data(uint8_t id, uint32_t value)
{
if (g.log_bitmask != 0) {
if (should_log(MASK_LOG_ANY)) {
struct log_Data_UInt32t pkt = {
LOG_PACKET_HEADER_INIT(LOG_DATA_UINT32_MSG),
id : id,
@ -624,7 +627,7 @@ struct PACKED log_Data_Float {
// Write a float data packet
static void Log_Write_Data(uint8_t id, float value)
{
if (g.log_bitmask != 0) {
if (should_log(MASK_LOG_ANY)) {
struct log_Data_Float pkt = {
LOG_PACKET_HEADER_INIT(LOG_DATA_FLOAT_MSG),
id : id,
@ -685,7 +688,7 @@ static const struct LogStructure log_structure[] PROGMEM = {
{ LOG_PERFORMANCE_MSG, sizeof(log_Performance),
"PM", "HHIhBHB", "NLon,NLoop,MaxT,PMT,I2CErr,INSErr,INAVErr" },
{ LOG_ATTITUDE_MSG, sizeof(log_Attitude),
"ATT", "IccccCC", "TimeMS,DesRoll,Roll,DesPitch,Pitch,DesYaw,Yaw" },
"ATT", "IccccCCCC", "TimeMS,DesRoll,Roll,DesPitch,Pitch,DesYaw,Yaw,ErrRP,ErrYaw" },
{ LOG_MODE_MSG, sizeof(log_Mode),
"MODE", "Mh", "Mode,ThrCrs" },
{ LOG_STARTUP_MSG, sizeof(log_Startup),
@ -715,7 +718,8 @@ static void Log_Read(uint16_t log_num, uint16_t start_page, uint16_t end_page)
#endif
cliSerial->printf_P(PSTR("\n" FIRMWARE_STRING
"\nFree RAM: %u\n"),
"\nFree RAM: %u\n"
"\nFrame: " FRAME_CONFIG_STRING "\n"),
(unsigned) hal.util->available_memory());
cliSerial->println_P(PSTR(HAL_BOARD_NAME));
@ -746,6 +750,7 @@ static void start_logging()
if (hal.util->get_system_id(sysid)) {
DataFlash.Log_Write_Message(sysid);
}
DataFlash.Log_Write_Message_P(PSTR("Frame: " FRAME_CONFIG_STRING));
// log the flight mode
Log_Write_Mode(control_mode);

View File

@ -81,7 +81,7 @@ public:
// Misc
//
k_param_log_bitmask = 20,
k_param_log_bitmask_old = 20, // Deprecated
k_param_log_last_filenumber, // *** Deprecated - remove
// with next eeprom number
// change
@ -119,7 +119,11 @@ public:
k_param_sonar, // sonar object
k_param_ekfcheck_thresh,
k_param_terrain,
k_param_acro_expo, // 56
k_param_acro_expo,
k_param_throttle_deadzone,
k_param_optflow,
k_param_dcmcheck_thresh, // 59
k_param_log_bitmask,
// 65: AP_Limits Library
k_param_limits = 65, // deprecated - remove
@ -365,6 +369,7 @@ public:
AP_Int16 failsafe_throttle_value;
AP_Int16 throttle_cruise;
AP_Int16 throttle_mid;
AP_Int16 throttle_deadzone;
// Flight modes
//
@ -378,7 +383,7 @@ public:
// Misc
//
AP_Int16 log_bitmask;
AP_Int32 log_bitmask;
AP_Int8 esc_calibrate;
AP_Int8 radio_tuning;
AP_Int16 radio_tuning_high;
@ -390,6 +395,7 @@ public:
AP_Int8 land_repositioning;
AP_Float ekfcheck_thresh;
AP_Float dcmcheck_thresh;
#if FRAME_CONFIG == HELI_FRAME
// Heli

View File

@ -295,6 +295,15 @@ const AP_Param::Info var_info[] PROGMEM = {
// @Increment: 1
GSCALAR(throttle_mid, "THR_MID", THR_MID_DEFAULT),
// @Param: THR_DZ
// @DisplayName: Throttle deadzone
// @Description: The deadzone above and below mid throttle. Used in AltHold, Loiter, PosHold flight modes
// @User: Standard
// @Range: 0 300
// @Units: pwm
// @Increment: 1
GSCALAR(throttle_deadzone, "THR_DZ", THR_DZ_DEFAULT),
// @Param: FLTMODE1
// @DisplayName: Flight Mode 1
// @Description: Flight mode when Channel 5 pwm is <= 1230
@ -345,8 +354,8 @@ const AP_Param::Info var_info[] PROGMEM = {
// @Param: LOG_BITMASK
// @DisplayName: Log bitmask
// @Description: 2 byte bitmap of log types to enable
// @Values: 830:Default,894:Default+RCIN,958:Default+IMU,1854:Default+Motors,-6146:NearlyAll,0:Disabled
// @Description: 4 byte bitmap of log types to enable
// @Values: 830:Default,894:Default+RCIN,958:Default+IMU,1854:Default+Motors,-6146:NearlyAll-AC315,43006:NearlyAll,131070:All+DisarmedLogging,0:Disabled
// @User: Standard
GSCALAR(log_bitmask, "LOG_BITMASK", DEFAULT_LOG_BITMASK),
@ -381,7 +390,7 @@ const AP_Param::Info var_info[] PROGMEM = {
// @Param: FRAME
// @DisplayName: Frame Orientation (+, X or V)
// @Description: Controls motor mixing for multicopters. Not used for Tri or Traditional Helicopters.
// @Values: 0:Plus, 1:X, 2:V, 3:H, 4:V-Tail, 10:Y6B (New)
// @Values: 0:Plus, 1:X, 2:V, 3:H, 4:V-Tail, 5:A-Tail, 10:Y6B (New)
// @User: Standard
GSCALAR(frame_orientation, "FRAME", AP_MOTORS_X_FRAME),
@ -447,12 +456,19 @@ const AP_Param::Info var_info[] PROGMEM = {
GSCALAR(land_repositioning, "LAND_REPOSITION", LAND_REPOSITION_DEFAULT),
// @Param: EKF_CHECK_THRESH
// @DisplayName: EKF and InertialNav check compass and velocity variance threshold
// @DisplayName: EKF check compass and velocity variance threshold
// @Description: Allows setting the maximum acceptable compass and velocity variance (0 to disable check)
// @Values: 0:Disabled, 0.6:Default, 1.0:Relaxed
// @User: Advanced
GSCALAR(ekfcheck_thresh, "EKF_CHECK_THRESH", EKFCHECK_THRESHOLD_DEFAULT),
// @Param: DCM_CHECK_THRESH
// @DisplayName: DCM yaw error threshold
// @Description: Allows setting the maximum acceptable yaw error as a sin of the yaw error (0 to disable check)
// @Values: 0:Disabled, 0.8:Default, 0.98:Relaxed
// @User: Advanced
GSCALAR(dcmcheck_thresh, "DCM_CHECK_THRESH", DCMCHECK_THRESHOLD_DEFAULT),
#if FRAME_CONFIG == HELI_FRAME
// @Group: HS1_
// @Path: ../libraries/RC_Channel/RC_Channel.cpp
@ -589,7 +605,7 @@ const AP_Param::Info var_info[] PROGMEM = {
// @Param: ACRO_EXPO
// @DisplayName: Acro Expo
// @Description: Acro roll/pitch Expo to allow faster rotation when stick at edges
// @Values: 0:Disabled,0.2:Low,0.3:Medium,0.4:High
// @Values: 0:Disabled,0.1:Very Low,0.2:Low,0.3:Medium,0.4:High,0.5:Very High
// @User: Advanced
GSCALAR(acro_expo, "ACRO_EXPO", ACRO_EXPO_DEFAULT),
@ -799,7 +815,7 @@ const AP_Param::Info var_info[] PROGMEM = {
// @Param: THR_ACCEL_IMAX
// @DisplayName: Throttle acceleration controller I gain maximum
// @Description: Throttle acceleration controller I gain maximum. Constrains the maximum pwm that the I term will generate
// @Range: 0 500
// @Range: 0 1000
// @Units: Percent*10
// @User: Standard
@ -993,7 +1009,7 @@ const AP_Param::Info var_info[] PROGMEM = {
// @Group: BRD_
// @Path: ../libraries/AP_BoardConfig/AP_BoardConfig.cpp
GOBJECT(BoardConfig, "BRD_", AP_BoardConfig),
GOBJECT(BoardConfig, "BRD_", AP_BoardConfig),
#if SPRAYER == ENABLED
// @Group: SPRAY_
@ -1126,12 +1142,13 @@ const AP_Param::ConversionInfo conversion_table[] PROGMEM = {
{ Parameters::k_param_volt_div_ratio, 0, AP_PARAM_FLOAT, "BATT_VOLT_MULT" },
{ Parameters::k_param_curr_amp_per_volt, 0, AP_PARAM_FLOAT, "BATT_AMP_PERVOLT" },
{ Parameters::k_param_pack_capacity, 0, AP_PARAM_INT32, "BATT_CAPACITY" },
{ Parameters::k_param_log_bitmask_old, 0, AP_PARAM_INT16, "LOG_BITMASK" },
};
static void load_parameters(void)
{
if (!AP_Param::check_var_info()) {
cliSerial->printf_P(PSTR("Bad var table\n"));
cliSerial->printf_P(PSTR("Bad var table\n"));
hal.scheduler->panic(PSTR("Bad var table"));
}

View File

@ -1,5 +1,125 @@
ArduCopter Release Notes:
------------------------------------------------------------------
ArduCopter 3.2.1 11-Feb-2015 / 3.2.1-rc2 30-Jan-2015
Changes from 3.2.1-rc1
1) Bug Fixes:
a) prevent infinite loop with linked jump commands
b) Pixhawk memory corruption fix when connecting via USB
c) vehicle stops at fence altitude limit in Loiter, AltHold, PosHold
d) protect against multiple arming messages from GCS causing silent gyro calibration failure
------------------------------------------------------------------
ArduCopter 3.2.1-rc1 08-Jan-2015
Changes from 3.2
1) Enhancements:
a) reduced twitch when passing Spline waypoints
b) Faster disarm after landing in Auto, Land, RTL
c) Pixhawk LED turns green before arming only after GPS HDOP falls below 2.3 (only in flight modes requiring GPS)
2) Safety Features:
a) Add desired descent rate check to reduce chance of false-positive on landing check
b) improved MPU6k health monitoring and re-configuration in case of in-flight failure
c) Rally point distance check reduced to 300m (reduces chance of RTL to far away forgotten Rally point)
d) auto-disarm if vehicle is landed for 15seconds even in Auto, Guided, RTL, Circle
e) fence breach while vehicle is landed causes vehicle to disarm (previously did RTL)
3) Bug Fixes:
a) Check flight mode even when arming from GCS (previously it was possible to arm in RTL mode if arming was initiated from GCS)
b) Send vehicle target destination in RTL, Guided (allows GCS to show where vehicle is flying to in these modes)
c) PosHold wind compensation fix
------------------------------------------------------------------
ArduCopter 3.2 07-Nov2014 / 3.2-rc14 31-Oct-2014
Changes from 3.2-rc13
1) Safety Features:
a) fail to arm if second gyro calibration fails (can be disabled with ARMING_CHECK)
2) Bug fixes:
a) DCM-check to require one continuous second of bad heading before triggering LAND
b) I2C bug that could lead to Pixhawk freezing up if I2C bus is noisy
c) reset DCM and EKF gyro bias estimates after gyro calibration (DCM heading could drift after takeoff due to sudden change in gyro values)
d) use primary GPS for LED status (instead of always using first GPS)
------------------------------------------------------------------
ArduCopter 3.2-rc13 23-Oct-2014
Changes from 3.2-rc12
1) DCM check triggers LAND if yaw disagrees with GPS by > 60deg (configure with DCM_CHECK_THRESH param) and in Loiter, PosHold, Auto, etc
2) Safety features:
a) landing detector checks baro climbrate between -1.5 ~ +1.5 m/s
b) sanity check AHRS_RP_P and AHRS_YAW_P are never less than 0.05
c) check set-mode requests from GCS are for this vehicle
3) Bug fixes:
a) fix ch6 tuning of wp-speed (was getting stuck at zero)
b) parachute servo set to off position on startup
c) Auto Takeoff timing bug fix that could cause severe lean on takeoff
d) timer fix for "slow start" of motors on Pixhawk (timer was incorrectly based on 100hz APM2 main loop speed)
4) reduced number of relays from 4 to 2 (saves memory and flash required on APM boards)
5) reduced number of range finders from 2 to 1 (saves memory and flash on APM boards)
6) allow logging from startup when LOG_BITMASK set to "All+DisarmedLogging"
------------------------------------------------------------------
ArduCopter 3.2-rc12 10-Oct-2014
Changes from 3.2-rc11
1) disable sonar on APM1 and TradHeli (APM1 & APM2) to allow code to fit
2) Add pre-arm and health check that gyro calibration succeeded
3) Bug fix to EKF reporting invalid position and velocity when switched on in flight with Ch7/Ch8 switch
------------------------------------------------------------------
ArduCopter 3.2-rc11 06-Oct-2014
Changes from 3.2-rc10
1) reduce lean on take-off in Auto by resetting horizontal position targets
2) TradHeli landing check ignores overall throttle output
3) reduce AHRS bad messages by delaying 20sec after init to allow EKF to settle (Pixhawk only)
4) Bug fixes:
a) fix THR_MIN scaling issue that could cause landing-detector to fail to detect landing when ch3 min~max > 1000 pwm
b) fix Mediatek GPS configuration so update rate is set correctly to 5hz
c) fix to Condition-Yaw mission command to support relative angles
d) EKF bug fixes when recovering from GPS glitches (affects only Pixhawks using EKF)
------------------------------------------------------------------
ArduCopter 3.2-rc10 24-Sep-2014
Changes from 3.2-rc9
1) two-stage land-detector to reduce motor run-up when landing in Loiter, PosHold, RTL, Auto
2) Allow passthrough from input to output of channels 9 ~ 14 (thanks Emile!)
3) Add 4hz filter to vertical velocity error during AltHold
4) Safety Feature:
a) increase Alt Disparity pre-arm check threshold to 2m (was 1m)
b) reset battery failsafe after disarming/arming (thanks AndKe!)
c) EKF only apply centrifugal corrections when GPS has at least 6 satellites (Pixhawk with EKF enabled only)
5) Bug fixes:
a) to default compass devid to zero when no compass connected
b) reduce motor run-up while landing in RTL
------------------------------------------------------------------
ArduCopter 3.2-rc9 11-Sep-2014
Changes from 3.2-rc8
1) FRAM bug fix that could stop Mission or Parameter changes from being saved (Pixhawk, VRBrain only)
------------------------------------------------------------------
ArduCopter 3.2-rc8 11-Sep-2014
Changes from 3.2-rc7
1) EKF reduced ripple to resolve copter motor pulsing
2) Default Param changes:
a) AltHold Rate P reduced from 6 to 5
b) AltHold Accel P reduced from 0.75 to 0.5, I from 1.5 to 1.0
c) EKF check threshold increased from 0.6 to 0.8 to reduce false positives
3) sensor health flags sent to GCS only after initialisation to remove false alerts
4) suppress bad terrain data alerts
5) Bug Fix:
a)PX4 dataflash RAM useage reduced to 8k so it works again
------------------------------------------------------------------
ArduCopter 3.2-rc7 04-Sep-2014
Changes from 3.2-rc6
1) Safety Items:
a) Landing check made more strict (climb rate requirement reduced to 30cm/s, overall throttle < 25%, rotation < 20deg/sec)
b) pre-arm check that accels are consistent (Pixhawk only, must be within 1m/sec/sec of each other)
c) pre-arm check that gyros are consistent (Pixhawk only, must be within 20deg/sec of each other)
d) report health of all accels and gyros (not just primary) to ground station
------------------------------------------------------------------
ArduCopter 3.2-rc6 31-Aug-2014
Changes from 3.2-rc5
1) Spline twitch when passing through a waypoint largely resolved
2) THR_DZ param added to allow user configuration of throttle deadzone during AltHold, Loiter, PosHold
3) Landing check made more strict (climb rate must be -40~40cm/s for 1 full second)
4) LAND_REPOSITION param default set to 1
5) TradHeli with flybar passes through pilot inputs directly to swash when in ACRO mode
6) Safety Items:
a) EKF check disabled when using inertial nav (caused too many false positives)
b) pre-arm check of internal vs external compass direction (must be within 45deg of each other)
7) Bug Fixes:
a) resolve NaN in angle targets when vehicle hits gimbal lock in ACRO mode
b) resolve GPS driver buffer overflow that could lead to missed GPS messages on Pixhawk/PX4 boards
c) resolve false "compass not calibrated" warnings on Pixhawk/PX4 caused by missing device id initialisation
------------------------------------------------------------------
ArduCopter 3.2-rc5 15-Aug-2014
Changes from 3.2-rc4
1) Pixhawk's max num waypoints increased to 718

View File

@ -14,7 +14,7 @@ static void init_home()
inertial_nav.setup_home_position();
// log new home position which mission library will pull from ahrs
if (g.log_bitmask & MASK_LOG_CMD) {
if (should_log(MASK_LOG_CMD)) {
AP_Mission::Mission_Command temp_cmd;
if (mission.read_cmd_from_storage(0, temp_cmd)) {
Log_Write_Cmd(temp_cmd);

View File

@ -33,7 +33,7 @@ static void auto_spline_start(const Vector3f& destination, bool stopped_at_start
static bool start_command(const AP_Mission::Mission_Command& cmd)
{
// To-Do: logging when new commands start/end
if (g.log_bitmask & MASK_LOG_CMD) {
if (should_log(MASK_LOG_CMD)) {
Log_Write_Cmd(cmd);
}
@ -151,16 +151,6 @@ static bool start_command(const AP_Mission::Mission_Command& cmd)
break;
#endif
#if MOUNT == ENABLED
case MAV_CMD_DO_MOUNT_CONFIGURE: // Mission command to configure a camera mount |Mount operation mode (see MAV_CONFIGURE_MOUNT_MODE enum)| stabilize roll? (1 = yes, 0 = no)| stabilize pitch? (1 = yes, 0 = no)| stabilize yaw? (1 = yes, 0 = no)| Empty| Empty| Empty|
camera_mount.configure_cmd();
break;
case MAV_CMD_DO_MOUNT_CONTROL: // Mission command to control a camera mount |pitch(deg*100) or lat, depending on mount mode.| roll(deg*100) or lon depending on mount mode| yaw(deg*100) or alt (in cm) depending on mount mode| Empty| Empty| Empty| Empty|
camera_mount.control_cmd();
break;
#endif
#if PARACHUTE == ENABLED
case MAV_CMD_DO_PARACHUTE: // Mission command to configure or release parachute
do_parachute(cmd);
@ -275,7 +265,7 @@ static void exit_mission()
}else{
#if LAND_REQUIRE_MIN_THROTTLE_TO_DISARM == ENABLED
// disarm when the landing detector says we've landed and throttle is at minimum
if (g.rc_3.control_in == 0 || failsafe.radio) {
if (ap.throttle_zero || failsafe.radio) {
init_disarm_motors();
}
#else
@ -782,6 +772,7 @@ static void do_yaw(const AP_Mission::Mission_Command& cmd)
set_auto_yaw_look_at_heading(
cmd.content.yaw.angle_deg,
cmd.content.yaw.turn_rate_dps,
cmd.content.yaw.direction,
cmd.content.yaw.relative_angle);
}
@ -913,7 +904,7 @@ static void do_take_picture()
{
#if CAMERA == ENABLED
camera.trigger_pic();
if (g.log_bitmask & MASK_LOG_CAMERA) {
if (should_log(MASK_LOG_CAMERA)) {
DataFlash.Log_Write_Camera(ahrs, gps, current_loc);
}
#endif

View File

@ -84,6 +84,13 @@
#if HAL_CPU_CLASS < HAL_CPU_CLASS_75
# define PARACHUTE DISABLED
# define AC_RALLY DISABLED
# define CLI_ENABLED DISABLED
# define FRSKY_TELEM_ENABLED DISABLED
#endif
// disable sonar on APM1 and TradHeli/APM2
#if (CONFIG_HAL_BOARD == HAL_BOARD_APM1 || (CONFIG_HAL_BOARD == HAL_BOARD_APM2 && FRAME_CONFIG == HELI_FRAME))
# define CONFIG_SONAR DISABLED
#endif
#if HAL_CPU_CLASS < HAL_CPU_CLASS_75 || CONFIG_HAL_BOARD == HAL_BOARD_AVR_SITL
@ -110,6 +117,28 @@
# define FRAME_CONFIG QUAD_FRAME
#endif
#if FRAME_CONFIG == QUAD_FRAME
# define FRAME_CONFIG_STRING "QUAD"
#elif FRAME_CONFIG == TRI_FRAME
# define FRAME_CONFIG_STRING "TRI"
#elif FRAME_CONFIG == HEXA_FRAME
# define FRAME_CONFIG_STRING "HEXA"
#elif FRAME_CONFIG == Y6_FRAME
# define FRAME_CONFIG_STRING "Y6"
#elif FRAME_CONFIG == OCTA_FRAME
# define FRAME_CONFIG_STRING "OCTA"
#elif FRAME_CONFIG == OCTA_QUAD_FRAME
# define FRAME_CONFIG_STRING "OCTA_QUAD"
#elif FRAME_CONFIG == HELI_FRAME
# define FRAME_CONFIG_STRING "HELI"
#elif FRAME_CONFIG == SINGLE_FRAME
# define FRAME_CONFIG_STRING "SINGLE"
#elif FRAME_CONFIG == COAX_FRAME
# define FRAME_CONFIG_STRING "COAX"
#else
# define FRAME_CONFIG_STRING "UNKNOWN"
#endif
/////////////////////////////////////////////////////////////////////////////////
// TradHeli defaults
#if FRAME_CONFIG == HELI_FRAME
@ -273,7 +302,7 @@
# define FAILSAFE_GPS_TIMEOUT_MS 5000 // gps failsafe triggers after 5 seconds with no GPS
#endif
#ifndef GPS_HDOP_GOOD_DEFAULT
# define GPS_HDOP_GOOD_DEFAULT 200 // minimum hdop that represents a good position. used during pre-arm checks if fence is enabled
# define GPS_HDOP_GOOD_DEFAULT 230 // minimum hdop that represents a good position. used during pre-arm checks if fence is enabled
#endif
// GCS failsafe
@ -299,15 +328,33 @@
#define FS_GCS_ENABLED_ALWAYS_RTL 1
#define FS_GCS_ENABLED_CONTINUE_MISSION 2
// pre-arm baro vs inertial nav max alt disparity
#ifndef PREARM_MAX_ALT_DISPARITY_CM
# define PREARM_MAX_ALT_DISPARITY_CM 200 // barometer and inertial nav altitude must be within this many centimeters
#endif
// pre-arm check max velocity
#ifndef PREARM_MAX_VELOCITY_CMS
# define PREARM_MAX_VELOCITY_CMS 50.0f // vehicle must be travelling under 50cm/s before arming
#endif
// arming check's maximum acceptable accelerometer vector difference (in m/s/s) between primary and backup accelerometers
#ifndef PREARM_MAX_ACCEL_VECTOR_DIFF
#define PREARM_MAX_ACCEL_VECTOR_DIFF 1.0f // pre arm accel check will fail if primary and backup accelerometer vectors differ by 1m/s/s
#endif
// arming check's maximum acceptable rotation rate difference (in rad/sec) between primary and backup gyros
#ifndef PREARM_MAX_GYRO_VECTOR_DIFF
#define PREARM_MAX_GYRO_VECTOR_DIFF 0.35f // pre arm gyro check will fail if primary and backup gyro vectors differ by 0.35 rad/sec (=20deg/sec)
#endif
//////////////////////////////////////////////////////////////////////////////
// EKF Checker
// EKF & DCM Checker
#ifndef EKFCHECK_THRESHOLD_DEFAULT
# define EKFCHECK_THRESHOLD_DEFAULT 0.6f // EKF checker's default compass and velocity variance above which the EKF's horizontal position will be considered bad
# define EKFCHECK_THRESHOLD_DEFAULT 0.8f // EKF checker's default compass and velocity variance above which the EKF's horizontal position will be considered bad
#endif
#ifndef DCMCHECK_THRESHOLD_DEFAULT
# define DCMCHECK_THRESHOLD_DEFAULT 0.8f // DCM checker's default yaw error threshold above which we will abandon horizontal position hold. The units are sin(angle) so 0.8 = about 60degrees of error
#endif
//////////////////////////////////////////////////////////////////////////////
@ -338,6 +385,11 @@
#endif
#endif
// arming check's maximum acceptable vector difference between internal and external compass after vectors are normalized to field length of 1.0
#ifndef COMPASS_ACCEPTABLE_VECTOR_DIFF
#define COMPASS_ACCEPTABLE_VECTOR_DIFF 0.75 // pre arm compass check will fail if internal vs external compass direction differ by more than 45 degrees
#endif
//////////////////////////////////////////////////////////////////////////////
// OPTICAL_FLOW
#ifndef OPTFLOW // sets global enabled/disabled flag for optflow (as seen in CLI)
@ -442,11 +494,26 @@
#ifndef LAND_DETECTOR_TRIGGER
# define LAND_DETECTOR_TRIGGER 50 // number of 50hz iterations with near zero climb rate and low throttle that triggers landing complete.
#endif
#ifndef LAND_DETECTOR_MAYBE_TRIGGER
# define LAND_DETECTOR_MAYBE_TRIGGER 10 // number of 50hz iterations with near zero climb rate and low throttle that means we might be landed (used to reset horizontal position targets to prevent tipping over)
#endif
#ifndef LAND_DETECTOR_CLIMBRATE_MAX
# define LAND_DETECTOR_CLIMBRATE_MAX 30 // vehicle climb rate must be between -30 and +30 cm/s
#endif
#ifndef LAND_DETECTOR_BARO_CLIMBRATE_MAX
# define LAND_DETECTOR_BARO_CLIMBRATE_MAX 150 // barometer climb rate must be between -150cm/s ~ +150cm/s
#endif
#ifndef LAND_DETECTOR_DESIRED_CLIMBRATE_MAX
# define LAND_DETECTOR_DESIRED_CLIMBRATE_MAX -20 // vehicle desired climb rate must be below -20cm/s
#endif
#ifndef LAND_DETECTOR_ROTATION_MAX
# define LAND_DETECTOR_ROTATION_MAX 0.50f // vehicle rotation must be below 0.5 rad/sec (=30deg/sec for) vehicle to consider itself landed
#endif
#ifndef LAND_REQUIRE_MIN_THROTTLE_TO_DISARM // require pilot to reduce throttle to minimum before vehicle will disarm
# define LAND_REQUIRE_MIN_THROTTLE_TO_DISARM ENABLED
#endif
#ifndef LAND_REPOSITION_DEFAULT
# define LAND_REPOSITION_DEFAULT 0 // by default the pilot cannot override roll/pitch during landing
# define LAND_REPOSITION_DEFAULT 1 // by default the pilot can override roll/pitch during landing
#endif
#ifndef LAND_WITH_DELAY_MS
# define LAND_WITH_DELAY_MS 4000 // default delay (in milliseconds) when a land-with-delay is triggered during a failsafe event
@ -584,7 +651,7 @@
# define RATE_PITCH_D 0.004f
#endif
#ifndef RATE_PITCH_IMAX
# define RATE_PITCH_IMAX 500
# define RATE_PITCH_IMAX 1000
#endif
#ifndef RATE_YAW_P
@ -654,8 +721,8 @@
# define THR_MAX_DEFAULT 1000 // maximum throttle sent to the motors
#endif
#ifndef THROTTLE_IN_DEADBAND
# define THROTTLE_IN_DEADBAND 100 // the throttle input channel's deadband in PWM
#ifndef THR_DZ_DEFAULT
# define THR_DZ_DEFAULT 100 // the deadzone above and below mid throttle while in althold or loiter
#endif
#ifndef ALT_HOLD_P
@ -664,7 +731,21 @@
// RATE control
#ifndef THROTTLE_RATE_P
# define THROTTLE_RATE_P 6.0f
# define THROTTLE_RATE_P 5.0f
#endif
// Throttle Accel control
#ifndef THROTTLE_ACCEL_P
# define THROTTLE_ACCEL_P 0.50f
#endif
#ifndef THROTTLE_ACCEL_I
# define THROTTLE_ACCEL_I 1.00f
#endif
#ifndef THROTTLE_ACCEL_D
# define THROTTLE_ACCEL_D 0.0f
#endif
#ifndef THROTTLE_ACCEL_IMAX
# define THROTTLE_ACCEL_IMAX 800
#endif
// default maximum vertical velocity and acceleration the pilot may request
@ -684,20 +765,6 @@
# define ALT_HOLD_ACCEL_MAX 250 // if you change this you must also update the duplicate declaration in AC_WPNav.h
#endif
// Throttle Accel control
#ifndef THROTTLE_ACCEL_P
# define THROTTLE_ACCEL_P 0.75f
#endif
#ifndef THROTTLE_ACCEL_I
# define THROTTLE_ACCEL_I 1.50f
#endif
#ifndef THROTTLE_ACCEL_D
# define THROTTLE_ACCEL_D 0.0f
#endif
#ifndef THROTTLE_ACCEL_IMAX
# define THROTTLE_ACCEL_IMAX 500
#endif
//////////////////////////////////////////////////////////////////////////////
// Dataflash logging control
//

View File

@ -59,6 +59,11 @@ static void get_pilot_desired_angle_rates(int16_t roll_in, int16_t pitch_in, int
// expo variables
float rp_in, rp_in3, rp_out;
// range check expo
if (g.acro_expo > 1.0f) {
g.acro_expo = 1.0f;
}
// roll expo
rp_in = float(roll_in)/ROLL_PITCH_INPUT_MAX;
rp_in3 = rp_in*rp_in*rp_in;

View File

@ -102,13 +102,14 @@ static void auto_takeoff_run()
{
// if not auto armed set throttle to zero and exit immediately
if(!ap.auto_armed) {
// initialise wpnav targets
wp_nav.shift_wp_origin_to_current_pos();
// reset attitude control targets
attitude_control.relax_bf_rate_controller();
attitude_control.set_yaw_target_to_current_heading();
attitude_control.set_throttle_out(0, false);
// tell motors to do a slow start
motors.slow_start(true);
// To-Do: re-initialise wpnav targets
return;
}
@ -287,6 +288,11 @@ static void auto_land_run()
return;
}
// relax loiter targets if we might be landed
if (land_complete_maybe()) {
wp_nav.loiter_soften_for_landing();
}
// process pilot's input
if (!failsafe.radio) {
if (g.land_repositioning) {
@ -309,7 +315,7 @@ static void auto_land_run()
wp_nav.update_loiter();
// call z-axis position controller
pos_control.set_alt_target_from_climb_rate(get_throttle_land(), G_Dt);
pos_control.set_alt_target_from_climb_rate(get_throttle_land(), G_Dt, true);
pos_control.update_z_controller();
// roll & pitch from waypoint controller, yaw rate from pilot
@ -470,7 +476,7 @@ void set_auto_yaw_mode(uint8_t yaw_mode)
}
// set_auto_yaw_look_at_heading - sets the yaw look at heading for auto mode
static void set_auto_yaw_look_at_heading(float angle_deg, float turn_rate_dps, uint8_t relative_angle)
static void set_auto_yaw_look_at_heading(float angle_deg, float turn_rate_dps, int8_t direction, uint8_t relative_angle)
{
// get current yaw target
int32_t curr_yaw_target = attitude_control.angle_ef_targets().z;
@ -481,7 +487,10 @@ static void set_auto_yaw_look_at_heading(float angle_deg, float turn_rate_dps, u
yaw_look_at_heading = wrap_360_cd(angle_deg * 100);
} else {
// relative angle
yaw_look_at_heading = wrap_360_cd(angle_deg * 100);
if (direction < 0) {
angle_deg = -angle_deg;
}
yaw_look_at_heading = wrap_360_cd((angle_deg*100+curr_yaw_target));
}
// get turn speed

View File

@ -53,10 +53,10 @@
#define AUTOTUNE_PI_RATIO_FOR_TESTING 0.1f // I is set 10x smaller than P during testing
#define AUTOTUNE_RP_RATIO_FINAL 1.0f // I is set 1x P after testing
#define AUTOTUNE_RD_MIN 0.002f // minimum Rate D value
#define AUTOTUNE_RD_MAX 0.015f // maximum Rate D value
#define AUTOTUNE_RD_MAX 0.020f // maximum Rate D value
#define AUTOTUNE_RP_MIN 0.01f // minimum Rate P value
#define AUTOTUNE_RP_MAX 0.25f // maximum Rate P value
#define AUTOTUNE_SP_MAX 15.0f // maximum Stab P value
#define AUTOTUNE_RP_MAX 0.35f // maximum Rate P value
#define AUTOTUNE_SP_MAX 20.0f // maximum Stab P value
#define AUTOTUNE_SUCCESS_COUNT 4 // how many successful iterations we need to freeze at current gains
// Auto Tune message ids for ground station

View File

@ -64,6 +64,7 @@ void guided_pos_control_start()
set_auto_yaw_mode(get_default_auto_yaw_mode(false));
}
#if NAV_GUIDED == ENABLED
// initialise guided mode's velocity controller
void guided_vel_control_start()
{
@ -77,6 +78,7 @@ void guided_vel_control_start()
// initialise velocity controller
pos_control.init_vel_controller_xyz();
}
#endif
// guided_set_destination - sets guided mode's target destination
static void guided_set_destination(const Vector3f& destination)
@ -89,6 +91,7 @@ static void guided_set_destination(const Vector3f& destination)
wp_nav.set_wp_destination(destination);
}
#if NAV_GUIDED == ENABLED
// guided_set_velocity - sets guided mode's target velocity
static void guided_set_velocity(const Vector3f& velocity)
{
@ -100,6 +103,7 @@ static void guided_set_velocity(const Vector3f& velocity)
// set position controller velocity target
pos_control.set_desired_velocity(velocity);
}
#endif
// guided_run - runs the guided controller
// should be called at 100hz or more
@ -128,9 +132,12 @@ static void guided_run()
guided_pos_control_run();
break;
#if NAV_GUIDED == ENABLED
case Guided_Velocity:
// run velocity controller
guided_vel_control_run();
break;
#endif
}
}
@ -140,13 +147,14 @@ static void guided_takeoff_run()
{
// if not auto armed set throttle to zero and exit immediately
if(!ap.auto_armed) {
// initialise wpnav targets
wp_nav.shift_wp_origin_to_current_pos();
// reset attitude control targets
attitude_control.relax_bf_rate_controller();
attitude_control.set_yaw_target_to_current_heading();
attitude_control.set_throttle_out(0, false);
// tell motors to do a slow start
motors.slow_start(true);
// To-Do: re-initialise wpnav targets
return;
}

View File

@ -1,7 +1,5 @@
/// -*- tab-width: 4; Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*-
// counter to verify landings
static uint16_t land_detector;
static bool land_with_gps;
static uint32_t land_start_time;
@ -61,7 +59,7 @@ static void land_gps_run()
#if LAND_REQUIRE_MIN_THROTTLE_TO_DISARM == ENABLED
// disarm when the landing detector says we've landed and throttle is at minimum
if (ap.land_complete && (g.rc_3.control_in == 0 || failsafe.radio)) {
if (ap.land_complete && (ap.throttle_zero || failsafe.radio)) {
init_disarm_motors();
}
#else
@ -73,6 +71,11 @@ static void land_gps_run()
return;
}
// relax loiter target if we might be landed
if (land_complete_maybe()) {
wp_nav.loiter_soften_for_landing();
}
// process pilot inputs
if (!failsafe.radio) {
if (g.land_repositioning) {
@ -107,7 +110,7 @@ static void land_gps_run()
}
// update altitude target and call position controller
pos_control.set_alt_target_from_climb_rate(cmb_rate, G_Dt);
pos_control.set_alt_target_from_climb_rate(cmb_rate, G_Dt, true);
pos_control.update_z_controller();
}
@ -126,7 +129,7 @@ static void land_nogps_run()
attitude_control.set_throttle_out(0, false);
#if LAND_REQUIRE_MIN_THROTTLE_TO_DISARM == ENABLED
// disarm when the landing detector says we've landed and throttle is at minimum
if (ap.land_complete && (g.rc_3.control_in == 0 || failsafe.radio)) {
if (ap.land_complete && (ap.throttle_zero || failsafe.radio)) {
init_disarm_motors();
}
#else
@ -165,7 +168,7 @@ static void land_nogps_run()
}
// call position controller
pos_control.set_alt_target_from_climb_rate(cmb_rate, G_Dt);
pos_control.set_alt_target_from_climb_rate(cmb_rate, G_Dt, true);
pos_control.update_z_controller();
}
@ -187,33 +190,6 @@ static float get_throttle_land()
}
}
// update_land_detector - checks if we have landed and updates the ap.land_complete flag
// returns true if we have landed
static bool update_land_detector()
{
// detect whether we have landed by watching for low climb rate and minimum throttle
if (abs(climb_rate) < 40 && motors.limit.throttle_lower) {
if (!ap.land_complete) {
// run throttle controller if accel based throttle controller is enabled and active (active means it has been given a target)
if( land_detector < LAND_DETECTOR_TRIGGER) {
land_detector++;
}else{
set_land_complete(true);
land_detector = 0;
}
}
} else if ((motors.get_throttle_out() > get_non_takeoff_throttle()) || failsafe.radio) {
// we've sensed movement up or down so reset land_detector
land_detector = 0;
if(ap.land_complete) {
set_land_complete(false);
}
}
// return current state of landing
return ap.land_complete;
}
// land_do_not_use_GPS - forces land-mode to not use the GPS but instead rely on pilot input for roll and pitch
// called during GPS failsafe to ensure that if we were already in LAND mode that we do not use the GPS
// has no effect if we are not already in LAND mode
@ -228,3 +204,8 @@ static void set_mode_land_with_pause()
set_mode(LAND);
land_pause = true;
}
// landing_with_GPS - returns true if vehicle is landing using GPS
static bool landing_with_GPS() {
return (control_mode == LAND && land_with_gps);
}

View File

@ -68,6 +68,11 @@ static void loiter_run()
wp_nav.clear_pilot_desired_acceleration();
}
// relax loiter target if we might be landed
if (land_complete_maybe()) {
wp_nav.loiter_soften_for_landing();
}
// when landed reset targets and output zero throttle
if (ap.land_complete) {
wp_nav.init_loiter_target();

View File

@ -77,7 +77,7 @@ static struct {
// loiter related variables
int16_t controller_to_pilot_timer_roll; // cycles to mix controller and pilot controls in POSHOLD_CONTROLLER_TO_PILOT
int16_t controller_to_pilot_timer_pitch; // cycles to mix controller and pilot controls in POSHOLD_CONTROLLER_TO_PILOT
int16_t controller_to_pilot_timer_pitch; // cycles to mix controller and pilot controls in POSHOLD_CONTROLLER_TO_PILOT
int16_t controller_final_roll; // final roll angle from controller as we exit brake or loiter mode (used for mixing with pilot input)
int16_t controller_final_pitch; // final pitch angle from controller as we exit brake or loiter mode (used for mixing with pilot input)
@ -85,8 +85,8 @@ static struct {
Vector2f wind_comp_ef; // wind compensation in earth frame, filtered lean angles from position controller
int16_t wind_comp_roll; // roll angle to compensate for wind
int16_t wind_comp_pitch; // pitch angle to compensate for wind
int8_t wind_comp_start_timer; // counter to delay start of wind compensation for a short time after loiter is engaged
int8_t wind_comp_timer; // counter to reduce wind comp roll/pitch lean angle calcs to 10hz
uint16_t wind_comp_start_timer; // counter to delay start of wind compensation for a short time after loiter is engaged
int8_t wind_comp_timer; // counter to reduce wind comp roll/pitch lean angle calcs to 10hz
// final output
int16_t roll; // final roll angle sent to attitude controller
@ -183,6 +183,11 @@ static void poshold_run()
}
}
// relax loiter target if we might be landed
if (land_complete_maybe()) {
wp_nav.loiter_soften_for_landing();
}
// if landed initialise loiter targets, set throttle to zero and exit
if (ap.land_complete) {
wp_nav.init_loiter_target();

View File

@ -325,15 +325,35 @@ static void rtl_land_run()
int16_t roll_control = 0, pitch_control = 0;
float target_yaw_rate = 0;
// if not auto armed set throttle to zero and exit immediately
if(!ap.auto_armed || !inertial_nav.position_ok()) {
if(!ap.auto_armed || ap.land_complete) {
attitude_control.relax_bf_rate_controller();
attitude_control.set_yaw_target_to_current_heading();
attitude_control.set_throttle_out(0, false);
// set target to current position
wp_nav.init_loiter_target();
#if LAND_REQUIRE_MIN_THROTTLE_TO_DISARM == ENABLED
// disarm when the landing detector says we've landed and throttle is at minimum
if (ap.land_complete && (ap.throttle_zero || failsafe.radio)) {
init_disarm_motors();
}
#else
// disarm when the landing detector says we've landed
if (ap.land_complete) {
init_disarm_motors();
}
#endif
// check if we've completed this stage of RTL
rtl_state_complete = ap.land_complete;
return;
}
// relax loiter target if we might be landed
if (land_complete_maybe()) {
wp_nav.loiter_soften_for_landing();
}
// process pilot's input
if (!failsafe.radio) {
if (g.land_repositioning) {
@ -357,7 +377,7 @@ static void rtl_land_run()
// call z-axis position controller
float cmb_rate = get_throttle_land();
pos_control.set_alt_target_from_climb_rate(cmb_rate, G_Dt);
pos_control.set_alt_target_from_climb_rate(cmb_rate, G_Dt, true);
pos_control.update_z_controller();
// roll & pitch from waypoint controller, yaw rate from pilot
@ -365,18 +385,6 @@ static void rtl_land_run()
// check if we've completed this stage of RTL
rtl_state_complete = ap.land_complete;
#if LAND_REQUIRE_MIN_THROTTLE_TO_DISARM == ENABLED
// disarm when the landing detector says we've landed and throttle is at minimum
if (ap.land_complete && (g.rc_3.control_in == 0 || failsafe.radio)) {
init_disarm_motors();
}
#else
// disarm when the landing detector says we've landed
if (ap.land_complete) {
init_disarm_motors();
}
#endif
}
// get_RTL_alt - return altitude which vehicle should return home at

View File

@ -25,7 +25,7 @@ void crash_check()
#endif
// return immediately if motors are not armed or pilot's throttle is above zero
if (!motors.armed() || (g.rc_3.control_in != 0 && !failsafe.radio)) {
if (!motors.armed() || (!ap.throttle_zero && !failsafe.radio)) {
inverted_count = 0;
return;
}

View File

@ -195,8 +195,10 @@ enum AutoMode {
// Guided modes
enum GuidedMode {
Guided_TakeOff,
Guided_WP,
Guided_Velocity
Guided_WP
#if NAV_GUIDED == ENABLED
,Guided_Velocity
#endif
};
// RTL states
@ -263,6 +265,8 @@ enum FlipState {
#define MASK_LOG_COMPASS (1<<13)
#define MASK_LOG_INAV (1<<14) // deprecated
#define MASK_LOG_CAMERA (1<<15)
#define MASK_LOG_WHEN_DISARMED (1UL<<16)
#define MASK_LOG_ANY 0xFFFF
// DATA - event logging
#define DATA_MAVLINK_FLOAT 1
@ -275,6 +279,7 @@ enum FlipState {
#define DATA_DISARMED 11
#define DATA_AUTO_ARMED 15
#define DATA_TAKEOFF 16
#define DATA_LAND_COMPLETE_MAYBE 17
#define DATA_LAND_COMPLETE 18
#define DATA_NOT_LANDED 28
#define DATA_LOST_GPS 19
@ -329,8 +334,8 @@ enum FlipState {
#define ERROR_SUBSYSTEM_FLIP 13
#define ERROR_SUBSYSTEM_AUTOTUNE 14
#define ERROR_SUBSYSTEM_PARACHUTE 15
#define ERROR_SUBSYSTEM_EKF_CHECK 16
#define ERROR_SUBSYSTEM_FAILSAFE_EKF 17
#define ERROR_SUBSYSTEM_EKFINAV_CHECK 16
#define ERROR_SUBSYSTEM_FAILSAFE_EKFINAV 17
#define ERROR_SUBSYSTEM_BARO 18
// general error codes
#define ERROR_CODE_ERROR_RESOLVED 0
@ -356,8 +361,8 @@ enum FlipState {
// parachute failed to deploy because of low altitude
#define ERROR_CODE_PARACHUTE_TOO_LOW 2
// EKF check definitions
#define ERROR_CODE_EKF_CHECK_BAD_VARIANCE 2
#define ERROR_CODE_EKF_CHECK_BAD_VARIANCE_CLEARED 0
#define ERROR_CODE_EKFINAV_CHECK_BAD_VARIANCE 2
#define ERROR_CODE_EKFINAV_CHECK_VARIANCE_CLEARED 0
// Baro specific error codes
#define ERROR_CODE_BARO_GLITCH 2

View File

@ -11,61 +11,52 @@
# define EKF_CHECK_ITERATIONS_MAX 10 // 1 second (ie. 10 iterations at 10hz) of bad variances signals a failure
#endif
#ifndef EKF_CHECK_COMPASS_INAV_CONVERSION
# define EKF_CHECK_COMPASS_INAV_CONVERSION 0.0075f // converts the inertial nav's acceleration corrections to a form that is comparable to the ekf variance
#endif
#ifndef EKF_CHECK_WARNING_TIME
# define EKF_CHECK_WARNING_TIME (30*1000) // warning text messages are sent to ground no more than every 30 seconds
#endif
// Enumerator for types of check
enum EKFCheckType {
CHECK_NONE = 0,
CHECK_DCM = 1,
CHECK_EKF = 2
};
////////////////////////////////////////////////////////////////////////////////
// EKF_check strucutre
////////////////////////////////////////////////////////////////////////////////
static struct {
uint8_t fail_count_compass; // number of iterations ekf's compass variance has been out of tolerances
uint8_t fail_count_compass; // number of iterations ekf or dcm have been out of tolerances
uint8_t bad_compass : 1; // true if compass variance is bad
uint8_t bad_compass : 1; // true if dcm or ekf should be considered untrusted (fail_count_compass has exceeded EKF_CHECK_ITERATIONS_MAX)
uint32_t last_warn_time; // system time of last warning in milliseconds. Used to throttle text warnings sent to GCS
} ekf_check_state;
// ekf_check - detects ekf variances that are out of tolerance
// ekf_dcm_check - detects if ekf variances or dcm yaw errors that are out of tolerance and triggers failsafe
// should be called at 10hz
void ekf_check()
void ekf_dcm_check()
{
// return immediately if motors are not armed, ekf check is disabled, no inertial-nav position yet or usb is connected
if (!motors.armed() || g.ekfcheck_thresh == 0.0f || !inertial_nav.position_ok() || ap.usb_connected) {
EKFCheckType check_type = CHECK_NONE;
// decide if we should check ekf or dcm
if (ahrs.have_inertial_nav() && g.ekfcheck_thresh > 0.0f) {
check_type = CHECK_EKF;
} else if (g.dcmcheck_thresh > 0.0f) {
check_type = CHECK_DCM;
}
// return immediately if motors are not armed, ekf check is disabled, not using ekf or usb is connected
if (!motors.armed() || ap.usb_connected || check_type == CHECK_NONE) {
ekf_check_state.fail_count_compass = 0;
ekf_check_state.bad_compass = 0;
ekf_check_state.bad_compass = false;
AP_Notify::flags.ekf_bad = ekf_check_state.bad_compass;
failsafe_ekf_off_event(); // clear failsafe
return;
}
// variances
float compass_variance = 0;
float vel_variance = 9.0; // default set high to enable failsafe trigger if not using EKF
#if AP_AHRS_NAVEKF_AVAILABLE
if (ahrs.have_inertial_nav()) {
// use EKF to get variance
float posVar, hgtVar, tasVar;
Vector3f magVar;
Vector2f offset;
ahrs.get_NavEKF().getVariances(vel_variance, posVar, hgtVar, magVar, tasVar, offset);
compass_variance = magVar.length();
} else {
// use complementary filter's acceleration corrections multiplied by conversion factor to make them general in the same range as the EKF's variances
compass_variance = safe_sqrt(inertial_nav.accel_correction_hbf.x * inertial_nav.accel_correction_hbf.x + inertial_nav.accel_correction_hbf.y * inertial_nav.accel_correction_hbf.y) * EKF_CHECK_COMPASS_INAV_CONVERSION;
}
#else
// use complementary filter's acceleration corrections multiplied by conversion factor to make them general in the same range as the EKF's variances
compass_variance = safe_sqrt(inertial_nav.accel_correction_hbf.x * inertial_nav.accel_correction_hbf.x + inertial_nav.accel_correction_hbf.y * inertial_nav.accel_correction_hbf.y) * EKF_CHECK_COMPASS_INAV_CONVERSION;
#endif
// compare compass and velocity variance vs threshold
if (compass_variance >= g.ekfcheck_thresh && vel_variance > g.ekfcheck_thresh) {
if ((check_type == CHECK_EKF && ekf_over_threshold()) || (check_type == CHECK_DCM && dcm_over_threshold())) {
// if compass is not yet flagged as bad
if (!ekf_check_state.bad_compass) {
// increase counter
@ -76,25 +67,29 @@ void ekf_check()
ekf_check_state.fail_count_compass = EKF_CHECK_ITERATIONS_MAX;
ekf_check_state.bad_compass = true;
// log an error in the dataflash
Log_Write_Error(ERROR_SUBSYSTEM_EKF_CHECK, ERROR_CODE_EKF_CHECK_BAD_VARIANCE);
Log_Write_Error(ERROR_SUBSYSTEM_EKFINAV_CHECK, ERROR_CODE_EKFINAV_CHECK_BAD_VARIANCE);
// send message to gcs
if ((hal.scheduler->millis() - ekf_check_state.last_warn_time) > EKF_CHECK_WARNING_TIME) {
gcs_send_text_P(SEVERITY_HIGH,PSTR("EKF variance"));
if (check_type == CHECK_EKF) {
gcs_send_text_P(SEVERITY_HIGH,PSTR("EKF variance"));
} else {
gcs_send_text_P(SEVERITY_HIGH,PSTR("DCM bad heading"));
}
ekf_check_state.last_warn_time = hal.scheduler->millis();
}
failsafe_ekf_event();
}
}
} else {
// if compass is flagged as bad
if (ekf_check_state.bad_compass) {
// reduce counter
// reduce counter
if (ekf_check_state.fail_count_compass > 0) {
ekf_check_state.fail_count_compass--;
// if counter reaches zero then clear flag
if (ekf_check_state.fail_count_compass == 0) {
// if compass is flagged as bad and the counter reaches zero then clear flag
if (ekf_check_state.bad_compass && ekf_check_state.fail_count_compass == 0) {
ekf_check_state.bad_compass = false;
// log recovery in the dataflash
Log_Write_Error(ERROR_SUBSYSTEM_EKF_CHECK, ERROR_CODE_EKF_CHECK_BAD_VARIANCE_CLEARED);
Log_Write_Error(ERROR_SUBSYSTEM_EKFINAV_CHECK, ERROR_CODE_EKFINAV_CHECK_VARIANCE_CLEARED);
// clear failsafe
failsafe_ekf_off_event();
}
@ -104,18 +99,47 @@ void ekf_check()
// set AP_Notify flags
AP_Notify::flags.ekf_bad = ekf_check_state.bad_compass;
// To-Do: add check for althold when vibrations are high
// To-Do: add ekf variances to extended status
// To-Do: add counter measures to try and recover from bad EKF
// To-Do: add check into GPS position_ok() to return false if ekf xy not healthy?
// To-Do: ensure it compiles for AVR
}
// dcm_over_threshold - returns true if the dcm yaw error is over the tolerance
static bool dcm_over_threshold()
{
// return true if yaw error is over the threshold
return (g.dcmcheck_thresh > 0.0f && ahrs.get_error_yaw() > g.dcmcheck_thresh);
}
// ekf_over_threshold - returns true if the ekf's variance are over the tolerance
static bool ekf_over_threshold()
{
#if AP_AHRS_NAVEKF_AVAILABLE
// return false immediately if disabled
if (g.ekfcheck_thresh <= 0.0f) {
return false;
}
// use EKF to get variance
float posVar, hgtVar, tasVar;
Vector3f magVar;
Vector2f offset;
float compass_variance;
float vel_variance;
ahrs.get_NavEKF().getVariances(vel_variance, posVar, hgtVar, magVar, tasVar, offset);
compass_variance = magVar.length();
// return true if compass and velocity variance over the threshold
return (compass_variance >= g.ekfcheck_thresh && vel_variance >= g.ekfcheck_thresh);
#else
return false;
#endif
}
// failsafe_ekf_event - perform ekf failsafe
static void failsafe_ekf_event()
{
// return immediately if ekf failsafe already triggered or disabled
if (failsafe.ekf || g.ekfcheck_thresh <= 0.0f) {
// return immediately if ekf failsafe already triggered
if (failsafe.ekf) {
return;
}
@ -126,7 +150,7 @@ static void failsafe_ekf_event()
// EKF failsafe event has occurred
failsafe.ekf = true;
Log_Write_Error(ERROR_SUBSYSTEM_FAILSAFE_EKF, ERROR_CODE_FAILSAFE_OCCURRED);
Log_Write_Error(ERROR_SUBSYSTEM_FAILSAFE_EKFINAV, ERROR_CODE_FAILSAFE_OCCURRED);
// take action based on flight mode
if (mode_requires_GPS(control_mode)) {
@ -149,5 +173,5 @@ static void failsafe_ekf_off_event(void)
// clear flag and log recovery
failsafe.ekf = false;
Log_Write_Error(ERROR_SUBSYSTEM_FAILSAFE_EKF, ERROR_CODE_FAILSAFE_RESOLVED);
Log_Write_Error(ERROR_SUBSYSTEM_FAILSAFE_EKFINAV, ERROR_CODE_FAILSAFE_RESOLVED);
}

View File

@ -16,7 +16,7 @@ static void failsafe_radio_on_event()
case STABILIZE:
case ACRO:
// if throttle is zero OR vehicle is landed disarm motors
if (g.rc_3.control_in == 0 || ap.land_complete) {
if (ap.throttle_zero || ap.land_complete) {
init_disarm_motors();
// if failsafe_throttle is FS_THR_ENABLED_ALWAYS_LAND then land immediately
@ -115,7 +115,7 @@ static void failsafe_battery_event(void)
case STABILIZE:
case ACRO:
// if throttle is zero OR vehicle is landed disarm motors
if (g.rc_3.control_in == 0 || ap.land_complete) {
if (ap.throttle_zero || ap.land_complete) {
init_disarm_motors();
}else{
// set mode to RTL or LAND
@ -274,7 +274,7 @@ static void failsafe_gcs_check()
case ACRO:
case SPORT:
// if throttle is zero disarm motors
if (g.rc_3.control_in == 0) {
if (ap.throttle_zero) {
init_disarm_motors();
}else if(home_distance > wp_nav.get_wp_radius()) {
if (!set_mode(RTL)) {

View File

@ -30,7 +30,7 @@ void fence_check()
// disarm immediately if we think we are on the ground
// don't disarm if the high-altitude fence has been broken because it's likely the user has pulled their throttle to zero to bring it down
if(manual_flight_mode(control_mode) && g.rc_3.control_in == 0 && !failsafe.radio && ((fence.get_breaches() & AC_FENCE_TYPE_ALT_MAX)== 0)){
if(ap.land_complete || manual_flight_mode(control_mode) && ap.throttle_zero && !failsafe.radio && ((fence.get_breaches() & AC_FENCE_TYPE_ALT_MAX)== 0)){
init_disarm_motors();
}else{
// if we are within 100m of the fence, RTL

View File

@ -227,6 +227,13 @@ static void exit_mode(uint8_t old_control_mode, uint8_t new_control_mode)
// this assumes all manual flight modes use get_pilot_desired_throttle to translate pilot input to output throttle
set_accel_throttle_I_from_pilot_throttle(get_pilot_desired_throttle(g.rc_3.control_in));
}
#if FRAME_CONFIG == HELI_FRAME
// firmly reset the flybar passthrough to false when exiting acro mode.
if (old_control_mode == ACRO) {
attitude_control.use_flybar_passthrough(false);
}
#endif //HELI_FRAME
}
// returns true or false whether mode requires GPS
@ -252,8 +259,6 @@ static bool manual_flight_mode(uint8_t mode) {
switch(mode) {
case ACRO:
case STABILIZE:
case DRIFT:
case SPORT:
return true;
default:
return false;
@ -262,6 +267,15 @@ static bool manual_flight_mode(uint8_t mode) {
return false;
}
// mode_allows_arming - returns true if vehicle can be armed in the specified mode
// arming_from_gcs should be set to true if the arming request comes from the ground station
static bool mode_allows_arming(uint8_t mode, bool arming_from_gcs) {
if (manual_flight_mode(mode) || mode == LOITER || mode == ALT_HOLD || mode == POSHOLD || (arming_from_gcs && mode == GUIDED)) {
return true;
}
return false;
}
//
// print_flight_mode - prints flight mode to serial port.
//
@ -320,8 +334,3 @@ print_flight_mode(AP_HAL::BetterStream *port, uint8_t mode)
}
}
// get_angle_targets_for_reporting() - returns 3d vector of roll, pitch and yaw target angles for logging and reporting to GCS
static void get_angle_targets_for_reporting(Vector3f& targets)
{
targets = attitude_control.angle_ef_targets();
}

View File

@ -7,6 +7,9 @@
// heli_acro_init - initialise acro controller
static bool heli_acro_init(bool ignore_checks)
{
// if heli is equipped with a flybar, then tell the attitude controller to pass through controls directly to servos
attitude_control.use_flybar_passthrough(motors.has_flybar());
// always successfully enter acro
return true;
}
@ -31,19 +34,33 @@ static void heli_acro_run()
if(motors.armed() && heli_flags.init_targets_on_arming) {
heli_flags.init_targets_on_arming=false;
attitude_control.relax_bf_rate_controller();
}
// To-Do: add support for flybarred helis
// convert the input to the desired body frame rate
get_pilot_desired_angle_rates(g.rc_1.control_in, g.rc_2.control_in, g.rc_4.control_in, target_roll, target_pitch, target_yaw);
// run attitude controller
attitude_control.rate_bf_roll_pitch_yaw(target_roll, target_pitch, target_yaw);
if (!motors.has_flybar()){
// convert the input to the desired body frame rate
get_pilot_desired_angle_rates(g.rc_1.control_in, g.rc_2.control_in, g.rc_4.control_in, target_roll, target_pitch, target_yaw);
// run attitude controller
attitude_control.rate_bf_roll_pitch_yaw(target_roll, target_pitch, target_yaw);
}else{
// flybar helis only need yaw rate control
get_pilot_desired_yaw_rate(g.rc_4.control_in, target_yaw);
// run attitude controller
attitude_control.passthrough_bf_roll_pitch_rate_yaw(g.rc_1.control_in, g.rc_2.control_in, target_yaw);
}
// output pilot's throttle without angle boost
attitude_control.set_throttle_out(g.rc_3.control_in, false);
}
// get_pilot_desired_yaw_rate - transform pilot's yaw input into a desired yaw angle rate
// returns desired yaw rate in centi-degrees-per-second
static void get_pilot_desired_yaw_rate(int16_t yaw_in, float &yaw_out)
{
// calculate rate request
float rate_bf_yaw_request = yaw_in * g.acro_yaw_p;
// hand back rate request
yaw_out = rate_bf_yaw_request;
}
#endif //HELI_FRAME

View File

@ -0,0 +1,43 @@
/// -*- tab-width: 4; Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*-
// counter to verify landings
static uint16_t land_detector = LAND_DETECTOR_TRIGGER; // we assume we are landed
// land_complete_maybe - return true if we may have landed (used to reset loiter targets during landing)
static bool land_complete_maybe()
{
return (ap.land_complete || ap.land_complete_maybe);
}
// update_land_detector - checks if we have landed and updates the ap.land_complete flag
// called at 50hz
static void update_land_detector()
{
bool climb_rate_low = (abs(climb_rate) < LAND_DETECTOR_CLIMBRATE_MAX) && (abs(baro_climbrate) < LAND_DETECTOR_BARO_CLIMBRATE_MAX);
bool target_climb_rate_low = !pos_control.is_active_z() || (pos_control.get_desired_velocity().z <= LAND_DETECTOR_DESIRED_CLIMBRATE_MAX);
bool motor_at_lower_limit = motors.limit.throttle_lower;
bool throttle_low = (FRAME_CONFIG == HELI_FRAME) || (motors.get_throttle_out() < get_non_takeoff_throttle());
bool not_rotating_fast = (ahrs.get_gyro().length() < LAND_DETECTOR_ROTATION_MAX);
if (climb_rate_low && target_climb_rate_low && motor_at_lower_limit && throttle_low && not_rotating_fast) {
if (!ap.land_complete) {
// increase counter until we hit the trigger then set land complete flag
if( land_detector < LAND_DETECTOR_TRIGGER) {
land_detector++;
}else{
set_land_complete(true);
land_detector = LAND_DETECTOR_TRIGGER;
}
}
} else {
// we've sensed movement up or down so reset land_detector
land_detector = 0;
// if throttle output is high then clear landing flag
if (motors.get_throttle_out() > get_non_takeoff_throttle()) {
set_land_complete(false);
}
}
// set land maybe flag
set_land_complete_maybe(land_detector >= LAND_DETECTOR_MAYBE_TRIGGER);
}

View File

@ -96,9 +96,6 @@ static bool mavlink_motor_test_check(mavlink_channel_t chan)
// returns MAV_RESULT_ACCEPTED on success, MAV_RESULT_FAILED on failure
static uint8_t mavlink_motor_test_start(mavlink_channel_t chan, uint8_t motor_seq, uint8_t throttle_type, uint16_t throttle_value, float timeout_sec)
{
// debug
cliSerial->printf_P(PSTR("\nMotTest Seq:%d TT:%d Thr:%d TimOut:%4.2f"),(int)motor_seq, (int)throttle_type, (int)throttle_value, (float)timeout_sec);
// if test has not started try to start it
if (!ap.motor_test) {
// perform checks that it is ok to start test

View File

@ -5,12 +5,13 @@
#define AUTO_TRIM_DELAY 100 // called at 10hz so 10 seconds
#define AUTO_DISARMING_DELAY 15 // called at 1hz so 15 seconds
static uint8_t auto_disarming_counter;
// arm_motors_check - checks for pilot input to arm or disarm the copter
// called at 10hz
static void arm_motors_check()
{
static int16_t arming_counter;
bool allow_arming = false;
// ensure throttle is down
if (g.rc_3.control_in > 0) {
@ -18,30 +19,6 @@ static void arm_motors_check()
return;
}
// allow arming/disarming in fully manual flight modes ACRO, STABILIZE, SPORT and DRIFT
if (manual_flight_mode(control_mode)) {
allow_arming = true;
}
// allow arming/disarming in Loiter and AltHold if landed
if (ap.land_complete && (control_mode == LOITER || control_mode == ALT_HOLD || control_mode == POSHOLD || control_mode == AUTOTUNE)) {
allow_arming = true;
}
// kick out other flight modes
if (!allow_arming) {
arming_counter = 0;
return;
}
#if FRAME_CONFIG == HELI_FRAME
// heli specific arming check
if (!motors.allow_arming()){
arming_counter = 0;
return;
}
#endif // HELI_FRAME
int16_t tmp = g.rc_4.control_in;
// full right
@ -56,8 +33,12 @@ static void arm_motors_check()
if (arming_counter == ARM_DELAY && !motors.armed()) {
// run pre-arm-checks and display failures
pre_arm_checks(true);
if(ap.pre_arm_check && arm_checks(true)) {
init_arm_motors();
if(ap.pre_arm_check && arm_checks(true,false)) {
if (!init_arm_motors()) {
// reset arming counter if arming fail
arming_counter = 0;
AP_Notify::flags.arming_failed = true;
}
}else{
// reset arming counter if pre-arm checks fail
arming_counter = 0;
@ -68,10 +49,16 @@ static void arm_motors_check()
// arm the motors and configure for flight
if (arming_counter == AUTO_TRIM_DELAY && motors.armed() && control_mode == STABILIZE) {
auto_trim_counter = 250;
// ensure auto-disarm doesn't trigger immediately
auto_disarming_counter = 0;
}
// full left
}else if (tmp < -4000) {
if (!manual_flight_mode(control_mode) && !ap.land_complete) {
arming_counter = 0;
return;
}
// increase the counter to a maximum of 1 beyond the disarm delay
if( arming_counter <= DISARM_DELAY ) {
@ -94,18 +81,14 @@ static void arm_motors_check()
// called at 1hz
static void auto_disarm_check()
{
static uint8_t auto_disarming_counter;
// exit immediately if we are already disarmed or throttle is not zero
if (!motors.armed() || g.rc_3.control_in > 0) {
if (!motors.armed() || !ap.throttle_zero) {
auto_disarming_counter = 0;
return;
}
// allow auto disarm in manual flight modes or Loiter/AltHold if we're landed
if (manual_flight_mode(control_mode) || (ap.land_complete && (control_mode == ALT_HOLD || control_mode == LOITER || control_mode == OF_LOITER ||
control_mode == DRIFT || control_mode == SPORT || control_mode == AUTOTUNE ||
control_mode == POSHOLD))) {
if (manual_flight_mode(control_mode) || ap.land_complete) {
auto_disarming_counter++;
if(auto_disarming_counter >= AUTO_DISARMING_DELAY) {
@ -118,13 +101,21 @@ static void auto_disarm_check()
}
// init_arm_motors - performs arming process including initialisation of barometer and gyros
static void init_arm_motors()
// returns false in the unlikely case that arming fails (because of a gyro calibration failure)
static bool init_arm_motors()
{
// arming marker
// Flag used to track if we have armed the motors the first time.
// This is used to decide if we should run the ground_start routine
// which calibrates the IMU
static bool did_ground_start = false;
static bool in_arm_motors = false;
// exit immediately if already in this function
if (in_arm_motors) {
return false;
}
in_arm_motors = true;
// disable cpu failsafe because initialising everything takes a while
failsafe_disable();
@ -132,6 +123,9 @@ static void init_arm_motors()
// disable inertial nav errors temporarily
inertial_nav.ignore_next_error();
// reset battery failsafe
set_failsafe_battery(false);
// notify that arming will occur (we do this early to give plenty of warning)
AP_Notify::flags.armed = true;
// call update_notify a few times to ensure the message gets out
@ -162,8 +156,16 @@ static void init_arm_motors()
}
if(did_ground_start == false) {
did_ground_start = true;
startup_ground(true);
// final check that gyros calibrated successfully
if (((g.arming_check == ARMING_CHECK_ALL) || (g.arming_check & ARMING_CHECK_INS)) && !ins.gyro_calibrated_ok_all()) {
gcs_send_text_P(SEVERITY_HIGH,PSTR("Arm: Gyro cal failed"));
AP_Notify::flags.armed = false;
failsafe_enable();
in_arm_motors = false;
return false;
}
did_ground_start = true;
}
// fast baro calibration to reset ground pressure
@ -188,8 +190,8 @@ static void init_arm_motors()
motors.output_min();
failsafe_enable();
AP_Notify::flags.armed = false;
AP_Notify::flags.arming_failed = false;
return;
in_arm_motors = false;
return false;
}
#if SPRAYER == ENABLED
@ -197,6 +199,9 @@ static void init_arm_motors()
sprayer.test_pump(false);
#endif
// short delay to allow reading of rc inputs
delay(30);
// enable output to motors
output_min();
@ -211,13 +216,26 @@ static void init_arm_motors()
// reenable failsafe
failsafe_enable();
// flag exiting this function
in_arm_motors = false;
// return success
return true;
}
// perform pre-arm checks and set ap.pre_arm_check flag
static void pre_arm_checks(bool display_failure)
{
// exit immediately if already armed
if (motors.armed()) {
return;
}
// exit immediately if we've already successfully performed the pre-arm check
// run gps checks because results may change and affect LED colour
if (ap.pre_arm_check) {
pre_arm_gps_checks(display_failure);
return;
}
@ -247,7 +265,7 @@ static void pre_arm_checks(bool display_failure)
return;
}
// check Baro & inav alt are within 1m
if(fabs(inertial_nav.get_altitude() - baro_alt) > 100) {
if(fabs(inertial_nav.get_altitude() - baro_alt) > PREARM_MAX_ALT_DISPARITY_CM) {
if (display_failure) {
gcs_send_text_P(SEVERITY_HIGH,PSTR("PreArm: Alt disparity"));
}
@ -266,7 +284,7 @@ static void pre_arm_checks(bool display_failure)
}
// check compass learning is on or offsets have been set
if(!compass.learn_offsets_enabled() && !compass.configured()) {
if(!compass.configured()) {
if (display_failure) {
gcs_send_text_P(SEVERITY_HIGH,PSTR("PreArm: Compass not calibrated"));
}
@ -290,21 +308,40 @@ static void pre_arm_checks(bool display_failure)
}
return;
}
#if COMPASS_MAX_INSTANCES > 1
// check all compasses point in roughly same direction
if (compass.get_count() > 1) {
Vector3f prime_mag_vec = compass.get_field();
prime_mag_vec.normalize();
for(uint8_t i=0; i<compass.get_count(); i++) {
// get next compass
Vector3f mag_vec = compass.get_field(i);
mag_vec.normalize();
Vector3f vec_diff = mag_vec - prime_mag_vec;
if (vec_diff.length() > COMPASS_ACCEPTABLE_VECTOR_DIFF) {
if (display_failure) {
gcs_send_text_P(SEVERITY_HIGH,PSTR("PreArm: compasses inconsistent"));
}
return;
}
}
}
#endif
}
// check GPS
if ((g.arming_check == ARMING_CHECK_ALL) || (g.arming_check & ARMING_CHECK_GPS)) {
// check gps is ok if required - note this same check is repeated again in arm_checks
if ((mode_requires_GPS(control_mode) || g.failsafe_gps_enabled == FS_GPS_LAND_EVEN_STABILIZE) && !pre_arm_gps_checks(display_failure)) {
return;
}
if (!pre_arm_gps_checks(display_failure)) {
return;
}
#if AC_FENCE == ENABLED
// check fence is initialised
if(!fence.pre_arm_check() || (((fence.get_enabled_fences() & AC_FENCE_TYPE_CIRCLE) != 0) && !pre_arm_gps_checks(display_failure))) {
return;
// check fence is initialised
if(!fence.pre_arm_check()) {
if (display_failure) {
gcs_send_text_P(SEVERITY_HIGH,PSTR("PreArm: check fence"));
}
#endif
return;
}
// check INS
@ -317,13 +354,63 @@ static void pre_arm_checks(bool display_failure)
return;
}
// check accels and gyros are healthy
if(!ins.healthy()) {
// check accels are healthy
if(!ins.get_accel_health_all()) {
if (display_failure) {
gcs_send_text_P(SEVERITY_HIGH,PSTR("PreArm: INS not healthy"));
gcs_send_text_P(SEVERITY_HIGH,PSTR("PreArm: Accels not healthy"));
}
return;
}
#if INS_MAX_INSTANCES > 1
// check all accelerometers point in roughly same direction
if (ins.get_accel_count() > 1) {
const Vector3f &prime_accel_vec = ins.get_accel();
for(uint8_t i=0; i<ins.get_accel_count(); i++) {
// get next accel vector
const Vector3f &accel_vec = ins.get_accel(i);
Vector3f vec_diff = accel_vec - prime_accel_vec;
if (vec_diff.length() > PREARM_MAX_ACCEL_VECTOR_DIFF) {
if (display_failure) {
gcs_send_text_P(SEVERITY_HIGH,PSTR("PreArm: Accels inconsistent"));
}
return;
}
}
}
#endif
// check gyros are healthy
if(!ins.get_gyro_health_all()) {
if (display_failure) {
gcs_send_text_P(SEVERITY_HIGH,PSTR("PreArm: Gyros not healthy"));
}
return;
}
// check gyros calibrated successfully
if(!ins.gyro_calibrated_ok_all()) {
if (display_failure) {
gcs_send_text_P(SEVERITY_HIGH,PSTR("PreArm: Gyro cal failed"));
}
return;
}
#if INS_MAX_INSTANCES > 1
// check all gyros are consistent
if (ins.get_gyro_count() > 1) {
for(uint8_t i=0; i<ins.get_gyro_count(); i++) {
// get rotation rate difference between gyro #i and primary gyro
Vector3f vec_diff = ins.get_gyro(i) - ins.get_gyro();
if (vec_diff.length() > PREARM_MAX_GYRO_VECTOR_DIFF) {
if (display_failure) {
gcs_send_text_P(SEVERITY_HIGH,PSTR("PreArm: Gyros inconsistent"));
}
return;
}
}
}
#endif
}
#if CONFIG_HAL_BOARD != HAL_BOARD_VRBRAIN
#ifndef CONFIG_ARCH_BOARD_PX4FMU_V1
@ -418,13 +505,39 @@ static void pre_arm_rc_checks()
// performs pre_arm gps related checks and returns true if passed
static bool pre_arm_gps_checks(bool display_failure)
{
float speed_cms = inertial_nav.get_velocity().length(); // speed according to inertial nav in cm/s
// return true immediately if gps check is disabled
if (!(g.arming_check == ARMING_CHECK_ALL || g.arming_check & ARMING_CHECK_GPS)) {
AP_Notify::flags.pre_arm_gps_check = true;
return true;
}
// check if flight mode requires GPS
bool gps_required = mode_requires_GPS(control_mode);
// if GPS failsafe will triggers even in stabilize mode we need GPS before arming
if (g.failsafe_gps_enabled == FS_GPS_LAND_EVEN_STABILIZE) {
gps_required = true;
}
#if AC_FENCE == ENABLED
// if circular fence is enabled we need GPS
if ((fence.get_enabled_fences() & AC_FENCE_TYPE_CIRCLE) != 0) {
gps_required = true;
}
#endif
// return true if GPS is not required
if (!gps_required) {
AP_Notify::flags.pre_arm_gps_check = true;
return true;
}
// check GPS is not glitching
if (gps_glitch.glitching()) {
if (display_failure) {
gcs_send_text_P(SEVERITY_HIGH,PSTR("PreArm: GPS Glitch"));
}
AP_Notify::flags.pre_arm_gps_check = false;
return false;
}
@ -433,14 +546,17 @@ static bool pre_arm_gps_checks(bool display_failure)
if (display_failure) {
gcs_send_text_P(SEVERITY_HIGH,PSTR("PreArm: Need 3D Fix"));
}
AP_Notify::flags.pre_arm_gps_check = false;
return false;
}
// check speed is below 50cm/s
float speed_cms = inertial_nav.get_velocity().length(); // speed according to inertial nav in cm/s
if (speed_cms == 0 || speed_cms > PREARM_MAX_VELOCITY_CMS) {
if (display_failure) {
gcs_send_text_P(SEVERITY_HIGH,PSTR("PreArm: Bad Velocity"));
}
AP_Notify::flags.pre_arm_gps_check = false;
return false;
}
@ -449,17 +565,38 @@ static bool pre_arm_gps_checks(bool display_failure)
if (display_failure) {
gcs_send_text_P(SEVERITY_HIGH,PSTR("PreArm: High GPS HDOP"));
}
AP_Notify::flags.pre_arm_gps_check = false;
return false;
}
// if we got here all must be ok
AP_Notify::flags.pre_arm_gps_check = true;
return true;
}
// arm_checks - perform final checks before arming
// always called just before arming. Return true if ok to arm
static bool arm_checks(bool display_failure)
static bool arm_checks(bool display_failure, bool arming_from_gcs)
{
// always check if the current mode allows arming
if (!mode_allows_arming(control_mode, arming_from_gcs)) {
if (display_failure) {
gcs_send_text_P(SEVERITY_HIGH,PSTR("Arm: Mode not armable"));
}
return false;
}
// always check if rotor is spinning on heli
#if FRAME_CONFIG == HELI_FRAME
// heli specific arming check
if (!motors.allow_arming()){
if (display_failure) {
gcs_send_text_P(SEVERITY_HIGH,PSTR("Arm: Rotor not spinning"));
}
return false;
}
#endif // HELI_FRAME
// succeed if arming checks are disabled
if (g.arming_check == ARMING_CHECK_NONE) {
return true;
@ -467,7 +604,7 @@ static bool arm_checks(bool display_failure)
// check Baro & inav alt are within 1m
if ((g.arming_check == ARMING_CHECK_ALL) || (g.arming_check & ARMING_CHECK_BARO)) {
if(fabs(inertial_nav.get_altitude() - baro_alt) > 100) {
if(fabs(inertial_nav.get_altitude() - baro_alt) > PREARM_MAX_ALT_DISPARITY_CM) {
if (display_failure) {
gcs_send_text_P(SEVERITY_HIGH,PSTR("Arm: Alt disparity"));
}
@ -475,11 +612,9 @@ static bool arm_checks(bool display_failure)
}
}
// check gps is ok if required - note this same check is also done in pre-arm checks
if ((g.arming_check == ARMING_CHECK_ALL) || (g.arming_check & ARMING_CHECK_GPS)) {
if ((mode_requires_GPS(control_mode) || g.failsafe_gps_enabled == FS_GPS_LAND_EVEN_STABILIZE) && !pre_arm_gps_checks(display_failure)) {
return false;
}
// check gps
if (!pre_arm_gps_checks(display_failure)) {
return false;
}
// check parameters
@ -546,6 +681,7 @@ static void init_disarm_motors()
// we are not in the air
set_land_complete(true);
set_land_complete_maybe(true);
// reset the mission
mission.reset();
@ -557,7 +693,9 @@ static void init_disarm_motors()
Log_Write_Event(DATA_DISARMED);
// suspend logging
DataFlash.EnableWrites(false);
if (!(g.log_bitmask & MASK_LOG_WHEN_DISARMED)) {
DataFlash.EnableWrites(false);
}
// disable gps velocity based centrefugal force compensation
ahrs.set_correct_centrifugal(false);

View File

@ -38,7 +38,7 @@ static void calc_wp_distance()
// get target from loiter or wpinav controller
if (control_mode == LOITER || control_mode == CIRCLE) {
wp_distance = wp_nav.get_loiter_distance_to_target();
}else if (control_mode == AUTO) {
}else if (control_mode == AUTO || control_mode == RTL || (control_mode == GUIDED && guided_mode == Guided_WP)) {
wp_distance = wp_nav.get_wp_distance_to_destination();
}else{
wp_distance = 0;
@ -51,7 +51,7 @@ static void calc_wp_bearing()
// get target from loiter or wpinav controller
if (control_mode == LOITER || control_mode == CIRCLE) {
wp_bearing = wp_nav.get_loiter_bearing_to_target();
} else if (control_mode == AUTO) {
} else if (control_mode == AUTO || control_mode == RTL || (control_mode == GUIDED && guided_mode == Guided_WP)) {
wp_bearing = wp_nav.get_wp_bearing_to_destination();
} else {
wp_bearing = 0;

View File

@ -38,6 +38,9 @@ static void init_rc_in()
// set default dead zones
default_dead_zones();
// initialise throttle_zero flag
ap.throttle_zero = true;
}
// init_rc_out -- initialise motors and check if pilot wants to perform ESC calibration
@ -62,13 +65,13 @@ static void init_rc_out()
// we will enter esc_calibrate mode on next reboot
g.esc_calibrate.set_and_save(1);
// display message on console
cliSerial->printf_P(PSTR("Entering ESC Calibration: please restart APM.\n"));
cliSerial->printf_P(PSTR("Entering ESC Cal: restart APM.\n"));
// turn on esc calibration notification
AP_Notify::flags.esc_calibration = true;
// block until we restart
while(1) { delay(5); }
}else{
cliSerial->printf_P(PSTR("ESC Calibration active: passing throttle through to ESCs.\n"));
cliSerial->printf_P(PSTR("ESC Cal: passing throttle through to ESCs.\n"));
// clear esc flag
g.esc_calibrate.set_and_save(0);
// pass through user throttle to escs
@ -97,9 +100,11 @@ void output_min()
static void read_radio()
{
static uint32_t last_update = 0;
static uint32_t last_update_ms = 0;
uint32_t tnow_ms = millis();
if (hal.rcin->new_input()) {
last_update = millis();
last_update_ms = tnow_ms;
ap.new_radio_frame = true;
uint16_t periods[8];
hal.rcin->read(periods,8);
@ -107,6 +112,7 @@ static void read_radio()
g.rc_2.set_pwm(periods[rcmap.pitch()-1]);
set_throttle_and_failsafe(periods[rcmap.throttle()-1]);
set_throttle_zero_flag(g.rc_3.control_in);
g.rc_4.set_pwm(periods[rcmap.yaw()-1]);
g.rc_5.set_pwm(periods[4]);
@ -114,6 +120,13 @@ static void read_radio()
g.rc_7.set_pwm(periods[6]);
g.rc_8.set_pwm(periods[7]);
// read channels 9 ~ 14
for (uint8_t i=8; i<RC_MAX_CHANNELS; i++) {
if (RC_Channel::rc_channel(i) != NULL) {
RC_Channel::rc_channel(i)->set_pwm(RC_Channel::rc_channel(i)->read());
}
}
// flag we must have an rc receiver attached
if (!failsafe.rc_override_active) {
ap.rc_receiver_present = true;
@ -122,7 +135,7 @@ static void read_radio()
// update output on any aux channels, for manual passthru
RC_Channel_aux::output_ch_all();
}else{
uint32_t elapsed = millis() - last_update;
uint32_t elapsed = tnow_ms - last_update_ms;
// turn on throttle failsafe if no update from the RC Radio for 500ms or 2000ms if we are using RC_OVERRIDE
if (((!failsafe.rc_override_active && (elapsed >= FS_RADIO_TIMEOUT_MS)) || (failsafe.rc_override_active && (elapsed >= FS_RADIO_RC_OVERRIDE_TIMEOUT_MS))) &&
(g.failsafe_throttle && motors.armed() && !failsafe.radio)) {
@ -174,6 +187,22 @@ static void set_throttle_and_failsafe(uint16_t throttle_pwm)
}
}
#define THROTTLE_ZERO_DEBOUNCE_TIME_MS 400
// set_throttle_zero_flag - set throttle_zero flag from debounced throttle control_in
static void set_throttle_zero_flag(int16_t throttle_control)
{
static uint32_t last_nonzero_throttle_ms = 0;
uint32_t tnow_ms = millis();
// if non-zero throttle immediately set as non-zero
if (throttle_control > 0) {
last_nonzero_throttle_ms = tnow_ms;
ap.throttle_zero = false;
} else if (tnow_ms - last_nonzero_throttle_ms > THROTTLE_ZERO_DEBOUNCE_TIME_MS) {
ap.throttle_zero = true;
}
}
static void trim_radio()
{
for (uint8_t i = 0; i < 30; i++) {

View File

@ -19,13 +19,14 @@ static void init_barometer(bool full_calibration)
}
// return barometric altitude in centimeters
static int32_t read_barometer(void)
static void read_barometer(void)
{
barometer.read();
if (g.log_bitmask & MASK_LOG_IMU) {
if (should_log(MASK_LOG_IMU)) {
Log_Write_Baro();
}
int32_t balt = barometer.get_altitude() * 100.0f;
baro_alt = barometer.get_altitude() * 100.0f;
baro_climbrate = barometer.get_climb_rate() * 100.0f;
// run glitch protection and update AP_Notify if home has been initialised
baro_glitch.check_alt();
@ -38,9 +39,6 @@ static int32_t read_barometer(void)
}
AP_Notify::flags.baro_glitching = report_baro_glitch;
}
// return altitude
return balt;
}
// return sonar altitude in centimeters

View File

@ -9,6 +9,7 @@
// Functions called from the setup menu
static int8_t setup_factory (uint8_t argc, const Menu::arg *argv);
static int8_t setup_show (uint8_t argc, const Menu::arg *argv);
static int8_t setup_set (uint8_t argc, const Menu::arg *argv);
#ifdef WITH_ESC_CALIB
static int8_t esc_calib (uint8_t argc, const Menu::arg *argv);
#endif
@ -19,6 +20,7 @@ const struct Menu::command setup_menu_commands[] PROGMEM = {
// ======= ===============
{"reset", setup_factory},
{"show", setup_show},
{"set", setup_set},
#ifdef WITH_ESC_CALIB
{"esc_calib", esc_calib},
#endif
@ -66,6 +68,65 @@ setup_factory(uint8_t argc, const Menu::arg *argv)
return(0);
}
//Set a parameter to a specified value. It will cast the value to the current type of the
//parameter and make sure it fits in case of INT8 and INT16
static int8_t setup_set(uint8_t argc, const Menu::arg *argv)
{
int8_t value_int8;
int16_t value_int16;
AP_Param *param;
enum ap_var_type p_type;
if(argc!=3)
{
cliSerial->printf_P(PSTR("Invalid command. Usage: set <name> <value>\n"));
return 0;
}
param = AP_Param::find(argv[1].str, &p_type);
if(!param)
{
cliSerial->printf_P(PSTR("Param not found: %s\n"), argv[1].str);
return 0;
}
switch(p_type)
{
case AP_PARAM_INT8:
value_int8 = (int8_t)(argv[2].i);
if(argv[2].i!=value_int8)
{
cliSerial->printf_P(PSTR("Value out of range for type INT8\n"));
return 0;
}
((AP_Int8*)param)->set_and_save(value_int8);
break;
case AP_PARAM_INT16:
value_int16 = (int16_t)(argv[2].i);
if(argv[2].i!=value_int16)
{
cliSerial->printf_P(PSTR("Value out of range for type INT16\n"));
return 0;
}
((AP_Int16*)param)->set_and_save(value_int16);
break;
//int32 and float don't need bounds checking, just use the value provoded by Menu::arg
case AP_PARAM_INT32:
((AP_Int32*)param)->set_and_save(argv[2].i);
break;
case AP_PARAM_FLOAT:
((AP_Float*)param)->set_and_save(argv[2].f);
break;
default:
cliSerial->printf_P(PSTR("Cannot set parameter of type %d.\n"), p_type);
break;
}
return 0;
}
// Print the current configuration.
// Called by the setup menu 'show' command.
static int8_t

View File

@ -288,12 +288,16 @@ static void init_ardupilot()
// mid-flight, so set the serial ports non-blocking once we are
// ready to fly
hal.uartA->set_blocking_writes(false);
hal.uartB->set_blocking_writes(false);
hal.uartC->set_blocking_writes(false);
if (hal.uartD != NULL) {
hal.uartD->set_blocking_writes(false);
}
cliSerial->print_P(PSTR("\nReady to FLY "));
// flag that initialisation has completed
ap.initialised = true;
}
@ -316,11 +320,17 @@ static void startup_ground(bool force_gyro_cal)
report_ins();
#endif
// reset ahrs gyro bias
if (force_gyro_cal) {
ahrs.reset_gyro_drift();
}
// setup fast AHRS gains to get right attitude
ahrs.set_fast_gains(true);
// set landed flag
set_land_complete(true);
set_land_complete_maybe(true);
}
// returns true if the GPS is ok and home position is set
@ -346,7 +356,7 @@ static void update_auto_armed()
return;
}
// if in stabilize or acro flight mode and throttle is zero, auto-armed should become false
if(manual_flight_mode(control_mode) && g.rc_3.control_in == 0 && !failsafe.radio) {
if(manual_flight_mode(control_mode) && ap.throttle_zero && !failsafe.radio) {
set_auto_armed(false);
}
}else{
@ -354,12 +364,12 @@ static void update_auto_armed()
#if FRAME_CONFIG == HELI_FRAME
// for tradheli if motors are armed and throttle is above zero and the motor is started, auto_armed should be true
if(motors.armed() && g.rc_3.control_in != 0 && motors.motor_runup_complete()) {
if(motors.armed() && !ap.throttle_zero && motors.motor_runup_complete()) {
set_auto_armed(true);
}
#else
// if motors are armed and throttle is above zero auto_armed should be true
if(motors.armed() && g.rc_3.control_in != 0) {
if(motors.armed() && !ap.throttle_zero) {
set_auto_armed(true);
}
#endif // HELI_FRAME
@ -399,3 +409,24 @@ static void telemetry_send(void)
(AP_Frsky_Telem::FrSkyProtocol)g.serial2_protocol.get());
#endif
}
/*
should we log a message type now?
*/
static bool should_log(uint32_t mask)
{
#if LOGGING_ENABLED == ENABLED
if (!(mask & g.log_bitmask) || in_mavlink_delay) {
return false;
}
bool ret = motors.armed() || (g.log_bitmask & MASK_LOG_WHEN_DISARMED) != 0;
if (ret && !DataFlash.logging_started() && !in_log_download) {
// we have to set in_mavlink_delay to prevent logging while
// writing headers
start_logging();
}
return ret;
#else
return false;
#endif
}

View File

@ -58,13 +58,13 @@ test_baro(uint8_t argc, const Menu::arg *argv)
while(1) {
delay(100);
alt = read_barometer();
read_barometer();
if (!barometer.healthy()) {
cliSerial->println_P(PSTR("not healthy"));
} else {
cliSerial->printf_P(PSTR("Alt: %0.2fm, Raw: %f Temperature: %.1f\n"),
alt / 100.0,
baro_alt / 100.0,
barometer.get_pressure(),
barometer.get_temperature());
}

View File

@ -144,7 +144,7 @@ void LogReader::process_plane(uint8_t type, uint8_t *data, uint16_t length)
memcpy(&msg, data, sizeof(msg));
wait_timestamp(msg.time_ms);
compass.setHIL(Vector3f(msg.mag_x - msg.offset_x, msg.mag_y - msg.offset_y, msg.mag_z - msg.offset_z));
compass.set_and_save_offsets(0, msg.offset_x, msg.offset_y, msg.offset_z);
compass.set_offsets(0, Vector3f(msg.offset_x, msg.offset_y, msg.offset_z));
break;
}
@ -186,7 +186,7 @@ void LogReader::process_rover(uint8_t type, uint8_t *data, uint16_t length)
memcpy(&msg, data, sizeof(msg));
wait_timestamp(msg.time_ms);
compass.setHIL(Vector3f(msg.mag_x - msg.offset_x, msg.mag_y - msg.offset_y, msg.mag_z - msg.offset_z));
compass.set_and_save_offsets(0, msg.offset_x, msg.offset_y, msg.offset_z);
compass.set_offsets(0, Vector3f(msg.offset_x, msg.offset_y, msg.offset_z));
break;
}
@ -216,7 +216,7 @@ void LogReader::process_copter(uint8_t type, uint8_t *data, uint16_t length)
memcpy(&msg, data, sizeof(msg));
wait_timestamp(msg.time_ms);
compass.setHIL(Vector3f(msg.mag_x - msg.offset_x, msg.mag_y - msg.offset_y, msg.mag_z - msg.offset_z));
compass.set_and_save_offsets(0, msg.offset_x, msg.offset_y, msg.offset_z);
compass.set_offsets(0, Vector3f(msg.offset_x, msg.offset_y, msg.offset_z));
break;
}
@ -250,6 +250,10 @@ void LogReader::process_copter(uint8_t type, uint8_t *data, uint16_t length)
bool LogReader::set_parameter(const char *name, float value)
{
if (strcmp(name, "GPS_TYPE") == 0) {
// ignore this one
return true;
}
enum ap_var_type var_type;
AP_Param *vp = AP_Param::find(name, &var_type);
if (vp == NULL) {
@ -470,6 +474,18 @@ bool LogReader::update(uint8_t &type)
break;
}
case LOG_AHR2_MSG: {
struct log_AHRS msg;
if(sizeof(msg) != f.length) {
printf("Bad AHR2 length %u should be %u\n", (unsigned)f.length, (unsigned)sizeof(msg));
exit(1);
}
memcpy(&msg, data, sizeof(msg));
wait_timestamp(msg.time_ms);
ahr2_attitude = Vector3f(msg.roll*0.01f, msg.pitch*0.01f, msg.yaw*0.01f);
break;
}
default:
if (vehicle == VEHICLE_PLANE) {

View File

@ -3,6 +3,7 @@ enum log_messages {
// plane specific messages
LOG_PLANE_ATTITUDE_MSG = 9,
LOG_PLANE_COMPASS_MSG = 11,
LOG_PLANE_COMPASS2_MSG = 15,
LOG_PLANE_AIRSPEED_MSG = 17,
// copter specific messages
@ -25,6 +26,7 @@ public:
bool wait_type(uint8_t type);
const Vector3f &get_attitude(void) const { return attitude; }
const Vector3f &get_ahr2_attitude(void) const { return ahr2_attitude; }
const Vector3f &get_inavpos(void) const { return inavpos; }
const Vector3f &get_sim_attitude(void) const { return sim_attitude; }
const float &get_relalt(void) const { return rel_altitude; }
@ -57,6 +59,7 @@ private:
struct log_Format formats[LOGREADER_MAX_FORMATS];
Vector3f attitude;
Vector3f ahr2_attitude;
Vector3f sim_attitude;
Vector3f inavpos;
float rel_altitude;

View File

@ -15,7 +15,8 @@ public:
k_param_ins,
k_param_ahrs,
k_param_airspeed,
k_param_NavEKF
k_param_NavEKF,
k_param_compass
};
AP_Int8 dummy;
};

View File

@ -34,6 +34,10 @@ const AP_Param::Info var_info[] PROGMEM = {
// @Path: ../libraries/AP_NavEKF/AP_NavEKF.cpp
GOBJECTN(ahrs.get_NavEKF(), NavEKF, "EKF_", NavEKF),
// @Group: COMPASS_
// @Path: ../libraries/AP_Compass/AP_Compass.cpp
GOBJECT(compass, "COMPASS_", Compass),
AP_VAREND
};

View File

@ -103,6 +103,8 @@ static struct {
float value;
} user_parameters[100];
// setup the var_info table
AP_Param param_loader(var_info);
static void usage(void)
{
@ -228,7 +230,7 @@ void setup()
ekf3f = fopen("EKF3.dat", "w");
ekf4f = fopen("EKF4.dat", "w");
fprintf(plotf, "time SIM.Roll SIM.Pitch SIM.Yaw BAR.Alt FLIGHT.Roll FLIGHT.Pitch FLIGHT.Yaw FLIGHT.dN FLIGHT.dE FLIGHT.Alt DCM.Roll DCM.Pitch DCM.Yaw EKF.Roll EKF.Pitch EKF.Yaw INAV.dN INAV.dE INAV.Alt EKF.dN EKF.dE EKF.Alt\n");
fprintf(plotf, "time SIM.Roll SIM.Pitch SIM.Yaw BAR.Alt FLIGHT.Roll FLIGHT.Pitch FLIGHT.Yaw FLIGHT.dN FLIGHT.dE FLIGHT.Alt AHR2.Roll AHR2.Pitch AHR2.Yaw DCM.Roll DCM.Pitch DCM.Yaw EKF.Roll EKF.Pitch EKF.Yaw INAV.dN INAV.dE INAV.Alt EKF.dN EKF.dE EKF.Alt\n");
fprintf(plotf2, "time E1 E2 E3 VN VE VD PN PE PD GX GY GZ WN WE MN ME MD MX MY MZ E1ref E2ref E3ref\n");
fprintf(ekf1f, "timestamp TimeMS Roll Pitch Yaw VN VE VD PN PE PD GX GY GZ\n");
fprintf(ekf2f, "timestamp TimeMS AX AY AZ VWN VWE MN ME MD MX MY MZ\n");
@ -391,10 +393,13 @@ void loop()
barometer.get_altitude(),
LogReader.get_attitude().x,
LogReader.get_attitude().y,
LogReader.get_attitude().z,
wrap_180_cd(LogReader.get_attitude().z*100)*0.01f,
LogReader.get_inavpos().x,
LogReader.get_inavpos().y,
LogReader.get_relalt(),
LogReader.get_ahr2_attitude().x,
LogReader.get_ahr2_attitude().y,
wrap_180_cd(LogReader.get_ahr2_attitude().z*100)*0.01f,
degrees(DCM_attitude.x),
degrees(DCM_attitude.y),
degrees(DCM_attitude.z),

View File

@ -65,3 +65,10 @@ ACRO_LOCKING 1
ELEVON_OUTPUT 0
VTAIL_OUTPUT 0
SKIP_GYRO_CAL 1
# we need small INS_ACC offsets so INS is recognised as being calibrated
INS_ACCOFFS_X 0.001
INS_ACCOFFS_Y 0.001
INS_ACCOFFS_Z 0.001
INS_ACCSCAL_X 1.001
INS_ACCSCAL_Y 1.001
INS_ACCSCAL_Z 1.001

View File

@ -18,3 +18,10 @@ MODE6 0
STEER2SRV_P 1.8
SIM_GPS_DELAY 2
NAVL1_PERIOD 6
# we need small INS_ACC offsets so INS is recognised as being calibrated
INS_ACCOFFS_X 0.001
INS_ACCOFFS_Y 0.001
INS_ACCOFFS_Z 0.001
INS_ACCSCAL_X 1.001
INS_ACCSCAL_Y 1.001
INS_ACCSCAL_Z 1.001

View File

@ -160,7 +160,7 @@ def fly_square(mavproxy, mav, side=50, timeout=120):
save_wp(mavproxy, mav)
# switch back to stabilize mode
mavproxy.send('rc 3 1400\n')
mavproxy.send('rc 3 1430\n')
mavproxy.send('switch 6\n')
wait_mode(mav, 'STABILIZE')
@ -620,7 +620,7 @@ def fly_simple(mavproxy, mav, side=50, timeout=120):
# switch to stabilize mode
mavproxy.send('switch 6\n')
wait_mode(mav, 'STABILIZE')
mavproxy.send('rc 3 1400\n')
mavproxy.send('rc 3 1430\n')
# fly south 50m
print("# Flying south %u meters" % side)
@ -685,7 +685,7 @@ def fly_super_simple(mavproxy, mav, timeout=45):
# switch to stabilize mode
mavproxy.send('switch 6\n')
wait_mode(mav, 'STABILIZE')
mavproxy.send('rc 3 1400\n')
mavproxy.send('rc 3 1430\n')
# start copter yawing slowly
mavproxy.send('rc 4 1550\n')

View File

@ -48,6 +48,13 @@ SIM_WIND_SPD 0
SIM_WIND_TURB 0
SIM_BARO_RND 0
SIM_MAG_RND 0
# we need small INS_ACC offsets so INS is recognised as being calibrated
INS_ACCOFFS_X 0.001
INS_ACCOFFS_Y 0.001
INS_ACCOFFS_Z 0.001
INS_ACCSCAL_X 1.001
INS_ACCSCAL_Y 1.001
INS_ACCSCAL_Z 1.001
# flightmodes
# switch 1 Circle
# switch 2 LAND

View File

@ -46,6 +46,13 @@ SIM_WIND_SPD 0
SIM_WIND_TURB 0
SIM_BARO_RND 0
SIM_MAG_RND 0
# we need small INS_ACC offsets so INS is recognised as being calibrated
INS_ACCOFFS_X 0.001
INS_ACCOFFS_Y 0.001
INS_ACCOFFS_Z 0.001
INS_ACCSCAL_X 1.001
INS_ACCSCAL_Y 1.001
INS_ACCSCAL_Z 1.001
# flightmodes
# switch 1 Circle
# switch 2 LAND

View File

@ -13,8 +13,14 @@ elif [ -x /usr/bin/konsole ]; then
/usr/bin/konsole --hold -e $*
elif [ -x /usr/bin/gnome-terminal ]; then
/usr/bin/gnome-terminal -e "$*"
elif [ -n "$STY" ]; then
# We are running inside of screen, try to start it there
/usr/bin/screen -X screen -t $name $*
else
echo "ERROR: Please install xterm"
exit 1
filename="/tmp/$name.log"
echo "Window access not found, logging to $filename"
cmd="$1"
shift
( run_cmd.sh $cmd $* &>$filename < /dev/null ) &
fi
exit 0

View File

@ -0,0 +1,31 @@
#!/bin/bash
# useful script to test all the different build types that we support.
# This helps when doing large merges
# Andrew Tridgell, November 2011
. config.mk
set -e
set -x
echo "Testing ArduPlane build"
pushd ArduCopter
make configure
for b in all apm2 sitl; do
pwd
make clean
make $b -j4
done
popd
for d in ArduCopter; do
pushd $d
make clean
make sitl -j4
make clean
make px4-cleandep
make px4-v2
popd
done
exit 0

View File

@ -0,0 +1,277 @@
#!/bin/bash
# script to build the latest binaries for each vehicle type, ready to upload
# Andrew Tridgell, March 2013
export PATH=$PATH:/bin:/usr/bin
export TMPDIR=$PWD/build.tmp.$$
echo $TMDIR
rm -rf $TMPDIR
echo "Building in $TMPDIR"
date
git checkout master
githash=$(git rev-parse HEAD)
hdate=$(date +"%Y-%m/%Y-%m-%d-%H:%m")
mkdir -p binaries/$hdate
binaries=$PWD/../buildlogs/binaries
error_count=0
. config.mk
# checkout the right version of the tree
checkout() {
branch="$1"
git stash
if [ "$branch" = "master" ]; then
vbranch="master"
vbranch2="master"
fi
if [ "$branch" = "for_merge" ]; then
vbranch="for_merge"
vbranch2="for_merge"
fi
if [ "$branch" = "for_merge-3.2" ]; then
vbranch="for_merge-3.2"
vbranch2="for_merge"
fi
if [ "$branch" = "tone_alarm" ]; then
vbranch="ToneAlarm"
vbranch2="ToneAlarm"
fi
if [ "$branch" = "tone_alarm-3.2" ]; then
vbranch="ToneAlarm-3.2"
vbranch2="ToneAlarm"
fi
echo "Checkout with branch $branch"
git remote update
git checkout -B "$vbranch" remotes/origin/"$vbranch"
git pull -v --progress "origin" "$vbranch" || return 1
git log -1
pushd ../../vrbrain_nuttx
git remote update
git checkout -B "$vbranch2" remotes/origin/"$vbranch2"
git pull -v --progress "origin" "$vbranch2" || {
popd
return 1
}
git log -1
popd
return 0
}
# check if we should skip this build because we have already
# built this version
skip_build() {
[ "$FORCE_BUILD" = "1" ] && return 1
tag="$1"
ddir="$2"
bname=$(basename $ddir)
ldir=$(dirname $(dirname $(dirname $ddir)))/$tag/$bname
[ -d "$ldir" ] || {
echo "$ldir doesn't exist - building"
return 1
}
oldversion=$(cat "$ldir/git-version.txt" | head -1)
newversion=$(git log -1 | head -1)
[ "$oldversion" = "$newversion" ] && {
echo "Skipping build - version match $newversion"
return 0
}
echo "$ldir needs rebuild"
return 1
}
addfwversion() {
destdir="$1"
git log -1 > "$destdir/git-version.txt"
[ -f APM_Config.h ] && {
version=$(grep 'define.THISFIRMWARE' *.pde 2> /dev/null | cut -d'"' -f2)
echo >> "$destdir/git-version.txt"
echo "APMVERSION: $version" >> "$destdir/git-version.txt"
}
}
# copy the built firmware to the right directory
copyit() {
file="$1"
dir="$2"
tag="$3"
bname=$(basename $dir)
tdir=$(dirname $(dirname $(dirname $dir)))/$tag/$bname
if [ "$tag" = "latest" ]; then
mkdir -p "$dir"
/bin/cp "$file" "$dir"
addfwversion "$dir"
fi
echo "Copying $file to $tdir"
mkdir -p "$tdir"
addfwversion "$tdir"
rsync "$file" "$tdir"
}
# build plane binaries
build_arduplane() {
tag="$1"
echo "Building ArduPlane $tag binaries"
pushd ArduPlane
test -n "$VRBRAIN_ROOT" && {
echo "Building ArduPlane VRBRAIN binaries"
ddir=$binaries/Plane/$hdate/VRX
checkout $tag || {
echo "Failed checkout of ArduPlane VRBRAIN $tag"
error_count=$((error_count+1))
continue
}
skip_build $tag $ddir || {
make vrbrain-clean &&
make vrbrain || {
echo "Failed build of ArduPlane VRBRAIN $tag"
error_count=$((error_count+1))
continue
}
copyit ArduPlane-vrbrain-v45.vrx $ddir $tag &&
copyit ArduPlane-vrbrain-v45.bin $ddir $tag &&
copyit ArduPlane-vrbrain-v45.hex $ddir $tag &&
copyit ArduPlane-vrbrain-v51.vrx $ddir $tag &&
copyit ArduPlane-vrbrain-v51.bin $ddir $tag &&
copyit ArduPlane-vrbrain-v51.hex $ddir $tag &&
copyit ArduPlane-vrbrain-v51P.vrx $ddir $tag &&
copyit ArduPlane-vrbrain-v51P.bin $ddir $tag &&
copyit ArduPlane-vrbrain-v51P.hex $ddir $tag &&
copyit ArduPlane-vrbrain-v51Pro.vrx $ddir $tag &&
copyit ArduPlane-vrbrain-v51Pro.bin $ddir $tag &&
copyit ArduPlane-vrbrain-v51Pro.hex $ddir $tag &&
copyit ArduPlane-vrbrain-v51ProP.vrx $ddir $tag &&
copyit ArduPlane-vrbrain-v51ProP.bin $ddir $tag &&
copyit ArduPlane-vrbrain-v51ProP.hex $ddir $tag &&
copyit ArduPlane-vrubrain-v51.vrx $ddir $tag &&
copyit ArduPlane-vrubrain-v51.bin $ddir $tag &&
copyit ArduPlane-vrubrain-v51.hex $ddir $tag &&
copyit ArduPlane-vrubrain-v51P.vrx $ddir $tag &&
copyit ArduPlane-vrubrain-v51P.bin $ddir $tag &&
copyit ArduPlane-vrubrain-v51P.hex $ddir $tag
}
}
checkout "master"
popd
}
# build copter binaries
build_arducopter() {
tag="$1"
echo "Building ArduCopter $tag binaries from $(pwd)"
pushd ArduCopter
frames="quad tri hexa y6 octa octa-quad heli"
test -n "$VRBRAIN_ROOT" && {
checkout $tag || {
echo "Failed checkout of ArduCopter VRBRAIN $tag"
error_count=$((error_count+1))
checkout "master"
popd
return
}
make vrbrain-clean || return
for f in $frames quad-hil heli-hil; do
echo "Building ArduCopter VRBRAIN-$f binaries"
ddir="$binaries/Copter/$hdate/VRX-$f"
skip_build $tag $ddir && continue
rm -rf ../Build.ArduCopter
make vrbrain-$f || {
echo "Failed build of ArduCopter VRBRAIN $tag"
error_count=$((error_count+1))
continue
}
copyit ArduCopter-vrbrain-v45.vrx $ddir $tag &&
copyit ArduCopter-vrbrain-v45.bin $ddir $tag &&
copyit ArduCopter-vrbrain-v45.hex $ddir $tag &&
copyit ArduCopter-vrbrain-v51.vrx $ddir $tag &&
copyit ArduCopter-vrbrain-v51.bin $ddir $tag &&
copyit ArduCopter-vrbrain-v51.hex $ddir $tag &&
copyit ArduCopter-vrbrain-v51P.vrx $ddir $tag &&
copyit ArduCopter-vrbrain-v51P.bin $ddir $tag &&
copyit ArduCopter-vrbrain-v51P.hex $ddir $tag &&
copyit ArduCopter-vrbrain-v51Pro.vrx $ddir $tag &&
copyit ArduCopter-vrbrain-v51Pro.bin $ddir $tag &&
copyit ArduCopter-vrbrain-v51Pro.hex $ddir $tag &&
copyit ArduCopter-vrbrain-v51ProP.vrx $ddir $tag &&
copyit ArduCopter-vrbrain-v51ProP.bin $ddir $tag &&
copyit ArduCopter-vrbrain-v51ProP.hex $ddir $tag &&
copyit ArduCopter-vrubrain-v51.vrx $ddir $tag &&
copyit ArduCopter-vrubrain-v51.bin $ddir $tag &&
copyit ArduCopter-vrubrain-v51.hex $ddir $tag &&
copyit ArduCopter-vrubrain-v51P.vrx $ddir $tag &&
copyit ArduCopter-vrubrain-v51P.bin $ddir $tag &&
copyit ArduCopter-vrubrain-v51P.hex $ddir $tag
done
}
checkout "master"
popd
}
# build rover binaries
build_rover() {
tag="$1"
echo "Building APMrover2 $tag binaries from $(pwd)"
pushd APMrover2
test -n "$VRBRAIN_ROOT" && {
echo "Building APMrover2 VRBRAIN binaries"
ddir=$binaries/Rover/$hdate/VRX
checkout $tag || {
checkout "master"
popd
return
}
skip_build $tag $ddir || {
make vrbrain-clean &&
make vrbrain || {
echo "Failed build of APMrover2 VRBRAIN $tag"
error_count=$((error_count+1))
checkout APMrover2 "latest" ""
popd
return
}
copyit APMrover2-vrbrain-v45.vrx $ddir $tag &&
copyit APMrover2-vrbrain-v45.bin $ddir $tag &&
copyit APMrover2-vrbrain-v45.hex $ddir $tag &&
copyit APMrover2-vrbrain-v51.vrx $ddir $tag &&
copyit APMrover2-vrbrain-v51.bin $ddir $tag &&
copyit APMrover2-vrbrain-v51.hex $ddir $tag &&
copyit APMrover2-vrbrain-v51P.vrx $ddir $tag &&
copyit APMrover2-vrbrain-v51P.bin $ddir $tag &&
copyit APMrover2-vrbrain-v51P.hex $ddir $tag &&
copyit APMrover2-vrbrain-v51Pro.vrx $ddir $tag &&
copyit APMrover2-vrbrain-v51Pro.bin $ddir $tag &&
copyit APMrover2-vrbrain-v51Pro.hex $ddir $tag &&
copyit APMrover2-vrbrain-v51ProP.vrx $ddir $tag &&
copyit APMrover2-vrbrain-v51ProP.bin $ddir $tag &&
copyit APMrover2-vrbrain-v51ProP.hex $ddir $tag &&
copyit APMrover2-vrubrain-v51.vrx $ddir $tag &&
copyit APMrover2-vrubrain-v51.bin $ddir $tag &&
copyit APMrover2-vrubrain-v51.hex $ddir $tag &&
copyit APMrover2-vrubrain-v51P.vrx $ddir $tag &&
copyit APMrover2-vrubrain-v51P.bin $ddir $tag &&
copyit APMrover2-vrubrain-v51P.hex $ddir $tag
}
}
checkout "master"
popd
}
for build in for_merge for_merge-3.2 tone_alarm tone_alarm-3.2; do
build_arduplane $build
build_arducopter $build
build_rover $build
done
rm -rf $TMPDIR
exit $error_count

View File

@ -6,6 +6,7 @@ OPT="/opt"
BASE_PKGS="gawk make git arduino-core curl"
SITL_PKGS="g++ python-pip python-matplotlib python-serial python-wxgtk2.8 python-scipy python-opencv python-numpy python-pyparsing ccache"
AVR_PKGS="gcc-avr binutils-avr avr-libc"
PYTHON_PKGS="pymavlink MAVProxy droneapi"
PX4_PKGS="python-serial python-argparse openocd flex bison libncurses5-dev \
autoconf texinfo build-essential libftdi-dev libtool zlib1g-dev \
@ -15,9 +16,9 @@ ASSUME_YES=false
# GNU Tools for ARM Embedded Processors
# (see https://launchpad.net/gcc-arm-embedded/)
ARM_ROOT="gcc-arm-none-eabi-4_8-2013q4"
ARM_TARBALL="$ARM_ROOT-20131204-linux.tar.bz2"
ARM_TARBALL_URL="https://launchpad.net/gcc-arm-embedded/4.8/4.8-2013-q4-major/+download/$ARM_TARBALL"
ARM_ROOT="gcc-arm-none-eabi-4_7-2014q2"
ARM_TARBALL="$ARM_ROOT-20140408-linux.tar.bz2"
ARM_TARBALL_URL="http://firmware.diydrones.com/Tools/PX4-tools/$ARM_TARBALL"
# Ardupilot Tools
ARDUPILOT_TOOLS="ardupilot/Tools/autotest"
@ -57,7 +58,7 @@ sudo usermod -a -G dialout $USER
$APT_GET remove modemmanager
$APT_GET update
$APT_GET install $BASE_PKGS $SITL_PKGS $PX4_PKGS $UBUNTU64_PKGS
$APT_GET install $BASE_PKGS $SITL_PKGS $PX4_PKGS $UBUNTU64_PKGS $AVR_PKGS
sudo pip -q install $PYTHON_PKGS
@ -69,6 +70,10 @@ if [ ! -d PX4NuttX ]; then
git clone https://github.com/diydrones/PX4NuttX.git
fi
if [ ! -d uavcan ]; then
git clone https://github.com/diydrones/uavcan.git
fi
if [ ! -d VRNuttX ]; then
git clone https://github.com/virtualrobotix/vrbrain_nuttx.git VRNuttX
fi

View File

@ -3,8 +3,6 @@
#include "AC_AttitudeControl.h"
#include <AP_HAL.h>
extern const AP_HAL::HAL& hal;
// table of user settable parameters
const AP_Param::GroupInfo AC_AttitudeControl::var_info[] PROGMEM = {
@ -382,18 +380,19 @@ void AC_AttitudeControl::rate_bf_roll_pitch_yaw(float roll_rate_bf, float pitch_
} else {
_acro_angle_switch = 4500;
integrate_bf_rate_error_to_angle_errors();
frame_conversion_bf_to_ef(_angle_bf_error, angle_ef_error);
_angle_ef_target.x = wrap_180_cd_float(angle_ef_error.x + _ahrs.roll_sensor);
_angle_ef_target.y = wrap_180_cd_float(angle_ef_error.y + _ahrs.pitch_sensor);
_angle_ef_target.z = wrap_360_cd_float(angle_ef_error.z + _ahrs.yaw_sensor);
if (frame_conversion_bf_to_ef(_angle_bf_error, angle_ef_error)) {
_angle_ef_target.x = wrap_180_cd_float(angle_ef_error.x + _ahrs.roll_sensor);
_angle_ef_target.y = wrap_180_cd_float(angle_ef_error.y + _ahrs.pitch_sensor);
_angle_ef_target.z = wrap_360_cd_float(angle_ef_error.z + _ahrs.yaw_sensor);
}
if (_angle_ef_target.y > 9000.0f) {
_angle_ef_target.x = wrap_180_cd_float(_angle_ef_target.x + 18000.0f);
_angle_ef_target.y = wrap_180_cd_float(18000.0f - _angle_ef_target.x);
_angle_ef_target.y = wrap_180_cd_float(18000.0f - _angle_ef_target.y);
_angle_ef_target.z = wrap_360_cd_float(_angle_ef_target.z + 18000.0f);
}
if (_angle_ef_target.y < -9000.0f) {
_angle_ef_target.x = wrap_180_cd_float(_angle_ef_target.x + 18000.0f);
_angle_ef_target.y = wrap_180_cd_float(-18000.0f - _angle_ef_target.x);
_angle_ef_target.y = wrap_180_cd_float(-18000.0f - _angle_ef_target.y);
_angle_ef_target.z = wrap_360_cd_float(_angle_ef_target.z + 18000.0f);
}
}
@ -432,12 +431,17 @@ void AC_AttitudeControl::frame_conversion_ef_to_bf(const Vector3f& ef_vector, Ve
}
// frame_conversion_bf_to_ef - converts body frame vector to earth frame vector
void AC_AttitudeControl::frame_conversion_bf_to_ef(const Vector3f& bf_vector, Vector3f& ef_vector)
bool AC_AttitudeControl::frame_conversion_bf_to_ef(const Vector3f& bf_vector, Vector3f& ef_vector)
{
// convert earth frame rates to body frame rates
// avoid divide by zero
if (_ahrs.cos_pitch() == 0.0f) {
return false;
}
// convert earth frame angle or rates to body frame
ef_vector.x = bf_vector.x + _ahrs.sin_roll() * (_ahrs.sin_pitch()/_ahrs.cos_pitch()) * bf_vector.y + _ahrs.cos_roll() * (_ahrs.sin_pitch()/_ahrs.cos_pitch()) * bf_vector.z;
ef_vector.y = _ahrs.cos_roll() * bf_vector.y - _ahrs.sin_roll() * bf_vector.z;
ef_vector.z = (_ahrs.sin_roll() / _ahrs.cos_pitch()) * bf_vector.y + (_ahrs.cos_roll() / _ahrs.cos_pitch()) * bf_vector.z;
return true;
}
//
@ -668,7 +672,6 @@ void AC_AttitudeControl::accel_limiting(bool enable_limits)
_accel_rp_max = 0.0f;
_accel_y_max = 0.0f;
}
hal.console->printf_P(PSTR("AccLim:%d"),(int)enable_limits);
}
//

View File

@ -116,11 +116,12 @@ public:
//
// earth-frame <-> body-frame conversion functions
//
// frame_conversion_ef_to_bf - converts earth frame rate targets to body frame rate targets
// frame_conversion_ef_to_bf - converts earth frame angles or rates to body frame
void frame_conversion_ef_to_bf(const Vector3f& ef_vector, Vector3f &bf_vector);
// frame_conversion_bf_to_ef - converts body frame rate targets to earth frame rate targets
void frame_conversion_bf_to_ef(const Vector3f& bf_vector, Vector3f &ef_vector);
// frame_conversion_bf_to_ef - converts body frame angles or rates to earth frame
// returns false if conversion fails due to gimbal lock
bool frame_conversion_bf_to_ef(const Vector3f& bf_vector, Vector3f &ef_vector);
//
// public accessor functions

View File

@ -10,7 +10,7 @@ const AP_Param::GroupInfo AC_AttitudeControl_Heli::var_info[] PROGMEM = {
// @DisplayName: Angle Rate Roll-Pitch max
// @Description: maximum rotation rate in roll/pitch axis requested by angle controller used in stabilize, loiter, rtl, auto flight modes
// @Units: Centi-Degrees/Sec
// @Range: 90000 250000
// @Range: 9000 36000
// @Increment: 500
// @User: Advanced
AP_GROUPINFO("RATE_RP_MAX", 0, AC_AttitudeControl_Heli, _angle_rate_rp_max, AC_ATTITUDE_CONTROL_RATE_RP_MAX_DEFAULT),
@ -19,7 +19,7 @@ const AP_Param::GroupInfo AC_AttitudeControl_Heli::var_info[] PROGMEM = {
// @DisplayName: Angle Rate Yaw max
// @Description: maximum rotation rate in roll/pitch axis requested by angle controller used in stabilize, loiter, rtl, auto flight modes
// @Units: Centi-Degrees/Sec
// @Range: 90000 250000
// @Range: 4500 18000
// @Increment: 500
// @User: Advanced
AP_GROUPINFO("RATE_Y_MAX", 1, AC_AttitudeControl_Heli, _angle_rate_y_max, AC_ATTITUDE_CONTROL_RATE_Y_MAX_DEFAULT),
@ -37,8 +37,9 @@ const AP_Param::GroupInfo AC_AttitudeControl_Heli::var_info[] PROGMEM = {
// @DisplayName: Acceleration Max for Roll/Pitch
// @Description: Maximum acceleration in roll/pitch axis
// @Units: Centi-Degrees/Sec/Sec
// @Range: 20000 100000
// @Increment: 100
// @Range: 0 180000
// @Increment: 1000
// @Values: 0:Disabled, 72000:Slow, 108000:Medium, 162000:Fast
// @User: Advanced
AP_GROUPINFO("ACCEL_RP_MAX", 3, AC_AttitudeControl_Heli, _accel_rp_max, AC_ATTITUDE_CONTROL_ACCEL_RP_MAX_DEFAULT),
@ -46,8 +47,9 @@ const AP_Param::GroupInfo AC_AttitudeControl_Heli::var_info[] PROGMEM = {
// @DisplayName: Acceleration Max for Yaw
// @Description: Maximum acceleration in yaw axis
// @Units: Centi-Degrees/Sec/Sec
// @Range: 20000 100000
// @Increment: 100
// @Range: 0 72000
// @Values: 0:Disabled, 18000:Slow, 36000:Medium, 54000:Fast
// @Increment: 1000
// @User: Advanced
AP_GROUPINFO("ACCEL_Y_MAX", 4, AC_AttitudeControl_Heli, _accel_y_max, AC_ATTITUDE_CONTROL_ACCEL_Y_MAX_DEFAULT),
@ -61,6 +63,65 @@ const AP_Param::GroupInfo AC_AttitudeControl_Heli::var_info[] PROGMEM = {
AP_GROUPEND
};
// passthrough_bf_roll_pitch_rate_yaw - passthrough the pilots roll and pitch inputs directly to swashplate for flybar acro mode
void AC_AttitudeControl_Heli::passthrough_bf_roll_pitch_rate_yaw(float roll_passthrough, float pitch_passthrough, float yaw_rate_bf)
{
// store roll and pitch passthroughs
_passthrough_roll = roll_passthrough;
_passthrough_pitch = pitch_passthrough;
// set rate controller to use pass through
_flags_heli.flybar_passthrough = true;
// set bf rate targets to current body frame rates (i.e. relax and be ready for vehicle to switch out of acro)
_rate_bf_desired.x = _ahrs.get_gyro().x * AC_ATTITUDE_CONTROL_DEGX100;
_rate_bf_desired.y = _ahrs.get_gyro().y * AC_ATTITUDE_CONTROL_DEGX100;
// accel limit desired yaw rate
if (_accel_y_max > 0.0f) {
float rate_change_limit = _accel_y_max * _dt;
float rate_change = yaw_rate_bf - _rate_bf_desired.z;
rate_change = constrain_float(rate_change, -rate_change_limit, rate_change_limit);
_rate_bf_desired.z += rate_change;
} else {
_rate_bf_desired.z = yaw_rate_bf;
}
integrate_bf_rate_error_to_angle_errors();
_angle_bf_error.x = 0;
_angle_bf_error.y = 0;
// update our earth-frame angle targets
Vector3f angle_ef_error;
if (frame_conversion_bf_to_ef(_angle_bf_error, angle_ef_error)) {
_angle_ef_target.x = wrap_180_cd_float(angle_ef_error.x + _ahrs.roll_sensor);
_angle_ef_target.y = wrap_180_cd_float(angle_ef_error.y + _ahrs.pitch_sensor);
_angle_ef_target.z = wrap_360_cd_float(angle_ef_error.z + _ahrs.yaw_sensor);
}
// handle flipping over pitch axis
if (_angle_ef_target.y > 9000.0f) {
_angle_ef_target.x = wrap_180_cd_float(_angle_ef_target.x + 18000.0f);
_angle_ef_target.y = wrap_180_cd_float(18000.0f - _angle_ef_target.x);
_angle_ef_target.z = wrap_360_cd_float(_angle_ef_target.z + 18000.0f);
}
if (_angle_ef_target.y < -9000.0f) {
_angle_ef_target.x = wrap_180_cd_float(_angle_ef_target.x + 18000.0f);
_angle_ef_target.y = wrap_180_cd_float(-18000.0f - _angle_ef_target.x);
_angle_ef_target.z = wrap_360_cd_float(_angle_ef_target.z + 18000.0f);
}
// convert body-frame angle errors to body-frame rate targets
update_rate_bf_targets();
// set body-frame roll/pitch rate target to current desired rates which are the vehicle's actual rates
_rate_bf_target.x = _rate_bf_desired.x;
_rate_bf_target.y = _rate_bf_desired.y;
// add desired target to yaw
_rate_bf_target.z += _rate_bf_desired.z;
}
//
// rate controller (body-frame) methods
//
@ -70,8 +131,13 @@ const AP_Param::GroupInfo AC_AttitudeControl_Heli::var_info[] PROGMEM = {
void AC_AttitudeControl_Heli::rate_controller_run()
{
// call rate controllers and send output to motors object
// To-Do: should the outputs from get_rate_roll, pitch, yaw be int16_t which is the input to the motors library?
rate_bf_to_motor_roll_pitch(_rate_bf_target.x, _rate_bf_target.y);
// if using a flybar passthrough roll and pitch directly to motors
if (_flags_heli.flybar_passthrough) {
_motors.set_roll(_passthrough_roll);
_motors.set_pitch(_passthrough_pitch);
} else {
rate_bf_to_motor_roll_pitch(_rate_bf_target.x, _rate_bf_target.y);
}
_motors.set_yaw(rate_bf_to_motor_yaw(_rate_bf_target.z));
}

View File

@ -26,11 +26,15 @@ public:
) :
AC_AttitudeControl(ahrs, aparm, motors,
p_angle_roll, p_angle_pitch, p_angle_yaw,
pid_rate_roll, pid_rate_pitch, pid_rate_yaw)
pid_rate_roll, pid_rate_pitch, pid_rate_yaw),
_passthrough_roll(0), _passthrough_pitch(0)
{
AP_Param::setup_object_defaults(this, var_info);
}
// passthrough_bf_roll_pitch_rate_yaw - roll and pitch are passed through directly, body-frame rate target for yaw
void passthrough_bf_roll_pitch_rate_yaw(float roll_passthrough, float pitch_passthrough, float yaw_rate_bf);
// rate_controller_run - run lowest level body-frame rate controller and send outputs to the motors
// should be called at 100hz or more
virtual void rate_controller_run();
@ -38,6 +42,9 @@ public:
// use_leaky_i - controls whether we use leaky i term for body-frame to motor output stage
void use_leaky_i(bool leaky_i) { _flags_heli.leaky_i = leaky_i; }
// use_flybar_passthrough - controls whether we pass-through control inputs to swash-plate
void use_flybar_passthrough(bool passthrough) { _flags_heli.flybar_passthrough = passthrough; }
void update_feedforward_filter_rates(float time_step);
// user settable parameters
@ -47,10 +54,11 @@ private:
// To-Do: move these limits flags into the heli motors class
struct AttControlHeliFlags {
uint8_t limit_roll : 1; // 1 if we have requested larger roll angle than swash can physically move
uint8_t limit_pitch : 1; // 1 if we have requested larger pitch angle than swash can physically move
uint8_t limit_yaw : 1; // 1 if we have requested larger yaw angle than tail servo can physically move
uint8_t leaky_i : 1; // 1 if we should use leaky i term for body-frame rate to motor stage
uint8_t limit_roll : 1; // 1 if we have requested larger roll angle than swash can physically move
uint8_t limit_pitch : 1; // 1 if we have requested larger pitch angle than swash can physically move
uint8_t limit_yaw : 1; // 1 if we have requested larger yaw angle than tail servo can physically move
uint8_t leaky_i : 1; // 1 if we should use leaky i term for body-frame rate to motor stage
uint8_t flybar_passthrough : 1; // 1 if we should pass through pilots roll & pitch input directly to swash-plate
} _flags_heli;
//
@ -68,6 +76,7 @@ private:
// get_angle_boost - calculate total body frame throttle required to produce the given earth frame throttle
virtual int16_t get_angle_boost(int16_t throttle_pwm);
// LPF filters to act on Rate Feedforward terms to linearize output.
// Due to complicated aerodynamic effects, feedforwards acting too fast can lead
// to jerks on rate change requests.
@ -75,6 +84,9 @@ private:
LowPassFilterInt32 roll_feedforward_filter;
LowPassFilterInt32 yaw_feedforward_filter;
// pass through for roll and pitch
int16_t _passthrough_roll;
int16_t _passthrough_pitch;
};
#endif //AC_ATTITUDECONTROL_HELI_H

View File

@ -84,6 +84,10 @@ void AC_PosControl::set_dt(float delta_sec)
// update rate controller's d filter
_pid_alt_accel.set_d_lpf_alpha(POSCONTROL_ACCEL_Z_DTERM_FILTER, _dt);
// update rate z-axis velocity error and accel error filters
_vel_error_filter.set_cutoff_frequency(_dt,POSCONTROL_VEL_ERROR_CUTOFF_FREQ);
_accel_error_filter.set_cutoff_frequency(_dt,POSCONTROL_ACCEL_ERROR_CUTOFF_FREQ);
}
/// set_speed_z - sets maximum climb and descent rates
@ -118,6 +122,8 @@ void AC_PosControl::set_accel_z(float accel_cmss)
void AC_PosControl::set_alt_target_with_slew(float alt_cm, float dt)
{
float alt_change = alt_cm-_pos_target.z;
_vel_desired.z = constrain_float(alt_change * dt, _speed_down_cms, _speed_up_cms);
// adjust desired alt if motors have not hit their limits
if ((alt_change<0 && !_motors.limit.throttle_lower) || (alt_change>0 && !_motors.limit.throttle_upper)) {
@ -133,13 +139,21 @@ void AC_PosControl::set_alt_target_with_slew(float alt_cm, float dt)
/// should be called continuously (with dt set to be the expected time between calls)
/// actual position target will be moved no faster than the speed_down and speed_up
/// target will also be stopped if the motors hit their limits or leash length is exceeded
void AC_PosControl::set_alt_target_from_climb_rate(float climb_rate_cms, float dt)
void AC_PosControl::set_alt_target_from_climb_rate(float climb_rate_cms, float dt, bool force_descend)
{
// adjust desired alt if motors have not hit their limits
// To-Do: add check of _limit.pos_up and _limit.pos_down?
if ((climb_rate_cms<0 && !_motors.limit.throttle_lower) || (climb_rate_cms>0 && !_motors.limit.throttle_upper)) {
// To-Do: add check of _limit.pos_down?
if ((climb_rate_cms<0 && (!_motors.limit.throttle_lower || force_descend)) || (climb_rate_cms>0 && !_motors.limit.throttle_upper && !_limit.pos_up)) {
_pos_target.z += climb_rate_cms * dt;
}
// do not let target alt get above limit
if (_alt_max > 0 && _pos_target.z > _alt_max) {
_pos_target.z = _alt_max;
_limit.pos_up = true;
}
_vel_desired.z = climb_rate_cms;
}
// get_alt_error - returns altitude error in cm
@ -249,12 +263,6 @@ void AC_PosControl::pos_to_rate_z()
_limit.pos_up = false;
_limit.pos_down = false;
// do not let target alt get above limit
if (_alt_max > 0 && _pos_target.z > _alt_max) {
_pos_target.z = _alt_max;
_limit.pos_up = true;
}
// calculate altitude error
_pos_error.z = _pos_target.z - curr_alt;
@ -334,10 +342,12 @@ void AC_PosControl::rate_to_accel_z()
if (_flags.reset_rate_to_accel_z) {
// Reset Filter
_vel_error.z = 0;
_vel_error_filter.reset(0);
desired_accel = 0;
_flags.reset_rate_to_accel_z = false;
} else {
_vel_error.z = (_vel_target.z - curr_vel.z);
// calculate rate error and filter with cut off frequency of 2 Hz
_vel_error.z = _vel_error_filter.apply(_vel_target.z - curr_vel.z);
}
// calculate p
@ -365,11 +375,11 @@ void AC_PosControl::accel_to_throttle(float accel_target_z)
if (_flags.reset_accel_to_throttle) {
// Reset Filter
_accel_error.z = 0;
_accel_error_filter.reset(0);
_flags.reset_accel_to_throttle = false;
} else {
// calculate accel error and Filter with fc = 2 Hz
// To-Do: replace constant below with one that is adjusted for update rate
_accel_error.z = _accel_error.z + 0.11164f * (constrain_float(accel_target_z - z_accel_meas, -32000, 32000) - _accel_error.z);
_accel_error.z = _accel_error_filter.apply(constrain_float(accel_target_z - z_accel_meas, -32000, 32000));
}
// separately calculate p, i, d values for logging
@ -469,7 +479,7 @@ void AC_PosControl::get_stopping_point_xy(Vector3f &stopping_point) const
float vel_total = pythagorous2(curr_vel.x, curr_vel.y);
// avoid divide by zero by using current position if the velocity is below 10cm/s, kP is very low or acceleration is zero
if (kP <= 0.0f || _accel_cms <= 0.0f) {
if (kP <= 0.0f || _accel_cms <= 0.0f || vel_total == 0.0f) {
stopping_point.x = curr_pos.x;
stopping_point.y = curr_pos.y;
return;
@ -545,6 +555,7 @@ void AC_PosControl::update_xy_controller(bool use_desired_velocity)
uint32_t now = hal.scheduler->millis();
if ((now - _last_update_xy_ms) >= POSCONTROL_ACTIVE_TIMEOUT_MS) {
init_xy_controller();
now = _last_update_xy_ms;
}
// check if xy leash needs to be recalculated

View File

@ -40,6 +40,9 @@
#define POSCONTROL_VEL_UPDATE_TIME 0.020f // 50hz update rate on high speed CPUs (Pixhawk, Flymaple)
#define POSCONTROL_VEL_ERROR_CUTOFF_FREQ 4.0 // 4hz low-pass filter on velocity error
#define POSCONTROL_ACCEL_ERROR_CUTOFF_FREQ 2.0 // 2hz low-pass filter on accel error
class AC_PosControl
{
public:
@ -64,8 +67,8 @@ public:
///
/// set_alt_max - sets maximum altitude above home in cm
/// set to zero to disable limit
/// To-Do: update this intermittantly from main code after checking if fence is enabled/disabled
/// only enforced when set_alt_target_from_climb_rate is used
/// set to zero to disable limit
void set_alt_max(float alt) { _alt_max = alt; }
/// set_speed_z - sets maximum climb and descent rates
@ -106,7 +109,8 @@ public:
/// should be called continuously (with dt set to be the expected time between calls)
/// actual position target will be moved no faster than the speed_down and speed_up
/// target will also be stopped if the motors hit their limits or leash length is exceeded
void set_alt_target_from_climb_rate(float climb_rate_cms, float dt);
/// set force_descend to true during landing to allow target to move low enough to slow the motors
void set_alt_target_from_climb_rate(float climb_rate_cms, float dt, bool force_descend = false);
/// set_alt_target_to_current_alt - set altitude target to current altitude
void set_alt_target_to_current_alt() { _pos_target.z = _inav.get_altitude(); }
@ -367,6 +371,8 @@ private:
float _distance_to_target; // distance to position target - for reporting only
uint8_t _xy_step; // used to decide which portion of horizontal position controller to run during this iteration
float _dt_xy; // time difference in seconds between horizontal position updates
LowPassFilterFloat _vel_error_filter; // low-pass-filter on z-axis velocity error
LowPassFilterFloat _accel_error_filter; // low-pass-filter on z-axis accelerometer error
// velocity controller internal variables
uint8_t _vel_xyz_step; // used to decide which portion of velocity controller to run during this iteration

View File

@ -176,6 +176,16 @@ void AC_WPNav::init_loiter_target()
_pilot_accel_rgt_cms = 0;
}
/// loiter_soften_for_landing - reduce response for landing
void AC_WPNav::loiter_soften_for_landing()
{
const Vector3f& curr_pos = _inav.get_position();
// set target position to current position
_pos_control.set_xy_target(curr_pos.x, curr_pos.y);
_pos_control.freeze_ff_xy();
}
/// set_loiter_velocity - allows main code to pass the maximum velocity for loiter
void AC_WPNav::set_loiter_velocity(float velocity_cms)
{
@ -331,7 +341,7 @@ void AC_WPNav::wp_and_spline_init()
void AC_WPNav::set_speed_xy(float speed_cms)
{
// range check new target speed and update position controller
if (_wp_speed_cms >= WPNAV_WP_SPEED_MIN) {
if (speed_cms >= WPNAV_WP_SPEED_MIN) {
_wp_speed_cms = speed_cms;
_pos_control.set_speed_xy(_wp_speed_cms);
// flag that wp leash must be recalculated
@ -404,6 +414,33 @@ void AC_WPNav::set_wp_origin_and_destination(const Vector3f& origin, const Vecto
_limited_speed_xy_cms = constrain_float(speed_along_track,0,_wp_speed_cms);
}
/// shift_wp_origin_to_current_pos - shifts the origin and destination so the origin starts at the current position
/// used to reset the position just before takeoff
/// relies on set_wp_destination or set_wp_origin_and_destination having been called first
void AC_WPNav::shift_wp_origin_to_current_pos()
{
// return immediately if vehicle is not at the origin
if (_track_desired > 0.0f) {
return;
}
// get current and target locations
const Vector3f curr_pos = _inav.get_position();
const Vector3f pos_target = _pos_control.get_pos_target();
// calculate difference between current position and target
Vector3f pos_diff = curr_pos - pos_target;
// shift origin and destination
_origin += pos_diff;
_destination += pos_diff;
// move pos controller target and disable feed forward
_pos_control.set_pos_target(curr_pos);
_pos_control.freeze_ff_xy();
_pos_control.freeze_ff_z();
}
/// get_wp_stopping_point_xy - returns vector to stopping point based on a horizontal position and velocity
void AC_WPNav::get_wp_stopping_point_xy(Vector3f& stopping_point) const
{
@ -695,7 +732,7 @@ void AC_WPNav::set_spline_origin_and_destination(const Vector3f& origin, const V
// before beginning it's spline path to the next waypoint. Note: we are using the previous segment's origin and destination
_spline_origin_vel = (_destination - _origin);
_spline_time = 0.0f; // To-Do: this should be set based on how much overrun there was from straight segment?
_spline_vel_scaler = 0.0f; // To-Do: this should be set based on speed at end of prev straight segment?
_spline_vel_scaler = _pos_control.get_vel_target().length(); // start velocity target from current target velocity
}else{
// previous segment is splined, vehicle will fly through origin
// we can use the previous segment's destination velocity as this segment's origin velocity
@ -707,7 +744,7 @@ void AC_WPNav::set_spline_origin_and_destination(const Vector3f& origin, const V
}else{
_spline_time = 0.0f;
}
_spline_vel_scaler = 0.0f;
// Note: we leave _spline_vel_scaler as it was from end of previous segment
}
}

View File

@ -69,6 +69,9 @@ public:
/// init_loiter_target - initialize's loiter position and feed-forward velocity from current pos and velocity
void init_loiter_target();
/// loiter_soften_for_landing - reduce response for landing
void loiter_soften_for_landing();
/// set_loiter_velocity - allows main code to pass the maximum velocity for loiter
void set_loiter_velocity(float velocity_cms);
@ -132,6 +135,11 @@ public:
/// set_wp_origin_and_destination - set origin and destination waypoints using position vectors (distance from home in cm)
void set_wp_origin_and_destination(const Vector3f& origin, const Vector3f& destination);
/// shift_wp_origin_to_current_pos - shifts the origin and destination so the origin starts at the current position
/// used to reset the position just before takeoff
/// relies on set_wp_destination or set_wp_origin_and_destination having been called first
void shift_wp_origin_to_current_pos();
/// get_wp_stopping_point_xy - calculates stopping point based on current position, velocity, waypoint acceleration
/// results placed in stopping_position vector
void get_wp_stopping_point_xy(Vector3f& stopping_point) const;

View File

@ -247,3 +247,15 @@ void AP_AHRS::update_trig(void)
_sin_pitch = -temp.c.x;
_sin_roll = temp.c.y / _cos_pitch;
}
/*
update the centi-degree values
*/
void AP_AHRS::update_cd_values(void)
{
roll_sensor = degrees(roll) * 100;
pitch_sensor = degrees(pitch) * 100;
yaw_sensor = degrees(yaw) * 100;
if (yaw_sensor < 0)
yaw_sensor += 36000;
}

View File

@ -32,6 +32,8 @@
#include <AP_Param.h>
#define AP_AHRS_TRIM_LIMIT 10.0f // maximum trim angle in degrees
#define AP_AHRS_RP_P_MIN 0.05f // minimum value for AHRS_RP_P parameter
#define AP_AHRS_YAW_P_MIN 0.05f // minimum value for AHRS_YAW_P parameter
enum AHRS_VehicleClass {
AHRS_VEHICLE_UNKNOWN,
@ -179,6 +181,10 @@ public:
// return the current estimate of the gyro drift
virtual const Vector3f &get_gyro_drift(void) const = 0;
// reset the current gyro drift estimate
// should be called if gyro offsets are recalculated
virtual void reset_gyro_drift(void) = 0;
// reset the current attitude, used on new IMU calibration
virtual void reset(bool recover_eulers=false) = 0;
@ -338,6 +344,9 @@ public:
// is the AHRS subsystem healthy?
virtual bool healthy(void) = 0;
// true if the AHRS has completed initialisation
virtual bool initialised(void) const { return true; };
protected:
AHRS_VehicleClass _vehicle_class;
@ -364,6 +373,9 @@ protected:
// should be called after _dcm_matrix is updated
void update_trig(void);
// update roll_sensor, pitch_sensor and yaw_sensor
void update_cd_values(void);
// pointer to compass object, if available
Compass * _compass;

View File

@ -36,6 +36,15 @@ extern const AP_HAL::HAL& hal;
// http://gentlenav.googlecode.com/files/fastRotations.pdf
#define SPIN_RATE_LIMIT 20
// reset the current gyro drift estimate
// should be called if gyro offsets are recalculated
void
AP_AHRS_DCM::reset_gyro_drift(void)
{
_omega_I.zero();
_omega_I_sum.zero();
_omega_I_sum_time = 0;
}
// run a full DCM update round
void
@ -143,7 +152,7 @@ AP_AHRS_DCM::check_matrix(void)
{
if (_dcm_matrix.is_nan()) {
//Serial.printf("ERROR: DCM matrix NAN\n");
reset(true);
AP_AHRS_DCM::reset(true);
return;
}
// some DCM matrix values can lead to an out of range error in
@ -161,7 +170,7 @@ AP_AHRS_DCM::check_matrix(void)
// in real trouble. All we can do is reset
//Serial.printf("ERROR: DCM matrix error. _dcm_matrix.c.x=%f\n",
// _dcm_matrix.c.x);
reset(true);
AP_AHRS_DCM::reset(true);
}
}
}
@ -242,7 +251,7 @@ AP_AHRS_DCM::normalize(void)
// Our solution is blowing up and we will force back
// to last euler angles
_last_failure_ms = hal.scheduler->millis();
reset(true);
AP_AHRS_DCM::reset(true);
}
}
@ -362,7 +371,7 @@ AP_AHRS_DCM::drift_correction_yaw(void)
float yaw_error;
float yaw_deltat;
if (use_compass()) {
if (AP_AHRS_DCM::use_compass()) {
/*
we are using compass for yaw
*/
@ -442,6 +451,11 @@ AP_AHRS_DCM::drift_correction_yaw(void)
// integration at higher rates
float spin_rate = _omega.length();
// sanity check _kp_yaw
if (_kp_yaw < AP_AHRS_YAW_P_MIN) {
_kp_yaw = AP_AHRS_YAW_P_MIN;
}
// update the proportional control to drag the
// yaw back to the right value. We use a gain
// that depends on the spin rate. See the fastRotations.pdf
@ -684,7 +698,7 @@ AP_AHRS_DCM::drift_correction(float deltat)
// reduce the impact of the gps/accelerometers on yaw when we are
// flat, but still allow for yaw correction using the
// accelerometers at high roll angles as long as we have a GPS
if (use_compass()) {
if (AP_AHRS_DCM::use_compass()) {
if (have_gps() && gps_gain == 1.0f) {
error[besti].z *= sinf(fabsf(roll));
} else {
@ -715,6 +729,11 @@ AP_AHRS_DCM::drift_correction(float deltat)
// base the P gain on the spin rate
float spin_rate = _omega.length();
// sanity check _kp value
if (_kp < AP_AHRS_RP_P_MIN) {
_kp = AP_AHRS_RP_P_MIN;
}
// we now want to calculate _omega_P and _omega_I. The
// _omega_P value is what drags us quickly to the
// accelerometer reading.
@ -837,12 +856,7 @@ AP_AHRS_DCM::euler_angles(void)
_body_dcm_matrix.rotateXYinv(_trim);
_body_dcm_matrix.to_euler(&roll, &pitch, &yaw);
roll_sensor = degrees(roll) * 100;
pitch_sensor = degrees(pitch) * 100;
yaw_sensor = degrees(yaw) * 100;
if (yaw_sensor < 0)
yaw_sensor += 36000;
update_cd_values();
}
/* reporting of DCM state for MAVLink */

View File

@ -75,6 +75,10 @@ public:
return _omega_I;
}
// reset the current gyro drift estimate
// should be called if gyro offsets are recalculated
void reset_gyro_drift(void);
// Methods
void update(void);
void reset(bool recover_eulers = false);

View File

@ -50,16 +50,35 @@ const Vector3f &AP_AHRS_NavEKF::get_gyro_drift(void) const
return _gyro_bias;
}
// reset the current gyro drift estimate
// should be called if gyro offsets are recalculated
void AP_AHRS_NavEKF::reset_gyro_drift(void)
{
// update DCM
AP_AHRS_DCM::reset_gyro_drift();
// reset the EKF gyro bias states
EKF.resetGyroBias();
}
void AP_AHRS_NavEKF::update(void)
{
// we need to restore the old DCM attitude values as these are
// used internally in DCM to calculate error values for gyro drift
// correction
roll = _dcm_attitude.x;
pitch = _dcm_attitude.y;
yaw = _dcm_attitude.z;
update_cd_values();
AP_AHRS_DCM::update();
// keep DCM attitude available for get_secondary_attitude()
_dcm_attitude(roll, pitch, yaw);
if (!ekf_started) {
// if we have a GPS lock we can start the EKF
if (get_gps().status() >= AP_GPS::GPS_OK_FIX_3D) {
// if we have a GPS lock and more than 6 satellites, we can start the EKF
if (get_gps().status() >= AP_GPS::GPS_OK_FIX_3D && get_gps().num_sats() >= _gps_minsats) {
if (start_time_ms == 0) {
start_time_ms = hal.scheduler->millis();
}
@ -78,11 +97,8 @@ void AP_AHRS_NavEKF::update(void)
roll = eulers.x;
pitch = eulers.y;
yaw = eulers.z;
roll_sensor = degrees(roll) * 100;
pitch_sensor = degrees(pitch) * 100;
yaw_sensor = degrees(yaw) * 100;
if (yaw_sensor < 0)
yaw_sensor += 36000;
update_cd_values();
update_trig();
// keep _gyro_bias for get_gyro_drift()
@ -166,6 +182,9 @@ bool AP_AHRS_NavEKF::airspeed_estimate(float *airspeed_ret) const
// true if compass is being used
bool AP_AHRS_NavEKF::use_compass(void)
{
if (using_EKF()) {
return EKF.use_compass();
}
return AP_AHRS_DCM::use_compass();
}
@ -263,5 +282,12 @@ bool AP_AHRS_NavEKF::healthy(void)
return AP_AHRS_DCM::healthy();
}
// true if the AHRS has completed initialisation
bool AP_AHRS_NavEKF::initialised(void) const
{
// initialisation complete 10sec after ekf has started
return (ekf_started && (hal.scheduler->millis() - start_time_ms > AP_AHRS_NAVEKF_SETTLE_TIME_MS));
};
#endif // AP_AHRS_NAVEKF_AVAILABLE

View File

@ -28,6 +28,7 @@
#include <AP_NavEKF.h>
#define AP_AHRS_NAVEKF_AVAILABLE 1
#define AP_AHRS_NAVEKF_SETTLE_TIME_MS 20000 // time in milliseconds the ekf needs to settle after being started
class AP_AHRS_NavEKF : public AP_AHRS_DCM
{
@ -48,6 +49,10 @@ public:
// return the current drift correction integrator value
const Vector3f &get_gyro_drift(void) const;
// reset the current gyro drift estimate
// should be called if gyro offsets are recalculated
void reset_gyro_drift(void);
void update(void);
void reset(bool recover_eulers = false);
@ -95,6 +100,9 @@ public:
// is the AHRS subsystem healthy?
bool healthy(void);
// true if the AHRS has completed initialisation
bool initialised(void) const;
private:
bool using_EKF(void) const;

View File

@ -60,7 +60,11 @@ extern const AP_HAL::HAL& hal;
#elif defined(CONFIG_ARCH_BOARD_VRBRAIN_V51)
#define ARSPD_DEFAULT_PIN 0
#elif defined(CONFIG_ARCH_BOARD_VRUBRAIN_V51)
#if APM_BUILD_TYPE(APM_BUILD_ArduPlane)
#define ARSPD_DEFAULT_PIN 1
#else
#define ARSPD_DEFAULT_PIN 0
#endif
#elif defined(CONFIG_ARCH_BOARD_VRHERO_V10)
#define ARSPD_DEFAULT_PIN 0
#endif

View File

@ -57,10 +57,8 @@ bool AP_Compass_VRBRAIN::init(void)
}
for (uint8_t i=0; i<_num_instances; i++) {
#ifdef DEVIOCGDEVICEID
// get device id
_dev_id[i] = ioctl(_mag_fd[i], DEVIOCGDEVICEID, 0);
#endif
// average over up to 20 samples
if (ioctl(_mag_fd[i], SENSORIOCSQUEUEDEPTH, 20) != 0) {
@ -70,6 +68,11 @@ bool AP_Compass_VRBRAIN::init(void)
// remember if the compass is external
_is_external[i] = (ioctl(_mag_fd[i], MAGIOCGEXTERNAL, 0) > 0);
#if defined(CONFIG_ARCH_BOARD_VRBRAIN_V45)
//deal with situations where user has cut internal mag on VRBRAIN 4.5
//and uses only one external mag attached to the internal I2C bus
_is_external[i] = _external.load() ? _external.get() : _is_external[i];
#endif
if (_is_external[i]) {
hal.console->printf("Using external compass[%u]\n", (unsigned)i);
}
@ -108,9 +111,10 @@ bool AP_Compass_VRBRAIN::read(void)
// a noop on most boards
_sum[i].rotate(MAG_BOARD_ORIENTATION);
#if !defined(CONFIG_ARCH_BOARD_VRBRAIN_V45)
// override any user setting of COMPASS_EXTERNAL
_external.set(_is_external[0]);
#endif
if (_is_external[i]) {
// add user selectable orientation
_sum[i].rotate((enum Rotation)_orientation.get());

View File

@ -120,13 +120,13 @@ const AP_Param::GroupInfo Compass::var_info[] PROGMEM = {
// @DisplayName: Compass device id
// @Description: Compass device id. Automatically detected, do not set manually
// @User: Advanced
AP_GROUPINFO("DEV_ID", 15, Compass, _dev_id[0], COMPASS_EXPECTED_DEV_ID),
AP_GROUPINFO("DEV_ID", 15, Compass, _dev_id[0], 0),
// @Param: DEV_ID2
// @DisplayName: Compass2 device id
// @Description: Second compass's device id. Automatically detected, do not set manually
// @User: Advanced
AP_GROUPINFO("DEV_ID2", 16, Compass, _dev_id[1], COMPASS_EXPECTED_DEV_ID2),
AP_GROUPINFO("DEV_ID2", 16, Compass, _dev_id[1], 0),
#endif
#if COMPASS_MAX_INSTANCES > 2
@ -134,7 +134,7 @@ const AP_Param::GroupInfo Compass::var_info[] PROGMEM = {
// @DisplayName: Compass3 device id
// @Description: Third compass's device id. Automatically detected, do not set manually
// @User: Advanced
AP_GROUPINFO("DEV_ID3", 17, Compass, _dev_id[2], COMPASS_EXPECTED_DEV_ID3),
AP_GROUPINFO("DEV_ID3", 17, Compass, _dev_id[2], 0),
#endif
AP_GROUPEND
@ -169,6 +169,15 @@ Compass::init()
return true;
}
void
Compass::set_offsets(uint8_t i, const Vector3f &offsets)
{
// sanity check compass instance provided
if (i < COMPASS_MAX_INSTANCES) {
_offset[i].set(offsets);
}
}
void
Compass::set_and_save_offsets(uint8_t i, const Vector3f &offsets)
{

View File

@ -52,25 +52,6 @@
#define COMPASS_MAX_INSTANCES 1
#endif
// default compass device ids for each board type to most common set-up to reduce eeprom usage
#if CONFIG_HAL_BOARD == HAL_BOARD_PX4
# define COMPASS_EXPECTED_DEV_ID 73225 // external hmc5883
# define COMPASS_EXPECTED_DEV_ID2 -1 // internal ldm303d
# define COMPASS_EXPECTED_DEV_ID3 0
#elif CONFIG_HAL_BOARD == HAL_BOARD_LINUX
# define COMPASS_EXPECTED_DEV_ID 0
# define COMPASS_EXPECTED_DEV_ID2 0
# define COMPASS_EXPECTED_DEV_ID3 0
#elif CONFIG_HAL_BOARD == HAL_BOARD_VRBRAIN
# define COMPASS_EXPECTED_DEV_ID 0
# define COMPASS_EXPECTED_DEV_ID2 0
# define COMPASS_EXPECTED_DEV_ID3 0
#else
# define COMPASS_EXPECTED_DEV_ID 0
# define COMPASS_EXPECTED_DEV_ID2 0
# define COMPASS_EXPECTED_DEV_ID3 0
#endif
class Compass
{
public:
@ -106,6 +87,13 @@ public:
///
float calculate_heading(const Matrix3f &dcm_matrix) const;
/// Sets offset x/y/z values.
///
/// @param i compass instance
/// @param offsets Offsets to the raw mag_ values.
///
void set_offsets(uint8_t i, const Vector3f &offsets);
/// Sets and saves the compass offset x/y/z values.
///
/// @param i compass instance

View File

@ -72,8 +72,8 @@ void AP_GPS::init(DataFlash_Class *dataflash)
{
_DataFlash = dataflash;
hal.uartB->begin(38400UL, 256, 16);
#if GPS_MAX_INSTANCES > 1
primary_instance = 0;
#if GPS_MAX_INSTANCES > 1
if (hal.uartE != NULL) {
hal.uartE->begin(38400UL, 256, 16);
}
@ -334,9 +334,6 @@ AP_GPS::update(void)
update_instance(i);
}
// update notify with gps status. We always base this on the first GPS
AP_Notify::flags.gps_status = state[0].status;
#if GPS_MAX_INSTANCES > 1
// work out which GPS is the primary, and how many sensors we have
for (uint8_t i=0; i<GPS_MAX_INSTANCES; i++) {
@ -368,6 +365,8 @@ AP_GPS::update(void)
#else
num_instances = 1;
#endif // GPS_MAX_INSTANCES
// update notify with gps status. We always base this on the primary_instance
AP_Notify::flags.gps_status = state[primary_instance].status;
}
/*

View File

@ -25,7 +25,7 @@
#include <AP_Common.h>
#include <AP_GPS.h>
#define SIRF_SET_BINARY "$PSRF100,0,38400,8,1,0*3C"
#define SIRF_SET_BINARY "$PSRF100,0,38400,8,1,0*3C\r\n"
class AP_GPS_SIRF : public AP_GPS_Backend {
public:

View File

@ -44,8 +44,6 @@ extern const AP_HAL::HAL& hal;
#define UBLOX_HW_LOGGING 0
#endif
bool AP_GPS_UBLOX::logging_started = false;
AP_GPS_UBLOX::AP_GPS_UBLOX(AP_GPS &_gps, AP_GPS::GPS_State &_state, AP_HAL::UARTDriver *_port) :
AP_GPS_Backend(_gps, _state, _port),
_step(0),
@ -249,53 +247,13 @@ AP_GPS_UBLOX::read(void)
// Private Methods /////////////////////////////////////////////////////////////
#if UBLOX_HW_LOGGING
#define LOG_MSG_UBX1 200
#define LOG_MSG_UBX2 201
struct PACKED log_Ubx1 {
LOG_PACKET_HEADER;
uint32_t timestamp;
uint8_t instance;
uint16_t noisePerMS;
uint8_t jamInd;
uint8_t aPower;
};
struct PACKED log_Ubx2 {
LOG_PACKET_HEADER;
uint32_t timestamp;
uint8_t instance;
int8_t ofsI;
uint8_t magI;
int8_t ofsQ;
uint8_t magQ;
};
static const struct LogStructure ubx_log_structures[] PROGMEM = {
{ LOG_MSG_UBX1, sizeof(log_Ubx1),
"UBX1", "IBHBB", "TimeMS,Instance,noisePerMS,jamInd,aPower" },
{ LOG_MSG_UBX2, sizeof(log_Ubx2),
"UBX2", "IBbBbB", "TimeMS,Instance,ofsI,magI,ofsQ,magQ" }
};
void AP_GPS_UBLOX::write_logging_headers(void)
{
if (!logging_started) {
logging_started = true;
gps._DataFlash->AddLogFormats(ubx_log_structures, 2);
}
}
void AP_GPS_UBLOX::log_mon_hw(void)
{
if (gps._DataFlash == NULL || !gps._DataFlash->logging_started()) {
return;
}
// log mon_hw message
write_logging_headers();
struct log_Ubx1 pkt = {
LOG_PACKET_HEADER_INIT(LOG_MSG_UBX1),
LOG_PACKET_HEADER_INIT(LOG_UBX1_MSG),
timestamp : hal.scheduler->millis(),
instance : state.instance,
noisePerMS : _buffer.mon_hw_60.noisePerMS,
@ -315,11 +273,9 @@ void AP_GPS_UBLOX::log_mon_hw2(void)
if (gps._DataFlash == NULL || !gps._DataFlash->logging_started()) {
return;
}
// log mon_hw message
write_logging_headers();
struct log_Ubx2 pkt = {
LOG_PACKET_HEADER_INIT(LOG_MSG_UBX2),
LOG_PACKET_HEADER_INIT(LOG_UBX2_MSG),
timestamp : hal.scheduler->millis(),
instance : state.instance,
ofsI : _buffer.mon_hw2.ofsI,

View File

@ -256,9 +256,6 @@ private:
bool _new_speed:1;
bool need_rate_update:1;
// have we written the logging headers to DataFlash?
static bool logging_started;
uint8_t _disable_counter;
// Buffer parse & GPS state update

View File

@ -215,13 +215,15 @@
#define HAL_BOARD_NAME "VRBRAIN"
#define HAL_CPU_CLASS HAL_CPU_CLASS_150
#define HAL_OS_POSIX_IO 1
#define HAL_STORAGE_SIZE 4096
#define HAL_STORAGE_SIZE 8192
#define HAL_STORAGE_SIZE_AVAILABLE HAL_STORAGE_SIZE
#define HAL_BOARD_LOG_DIRECTORY "/fs/microsd/APM/LOGS"
#define HAL_BOARD_TERRAIN_DIRECTORY "/fs/microsd/APM/TERRAIN"
#define HAL_INS_DEFAULT HAL_INS_VRBRAIN
#define HAL_BARO_DEFAULT HAL_BARO_VRBRAIN
#define HAL_COMPASS_DEFAULT HAL_COMPASS_VRBRAIN
#define HAL_SERIAL0_BAUD_DEFAULT 115200
#define CONFIG_HAL_BOARD_SUBTYPE HAL_BOARD_SUBTYPE_NONE
#else
#error "Unknown CONFIG_HAL_BOARD type"

View File

@ -3,6 +3,7 @@
#define __AP_HAL_SCHEDULER_H__
#include "AP_HAL_Namespace.h"
#include "AP_HAL_Boards.h"
#include <stdint.h>
#include <AP_Progmem.h>
@ -14,6 +15,11 @@ public:
virtual void delay(uint16_t ms) = 0;
virtual uint32_t millis() = 0;
virtual uint32_t micros() = 0;
#if HAL_CPU_CLASS >= HAL_CPU_CLASS_150
// offer non-wrapping 64 bit versions on faster CPUs
virtual uint64_t millis64() = 0;
virtual uint64_t micros64() = 0;
#endif
virtual void delay_microseconds(uint16_t us) = 0;
virtual void register_delay_callback(AP_HAL::Proc,
uint16_t min_time_ms) = 0;

View File

@ -65,7 +65,7 @@ uint16_t SITL_State::current_pin_value;
float SITL_State::_current;
AP_Baro_HIL *SITL_State::_barometer;
AP_InertialSensor_HIL *SITL_State::_ins;
AP_InertialSensor *SITL_State::_ins;
SITLScheduler *SITL_State::_scheduler;
AP_Compass_HIL *SITL_State::_compass;
@ -212,7 +212,7 @@ void SITL_State::_sitl_setup(void)
// find the barometer object if it exists
_sitl = (SITL *)AP_Param::find_object("SIM_");
_barometer = (AP_Baro_HIL *)AP_Param::find_object("GND_");
_ins = (AP_InertialSensor_HIL *)AP_Param::find_object("INS_");
_ins = (AP_InertialSensor *)AP_Param::find_object("INS_");
_compass = (AP_Compass_HIL *)AP_Param::find_object("COMPASS_");
if (_sitl != NULL) {

View File

@ -121,7 +121,7 @@ private:
static bool _motors_on;
static AP_Baro_HIL *_barometer;
static AP_InertialSensor_HIL *_ins;
static AP_InertialSensor *_ins;
static SITLScheduler *_scheduler;
static AP_Compass_HIL *_compass;

View File

@ -70,52 +70,64 @@ double SITLScheduler::_cyg_sec()
}
#endif
uint32_t SITLScheduler::_micros()
uint64_t SITLScheduler::_micros64()
{
#ifdef __CYGWIN__
return (uint32_t)(_cyg_sec() * 1.0e6);
return (uint64_t)(_cyg_sec() * 1.0e6);
#else
struct timeval tp;
gettimeofday(&tp,NULL);
return 1.0e6*((tp.tv_sec + (tp.tv_usec*1.0e-6)) -
uint64_t ret = 1.0e6*((tp.tv_sec + (tp.tv_usec*1.0e-6)) -
(_sketch_start_time.tv_sec +
(_sketch_start_time.tv_usec*1.0e-6)));
return ret;
#endif
}
uint64_t SITLScheduler::micros64()
{
return _micros64();
}
uint32_t SITLScheduler::micros()
{
return _micros();
return micros64() & 0xFFFFFFFF;
}
uint64_t SITLScheduler::millis64()
{
#ifdef __CYGWIN__
// 1000 ms in a second
return (uint64_t)(_cyg_sec() * 1000);
#else
struct timeval tp;
gettimeofday(&tp,NULL);
uint64_t ret = 1.0e3*((tp.tv_sec + (tp.tv_usec*1.0e-6)) -
(_sketch_start_time.tv_sec +
(_sketch_start_time.tv_usec*1.0e-6)));
return ret;
#endif
}
uint32_t SITLScheduler::millis()
{
#ifdef __CYGWIN__
// 1000 ms in a second
return (uint32_t)(_cyg_sec() * 1000);
#else
struct timeval tp;
gettimeofday(&tp,NULL);
return 1.0e3*((tp.tv_sec + (tp.tv_usec*1.0e-6)) -
(_sketch_start_time.tv_sec +
(_sketch_start_time.tv_usec*1.0e-6)));
#endif
return millis64() & 0xFFFFFFFF;
}
void SITLScheduler::delay_microseconds(uint16_t usec)
{
uint32_t start = micros();
while (micros() - start < usec) {
usleep(usec - (micros() - start));
uint64_t start = micros64();
while (micros64() - start < usec) {
usleep(usec - (micros64() - start));
}
}
void SITLScheduler::delay(uint16_t ms)
{
uint32_t start = micros();
uint64_t start = micros64();
while (ms > 0) {
while ((micros() - start) >= 1000) {
while ((micros64() - start) >= 1000) {
ms--;
if (ms == 0) break;
start += 1000;

View File

@ -19,6 +19,8 @@ public:
void delay(uint16_t ms);
uint32_t millis();
uint32_t micros();
uint64_t millis64();
uint64_t micros64();
void delay_microseconds(uint16_t us);
void register_delay_callback(AP_HAL::Proc, uint16_t min_time_ms);
@ -43,7 +45,7 @@ public:
void sitl_end_atomic();
// callable from interrupt handler
static uint32_t _micros();
static uint64_t _micros64();
static void timer_event() { _run_timer_procs(true); _run_io_procs(true); }
private:

View File

@ -52,7 +52,7 @@ float SITL_State::_gyro_drift(void)
return 0;
}
double period = _sitl->drift_time * 2;
double minutes = fmod(_scheduler->_micros() / 60.0e6, period);
double minutes = fmod(_scheduler->micros64() / 60.0e6, period);
if (minutes < period/2) {
return minutes * ToRad(_sitl->drift_speed);
}

View File

@ -14,14 +14,22 @@ void EmptyScheduler::init(void* machtnichts)
void EmptyScheduler::delay(uint16_t ms)
{}
uint32_t EmptyScheduler::millis() {
uint64_t EmptyScheduler::millis64() {
return 10000;
}
uint32_t EmptyScheduler::micros() {
uint64_t EmptyScheduler::micros64() {
return 200000;
}
uint32_t EmptyScheduler::millis() {
return millis64();
}
uint32_t EmptyScheduler::micros() {
return micros64();
}
void EmptyScheduler::delay_microseconds(uint16_t us)
{}

View File

@ -11,6 +11,8 @@ public:
void delay(uint16_t ms);
uint32_t millis();
uint32_t micros();
uint64_t millis64();
uint64_t micros64();
void delay_microseconds(uint16_t us);
void register_delay_callback(AP_HAL::Proc,
uint16_t min_time_ms);

View File

@ -76,6 +76,16 @@ void PX4Scheduler::init(void *unused)
pthread_create(&_io_thread_ctx, &thread_attr, (pthread_startroutine_t)&PX4::PX4Scheduler::_io_thread, this);
}
uint64_t PX4Scheduler::micros64()
{
return hrt_absolute_time();
}
uint64_t PX4Scheduler::millis64()
{
return micros64() / 1000;
}
uint32_t PX4Scheduler::micros()
{
return (uint32_t)(hrt_absolute_time() - _sketch_start_time);
@ -83,7 +93,7 @@ uint32_t PX4Scheduler::micros()
uint32_t PX4Scheduler::millis()
{
return hrt_absolute_time() / 1000;
return millis64() & 0xFFFFFFFF;
}
/**
@ -106,9 +116,9 @@ void PX4Scheduler::delay_microseconds(uint16_t usec)
perf_end(_perf_delay);
return;
}
uint32_t start = micros();
uint32_t dt;
while ((dt=(micros() - start)) < usec) {
uint64_t start = micros64();
uint64_t dt;
while ((dt=(micros64() - start)) < usec) {
up_udelay(usec - dt);
}
perf_end(_perf_delay);
@ -121,9 +131,9 @@ void PX4Scheduler::delay(uint16_t ms)
return;
}
perf_begin(_perf_delay);
uint64_t start = hrt_absolute_time();
uint64_t start = micros64();
while ((hrt_absolute_time() - start)/1000 < ms &&
while ((micros64() - start)/1000 < ms &&
!_px4_thread_should_exit) {
delay_microseconds_semaphore(1000);
if (_min_delay_cb_ms <= ms) {

View File

@ -29,6 +29,8 @@ public:
void delay(uint16_t ms);
uint32_t millis();
uint32_t micros();
uint64_t millis64();
uint64_t micros64();
void delay_microseconds(uint16_t us);
void register_delay_callback(AP_HAL::Proc, uint16_t min_time_ms);
void register_timer_process(AP_HAL::MemberProc);

View File

@ -176,12 +176,12 @@ void PX4Storage::_storage_open(void)
*/
void PX4Storage::_mark_dirty(uint16_t loc, uint16_t length)
{
uint16_t end = loc + length;
while (loc < end) {
uint8_t line = (loc >> PX4_STORAGE_LINE_SHIFT);
_dirty_mask |= 1 << line;
loc += PX4_STORAGE_LINE_SIZE;
}
uint16_t end = loc + length;
for (uint8_t line=loc>>PX4_STORAGE_LINE_SHIFT;
line <= end>>PX4_STORAGE_LINE_SHIFT;
line++) {
_dirty_mask |= 1U << line;
}
}
void PX4Storage::read_block(void *dst, uint16_t loc, size_t n)
@ -261,13 +261,6 @@ void PX4Storage::_timer_tick(void)
_fd = -1;
perf_count(_perf_errors);
}
if (_dirty_mask == 0) {
if (fsync(_fd) != 0) {
close(_fd);
_fd = -1;
perf_count(_perf_errors);
}
}
}
perf_end(_perf_storage);
}

View File

@ -503,7 +503,7 @@ void PX4UARTDriver::_timer_tick(void)
// split into two writes
uint16_t n1 = _writebuf_size - _writebuf_head;
int ret = _write_fd(&_writebuf[_writebuf_head], n1);
if (ret == n1 && n != n1) {
if (ret == n1 && n > n1) {
_write_fd(&_writebuf[_writebuf_head], n - n1);
}
}
@ -523,7 +523,7 @@ void PX4UARTDriver::_timer_tick(void)
uint16_t n1 = _readbuf_size - _readbuf_tail;
assert(_readbuf_tail+n1 <= _readbuf_size);
int ret = _read_fd(&_readbuf[_readbuf_tail], n1);
if (ret == n1 && n != n1) {
if (ret == n1 && n > n1) {
assert(_readbuf_tail+(n-n1) <= _readbuf_size);
_read_fd(&_readbuf[_readbuf_tail], n - n1);
}

View File

@ -18,6 +18,7 @@
#include <uORB/topics/system_power.h>
#include <GCS_MAVLink.h>
#include <errno.h>
#include <AP_Vehicle.h>
#define ANLOGIN_DEBUGGING 0
@ -57,6 +58,11 @@ static const struct {
{ 10, 3.3f/4096 },
{ 11, 3.3f/4096 },
#elif defined(CONFIG_ARCH_BOARD_VRUBRAIN_V51)
#if APM_BUILD_TYPE(APM_BUILD_ArduPlane)
{ 1, 3.3f/4096 },
{ 2, 3.3f/4096 },
{ 3, 3.3f/4096 },
#endif
{ 10, 3.3f/4096 },
#elif defined(CONFIG_ARCH_BOARD_VRHERO_V10)
{ 10, 3.3f/4096 },

View File

@ -44,22 +44,23 @@ void VRBRAINGPIO::init()
if (ioctl(_led_fd, LED_OFF, LED_GREEN) != 0) {
hal.console->printf("GPIO: Unable to setup GPIO LED GREEN\n");
}
#if !defined(CONFIG_ARCH_BOARD_VRHERO_V10)
#if defined(LED_EXT1)
if (ioctl(_led_fd, LED_OFF, LED_EXT1) != 0) {
hal.console->printf("GPIO: Unable to setup GPIO LED EXT 1\n");
}
#endif
#if !defined(CONFIG_ARCH_BOARD_VRHERO_V10)
#if defined(LED_EXT2)
if (ioctl(_led_fd, LED_OFF, LED_EXT2) != 0) {
hal.console->printf("GPIO: Unable to setup GPIO LED EXT 2\n");
}
#endif
#if !defined(CONFIG_ARCH_BOARD_VRHERO_V10) && !defined(CONFIG_ARCH_BOARD_VRUBRAIN_V51)
#if defined(LED_EXT3)
if (ioctl(_led_fd, LED_OFF, LED_EXT3) != 0) {
hal.console->printf("GPIO: Unable to setup GPIO LED EXT 3\n");
}
#endif
#if defined(BUZZER_EXT)
_buzzer_fd = open(BUZZER_DEVICE_PATH, O_RDWR);
if (_buzzer_fd == -1) {
hal.scheduler->panic("Unable to open " BUZZER_DEVICE_PATH);
@ -67,6 +68,15 @@ void VRBRAINGPIO::init()
if (ioctl(_buzzer_fd, BUZZER_OFF, BUZZER_EXT) != 0) {
hal.console->printf("GPIO: Unable to setup GPIO BUZZER\n");
}
#endif
#if defined(GPIO_GPIO0_OUTPUT)
stm32_configgpio(GPIO_GPIO0_OUTPUT);
#endif
#if defined(GPIO_GPIO1_OUTPUT)
stm32_configgpio(GPIO_GPIO1_OUTPUT);
#endif
}
void VRBRAINGPIO::pinMode(uint8_t pin, uint8_t output)
@ -85,6 +95,16 @@ uint8_t VRBRAINGPIO::read(uint8_t pin)
{
switch (pin) {
case EXTERNAL_RELAY1_PIN:
#if defined(GPIO_GPIO0_OUTPUT)
return (stm32_gpioread(GPIO_GPIO0_OUTPUT))?HIGH:LOW;
#endif
break;
case EXTERNAL_RELAY2_PIN:
#if defined(GPIO_GPIO1_OUTPUT)
return (stm32_gpioread(GPIO_GPIO1_OUTPUT))?HIGH:LOW;
#endif
break;
}
return LOW;
}
@ -118,7 +138,7 @@ void VRBRAINGPIO::write(uint8_t pin, uint8_t value)
break;
case EXTERNAL_LED_GPS:
#if !defined(CONFIG_ARCH_BOARD_VRHERO_V10)
#if defined(LED_EXT1)
if (value == LOW) {
ioctl(_led_fd, LED_OFF, LED_EXT1);
} else {
@ -128,7 +148,7 @@ void VRBRAINGPIO::write(uint8_t pin, uint8_t value)
break;
case EXTERNAL_LED_ARMED:
#if !defined(CONFIG_ARCH_BOARD_VRHERO_V10)
#if defined(LED_EXT2)
if (value == LOW) {
ioctl(_led_fd, LED_OFF, LED_EXT2);
} else {
@ -144,12 +164,26 @@ void VRBRAINGPIO::write(uint8_t pin, uint8_t value)
break;
case BUZZER_PIN:
#if defined(BUZZER_EXT)
if (value == LOW) {
ioctl(_buzzer_fd, BUZZER_OFF, BUZZER_EXT);
} else {
ioctl(_buzzer_fd, BUZZER_ON, BUZZER_EXT);
}
#endif
break;
case EXTERNAL_RELAY1_PIN:
#if defined(GPIO_GPIO0_OUTPUT)
stm32_gpiowrite(GPIO_GPIO0_OUTPUT, (value==HIGH));
#endif
break;
case EXTERNAL_RELAY2_PIN:
#if defined(GPIO_GPIO1_OUTPUT)
stm32_gpiowrite(GPIO_GPIO1_OUTPUT, (value==HIGH));
#endif
break;
}
}
@ -170,13 +204,13 @@ void VRBRAINGPIO::toggle(uint8_t pin)
break;
case EXTERNAL_LED_GPS:
#if !defined(CONFIG_ARCH_BOARD_VRHERO_V10)
#if defined(LED_EXT1)
ioctl(_led_fd, LED_TOGGLE, LED_EXT1);
#endif
break;
case EXTERNAL_LED_ARMED:
#if !defined(CONFIG_ARCH_BOARD_VRHERO_V10)
#if defined(LED_EXT2)
ioctl(_led_fd, LED_TOGGLE, LED_EXT2);
#endif
break;
@ -190,7 +224,9 @@ void VRBRAINGPIO::toggle(uint8_t pin)
break;
case BUZZER_PIN:
#if defined(BUZZER_EXT)
ioctl(_buzzer_fd, BUZZER_TOGGLE, BUZZER_EXT);
#endif
break;
default:

View File

@ -13,6 +13,8 @@
# define EXTERNAL_LED_MOTOR1 30
# define EXTERNAL_LED_MOTOR2 31
# define BUZZER_PIN 32
# define EXTERNAL_RELAY1_PIN 33
# define EXTERNAL_RELAY2_PIN 34
# define HAL_GPIO_LED_ON HIGH
# define HAL_GPIO_LED_OFF LOW

View File

@ -67,7 +67,7 @@ static VRBRAINGPIO gpioDriver;
#define UARTB_DEFAULT_DEVICE "/dev/ttyS0"
#define UARTC_DEFAULT_DEVICE "/dev/ttyS2"
#define UARTD_DEFAULT_DEVICE "/dev/null"
#define UARTE_DEFAULT_DEVICE "/dev/null"
#define UARTE_DEFAULT_DEVICE "/dev/ttyS1"
#elif defined(CONFIG_ARCH_BOARD_VRUBRAIN_V51)
#define UARTA_DEFAULT_DEVICE "/dev/ttyACM0"
#define UARTB_DEFAULT_DEVICE "/dev/ttyS0"

View File

@ -177,11 +177,11 @@ void VRBRAINStorage::_storage_open(void)
void VRBRAINStorage::_mark_dirty(uint16_t loc, uint16_t length)
{
uint16_t end = loc + length;
while (loc < end) {
uint8_t line = (loc >> VRBRAIN_STORAGE_LINE_SHIFT);
_dirty_mask |= 1 << line;
loc += VRBRAIN_STORAGE_LINE_SIZE;
}
for (uint8_t line=loc>>VRBRAIN_STORAGE_LINE_SHIFT;
line <= end>>VRBRAIN_STORAGE_LINE_SHIFT;
line++) {
_dirty_mask |= 1U << line;
}
}
void VRBRAINStorage::read_block(void *dst, uint16_t loc, size_t n)

View File

@ -503,7 +503,7 @@ void VRBRAINUARTDriver::_timer_tick(void)
// split into two writes
uint16_t n1 = _writebuf_size - _writebuf_head;
int ret = _write_fd(&_writebuf[_writebuf_head], n1);
if (ret == n1 && n != n1) {
if (ret == n1 && n > n1) {
_write_fd(&_writebuf[_writebuf_head], n - n1);
}
}
@ -523,7 +523,7 @@ void VRBRAINUARTDriver::_timer_tick(void)
uint16_t n1 = _readbuf_size - _readbuf_tail;
assert(_readbuf_tail+n1 <= _readbuf_size);
int ret = _read_fd(&_readbuf[_readbuf_tail], n1);
if (ret == n1 && n != n1) {
if (ret == n1 && n > n1) {
assert(_readbuf_tail+(n-n1) <= _readbuf_size);
_read_fd(&_readbuf[_readbuf_tail], n - n1);
}

View File

@ -25,12 +25,12 @@ void AP_InertialNav_NavEKF::init()
void AP_InertialNav_NavEKF::update(float dt)
{
AP_InertialNav::update(dt);
_ahrs.get_relative_position_NED(_relpos_cm);
_ahrs_ekf.get_NavEKF().getPosNED(_relpos_cm);
_relpos_cm *= 100; // convert to cm
_haveabspos = _ahrs.get_position(_abspos);
_ahrs.get_velocity_NED(_velocity_cm);
_ahrs_ekf.get_NavEKF().getVelNED(_velocity_cm);
_velocity_cm *= 100; // convert to cm/s
// InertialNav is NEU

View File

@ -14,9 +14,10 @@ class AP_InertialNav_NavEKF : public AP_InertialNav
{
public:
// Constructor
AP_InertialNav_NavEKF(AP_AHRS &ahrs, AP_Baro &baro, GPS_Glitch& gps_glitch, Baro_Glitch& baro_glitch) :
AP_InertialNav_NavEKF(AP_AHRS_NavEKF &ahrs, AP_Baro &baro, GPS_Glitch& gps_glitch, Baro_Glitch& baro_glitch) :
AP_InertialNav(ahrs, baro, gps_glitch, baro_glitch),
_haveabspos(false)
_haveabspos(false),
_ahrs_ekf(ahrs)
{
}
@ -113,6 +114,7 @@ private:
Vector3f _velocity_cm; // NEU
struct Location _abspos;
bool _haveabspos;
AP_AHRS_NavEKF &_ahrs_ekf;
};
#endif // __AP_INERTIALNAV_NAVEKF_H__

File diff suppressed because it is too large Load Diff

View File

@ -11,18 +11,22 @@
maximum number of INS instances available on this platform. If more
than 1 then redundent sensors may be available
*/
#if CONFIG_HAL_BOARD == HAL_BOARD_PX4 || CONFIG_HAL_BOARD == HAL_BOARD_LINUX || CONFIG_HAL_BOARD == HAL_BOARD_AVR_SITL
#define INS_MAX_INSTANCES 3
#elif CONFIG_HAL_BOARD == HAL_BOARD_VRBRAIN
#if HAL_CPU_CLASS > HAL_CPU_CLASS_16
#define INS_MAX_INSTANCES 3
#define INS_MAX_BACKENDS 6
#else
#define INS_MAX_INSTANCES 1
#define INS_MAX_BACKENDS 1
#endif
#include <stdint.h>
#include <AP_HAL.h>
#include <AP_Math.h>
#include "AP_InertialSensor_UserInteract.h"
class AP_InertialSensor_Backend;
/* AP_InertialSensor is an abstraction for gyro and accel measurements
* which are correctly aligned to the body axes and scaled to SI units.
*
@ -32,12 +36,11 @@
*/
class AP_InertialSensor
{
friend class AP_InertialSensor_Backend;
public:
AP_InertialSensor();
// empty virtual destructor
virtual ~AP_InertialSensor() {}
enum Start_style {
COLD_START = 0,
WARM_START
@ -64,22 +67,28 @@ public:
///
/// @param style The initialisation startup style.
///
virtual void init( Start_style style,
Sample_rate sample_rate);
void init( Start_style style,
Sample_rate sample_rate);
/// Perform cold startup initialisation for just the accelerometers.
///
/// @note This should not be called unless ::init has previously
/// been called, as ::init may perform other work.
///
virtual void init_accel();
void init_accel();
/// Register a new gyro/accel driver, allocating an instance
/// number
uint8_t register_gyro(void);
uint8_t register_accel(void);
#if !defined( __AVR_ATmega1280__ )
// perform accelerometer calibration including providing user instructions
// and feedback
virtual bool calibrate_accel(AP_InertialSensor_UserInteract *interact,
float& trim_roll,
float& trim_pitch);
bool calibrate_accel(AP_InertialSensor_UserInteract *interact,
float& trim_roll,
float& trim_pitch);
#endif
/// calibrated - returns true if the accelerometers have been calibrated
@ -93,61 +102,66 @@ public:
/// @note This should not be called unless ::init has previously
/// been called, as ::init may perform other work
///
virtual void init_gyro(void);
void init_gyro(void);
/// Fetch the current gyro values
///
/// @returns vector of rotational rates in radians/sec
///
const Vector3f &get_gyro(uint8_t i) const { return _gyro[i]; }
const Vector3f &get_gyro(void) const { return get_gyro(_get_primary_gyro()); }
virtual void set_gyro(uint8_t instance, const Vector3f &gyro) {}
const Vector3f &get_gyro(void) const { return get_gyro(_primary_gyro); }
void set_gyro(uint8_t instance, const Vector3f &gyro);
// set gyro offsets in radians/sec
const Vector3f &get_gyro_offsets(uint8_t i) const { return _gyro_offset[i]; }
const Vector3f &get_gyro_offsets(void) const { return get_gyro_offsets(_get_primary_gyro()); }
const Vector3f &get_gyro_offsets(void) const { return get_gyro_offsets(_primary_gyro); }
/// Fetch the current accelerometer values
///
/// @returns vector of current accelerations in m/s/s
///
const Vector3f &get_accel(uint8_t i) const { return _accel[i]; }
const Vector3f &get_accel(void) const { return get_accel(get_primary_accel()); }
virtual void set_accel(uint8_t instance, const Vector3f &accel) {}
const Vector3f &get_accel(void) const { return get_accel(_primary_accel); }
void set_accel(uint8_t instance, const Vector3f &accel);
uint32_t get_gyro_error_count(uint8_t i) const { return _gyro_error_count[i]; }
uint32_t get_accel_error_count(uint8_t i) const { return _accel_error_count[i]; }
// multi-device interface
virtual bool get_gyro_health(uint8_t instance) const { return true; }
bool get_gyro_health(void) const { return get_gyro_health(_get_primary_gyro()); }
virtual uint8_t get_gyro_count(void) const { return 1; };
bool get_gyro_health(uint8_t instance) const { return _gyro_healthy[instance]; }
bool get_gyro_health(void) const { return get_gyro_health(_primary_gyro); }
bool get_gyro_health_all(void) const;
uint8_t get_gyro_count(void) const { return _gyro_count; }
bool gyro_calibrated_ok(uint8_t instance) const { return _gyro_cal_ok[instance]; }
bool gyro_calibrated_ok_all() const;
virtual bool get_accel_health(uint8_t instance) const { return true; }
bool get_accel_health(void) const { return get_accel_health(get_primary_accel()); }
virtual uint8_t get_accel_count(void) const { return 1; };
bool get_accel_health(uint8_t instance) const { return _accel_healthy[instance]; }
bool get_accel_health(void) const { return get_accel_health(_primary_accel); }
bool get_accel_health_all(void) const;
uint8_t get_accel_count(void) const { return _accel_count; };
// get accel offsets in m/s/s
const Vector3f &get_accel_offsets(uint8_t i) const { return _accel_offset[i]; }
const Vector3f &get_accel_offsets(void) const { return get_accel_offsets(get_primary_accel()); }
const Vector3f &get_accel_offsets(void) const { return get_accel_offsets(_primary_accel); }
// get accel scale
const Vector3f &get_accel_scale(uint8_t i) const { return _accel_scale[i]; }
const Vector3f &get_accel_scale(void) const { return get_accel_scale(get_primary_accel()); }
/* Update the sensor data, so that getters are nonblocking.
* Returns a bool of whether data was updated or not.
*/
virtual bool update() = 0;
const Vector3f &get_accel_scale(void) const { return get_accel_scale(_primary_accel); }
/* get_delta_time returns the time period in seconds
* overwhich the sensor data was collected
*/
virtual float get_delta_time() const = 0;
float get_delta_time() const { return _delta_time; }
// return the maximum gyro drift rate in radians/s/s. This
// depends on what gyro chips are being used
virtual float get_gyro_drift_rate(void) = 0;
float get_gyro_drift_rate(void) const { return ToRad(0.5f/60); }
// wait for a sample to be available, with timeout in milliseconds
virtual bool wait_for_sample(uint16_t timeout_ms) = 0;
// update gyro and accel values from accumulated samples
void update(void);
// wait for a sample to be available
void wait_for_sample(void);
// class level parameters
static const struct AP_Param::GroupInfo var_info[];
@ -165,24 +179,28 @@ public:
}
// get_filter - return filter in hz
virtual uint8_t get_filter() const { return _mpu6000_filter.get(); }
uint8_t get_filter() const { return _mpu6000_filter.get(); }
virtual uint16_t error_count(void) const { return 0; }
virtual bool healthy(void) const { return get_gyro_health() && get_accel_health(); }
// return the selected sample rate
Sample_rate get_sample_rate(void) const { return _sample_rate; }
virtual uint8_t get_primary_accel(void) const { return 0; }
uint16_t error_count(void) const { return 0; }
bool healthy(void) const { return get_gyro_health() && get_accel_health(); }
protected:
uint8_t get_primary_accel(void) const { return 0; }
virtual uint8_t _get_primary_gyro(void) const { return 0; }
// enable HIL mode
void set_hil_mode(void) { _hil_mode = true; }
// sensor specific init to be overwritten by descendant classes
virtual uint16_t _init_sensor( Sample_rate sample_rate ) = 0;
private:
// no-save implementations of accel and gyro initialisation routines
virtual void _init_accel();
// load backend drivers
void _add_backend(AP_InertialSensor_Backend *(detect)(AP_InertialSensor &));
void _detect_backends(void);
virtual void _init_gyro();
// accel and gyro initialisation
void _init_accel();
void _init_gyro();
#if !defined( __AVR_ATmega1280__ )
// Calibration routines borrowed from Rolfe Schmidt
@ -190,50 +208,98 @@ protected:
// original sketch available at http://rolfeschmidt.com/mathtools/skimetrics/adxl_gn_calibration.pde
// _calibrate_accel - perform low level accel calibration
virtual bool _calibrate_accel(Vector3f accel_sample[6], Vector3f& accel_offsets, Vector3f& accel_scale);
virtual void _calibrate_update_matrices(float dS[6], float JS[6][6], float beta[6], float data[3]);
virtual void _calibrate_reset_matrices(float dS[6], float JS[6][6]);
virtual void _calibrate_find_delta(float dS[6], float JS[6][6], float delta[6]);
virtual void _calculate_trim(Vector3f accel_sample, float& trim_roll, float& trim_pitch);
bool _calibrate_accel(Vector3f accel_sample[6], Vector3f& accel_offsets, Vector3f& accel_scale);
void _calibrate_update_matrices(float dS[6], float JS[6][6], float beta[6], float data[3]);
void _calibrate_reset_matrices(float dS[6], float JS[6][6]);
void _calibrate_find_delta(float dS[6], float JS[6][6], float delta[6]);
void _calculate_trim(Vector3f accel_sample, float& trim_roll, float& trim_pitch);
#endif
// check if we have 3D accel calibration
void check_3D_calibration(void);
// save parameters to eeprom
void _save_parameters();
// Most recent accelerometer reading obtained by ::update
// backend objects
AP_InertialSensor_Backend *_backends[INS_MAX_BACKENDS];
// number of gyros and accel drivers. Note that most backends
// provide both accel and gyro data, so will increment both
// counters on initialisation
uint8_t _gyro_count;
uint8_t _accel_count;
uint8_t _backend_count;
// the selected sample rate
Sample_rate _sample_rate;
// Most recent accelerometer reading
Vector3f _accel[INS_MAX_INSTANCES];
// previous accelerometer reading obtained by ::update
Vector3f _previous_accel[INS_MAX_INSTANCES];
// Most recent gyro reading obtained by ::update
// Most recent gyro reading
Vector3f _gyro[INS_MAX_INSTANCES];
// product id
AP_Int16 _product_id;
// accelerometer scaling and offsets
AP_Vector3f _accel_scale[INS_MAX_INSTANCES];
AP_Vector3f _accel_offset[INS_MAX_INSTANCES];
AP_Vector3f _gyro_offset[INS_MAX_INSTANCES];
AP_Vector3f _accel_scale[INS_MAX_INSTANCES];
AP_Vector3f _accel_offset[INS_MAX_INSTANCES];
AP_Vector3f _gyro_offset[INS_MAX_INSTANCES];
// filtering frequency (0 means default)
AP_Int8 _mpu6000_filter;
AP_Int8 _mpu6000_filter;
// board orientation from AHRS
enum Rotation _board_orientation;
enum Rotation _board_orientation;
// calibrated_ok flags
bool _gyro_cal_ok[INS_MAX_INSTANCES];
// primary accel and gyro
uint8_t _primary_gyro;
uint8_t _primary_accel;
// has wait_for_sample() found a sample?
bool _have_sample:1;
// are we in HIL mode?
bool _hil_mode:1;
// do we have offsets/scaling from a 3D calibration?
bool _have_3D_calibration:1;
// the delta time in seconds for the last sample
float _delta_time;
// last time a wait_for_sample() returned a sample
uint32_t _last_sample_usec;
// target time for next wait_for_sample() return
uint32_t _next_sample_usec;
// time between samples in microseconds
uint32_t _sample_period_usec;
// health of gyros and accels
bool _gyro_healthy[INS_MAX_INSTANCES];
bool _accel_healthy[INS_MAX_INSTANCES];
uint32_t _accel_error_count[INS_MAX_INSTANCES];
uint32_t _gyro_error_count[INS_MAX_INSTANCES];
};
#include "AP_InertialSensor_Oilpan.h"
#include "AP_InertialSensor_Backend.h"
#include "AP_InertialSensor_MPU6000.h"
#include "AP_InertialSensor_HIL.h"
#include "AP_InertialSensor_PX4.h"
#include "AP_InertialSensor_VRBRAIN.h"
#include "AP_InertialSensor_Oilpan.h"
#include "AP_InertialSensor_MPU9250.h"
#include "AP_InertialSensor_L3G4200D.h"
#include "AP_InertialSensor_Flymaple.h"
#include "AP_InertialSensor_MPU9150.h"
#include "AP_InertialSensor_HIL.h"
#include "AP_InertialSensor_UserInteract_Stream.h"
#include "AP_InertialSensor_UserInteract_MAVLink.h"
#include "AP_InertialSensor_Flymaple.h"
#include "AP_InertialSensor_L3G4200D.h"
#include "AP_InertialSensor_MPU9150.h"
#include "AP_InertialSensor_MPU9250.h"
#endif // __AP_INERTIAL_SENSOR_H__

View File

@ -0,0 +1,72 @@
/// -*- tab-width: 4; Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*-
#include <AP_HAL.h>
#include "AP_InertialSensor.h"
#include "AP_InertialSensor_Backend.h"
AP_InertialSensor_Backend::AP_InertialSensor_Backend(AP_InertialSensor &imu) :
_imu(imu),
_product_id(AP_PRODUCT_ID_NONE)
{}
/*
rotate gyro vector and add the gyro offset
*/
void AP_InertialSensor_Backend::_rotate_and_offset_gyro(uint8_t instance, const Vector3f &gyro)
{
_imu._gyro[instance] = gyro;
_imu._gyro[instance].rotate(_imu._board_orientation);
_imu._gyro[instance] -= _imu._gyro_offset[instance];
_imu._gyro_healthy[instance] = true;
}
/*
rotate accel vector, scale and add the accel offset
*/
void AP_InertialSensor_Backend::_rotate_and_offset_accel(uint8_t instance, const Vector3f &accel)
{
_imu._accel[instance] = accel;
_imu._accel[instance].rotate(_imu._board_orientation);
const Vector3f &accel_scale = _imu._accel_scale[instance].get();
_imu._accel[instance].x *= accel_scale.x;
_imu._accel[instance].y *= accel_scale.y;
_imu._accel[instance].z *= accel_scale.z;
_imu._accel[instance] -= _imu._accel_offset[instance];
_imu._accel_healthy[instance] = true;
}
// set accelerometer error_count
void AP_InertialSensor_Backend::_set_accel_error_count(uint8_t instance, uint32_t error_count)
{
_imu._accel_error_count[instance] = error_count;
}
// set gyro error_count
void AP_InertialSensor_Backend::_set_gyro_error_count(uint8_t instance, uint32_t error_count)
{
_imu._gyro_error_count[instance] = error_count;
}
/*
return the default filter frequency in Hz for the sample rate
This uses the sample_rate as a proxy for what type of vehicle it is
(ie. plane and rover run at 50Hz). Copters need a bit more filter
bandwidth
*/
uint8_t AP_InertialSensor_Backend::_default_filter(void) const
{
switch (_imu.get_sample_rate()) {
case AP_InertialSensor::RATE_50HZ:
// on Rover and plane use a lower filter rate
return 15;
case AP_InertialSensor::RATE_100HZ:
return 30;
case AP_InertialSensor::RATE_200HZ:
return 30;
case AP_InertialSensor::RATE_400HZ:
return 30;
}
return 30;
}

View File

@ -0,0 +1,87 @@
// -*- tab-width: 4; Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*-
/*
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
IMU driver backend class. Each supported gyro/accel sensor type
needs to have an object derived from this class.
Note that drivers can implement just gyros or just accels, and can
also provide multiple gyro/accel instances.
*/
#ifndef __AP_INERTIALSENSOR_BACKEND_H__
#define __AP_INERTIALSENSOR_BACKEND_H__
class AP_InertialSensor_Backend
{
public:
AP_InertialSensor_Backend(AP_InertialSensor &imu);
// we declare a virtual destructor so that drivers can
// override with a custom destructor if need be.
virtual ~AP_InertialSensor_Backend(void) {}
/*
* Update the sensor data. Called by the frontend to transfer
* accumulated sensor readings to the frontend structure via the
* _rotate_and_offset_gyro() and _rotate_and_offset_accel() functions
*/
virtual bool update() = 0;
/*
* return true if at least one accel sample is available in the backend
* since the last call to update()
*/
virtual bool accel_sample_available() = 0;
/*
* return true if at least one gyro sample is available in the backend
* since the last call to update()
*/
virtual bool gyro_sample_available() = 0;
/*
return the product ID
*/
int16_t product_id(void) const { return _product_id; }
protected:
// access to frontend
AP_InertialSensor &_imu;
// rotate gyro vector and offset
void _rotate_and_offset_gyro(uint8_t instance, const Vector3f &gyro);
// rotate accel vector, scale and offset
void _rotate_and_offset_accel(uint8_t instance, const Vector3f &accel);
// set accelerometer error_count
void _set_accel_error_count(uint8_t instance, uint32_t error_count);
// set gyro error_count
void _set_gyro_error_count(uint8_t instance, uint32_t error_count);
// backend should fill in its product ID from AP_PRODUCT_ID_*
int16_t _product_id;
// return the default filter frequency in Hz for the sample rate
uint8_t _default_filter(void) const;
// note that each backend is also expected to have a static detect()
// function which instantiates an instance of the backend sensor
// driver if the sensor is available
};
#endif // __AP_INERTIALSENSOR_BACKEND_H__

View File

@ -14,7 +14,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
Flymaple port by Mike McCauley
Flymaple IMU driver by Mike McCauley
*/
// Interface to the Flymaple sensors:
@ -28,20 +28,6 @@
const extern AP_HAL::HAL& hal;
/// Statics
Vector3f AP_InertialSensor_Flymaple::_accel_filtered;
uint32_t AP_InertialSensor_Flymaple::_accel_samples;
Vector3f AP_InertialSensor_Flymaple::_gyro_filtered;
uint32_t AP_InertialSensor_Flymaple::_gyro_samples;
uint64_t AP_InertialSensor_Flymaple::_last_accel_timestamp;
uint64_t AP_InertialSensor_Flymaple::_last_gyro_timestamp;
LowPassFilter2p AP_InertialSensor_Flymaple::_accel_filter_x(800, 10);
LowPassFilter2p AP_InertialSensor_Flymaple::_accel_filter_y(800, 10);
LowPassFilter2p AP_InertialSensor_Flymaple::_accel_filter_z(800, 10);
LowPassFilter2p AP_InertialSensor_Flymaple::_gyro_filter_x(800, 10);
LowPassFilter2p AP_InertialSensor_Flymaple::_gyro_filter_y(800, 10);
LowPassFilter2p AP_InertialSensor_Flymaple::_gyro_filter_z(800, 10);
// This is how often we wish to make raw samples of the sensors in Hz
const uint32_t raw_sample_rate_hz = 800;
// And the equivalent time between samples in microseconds
@ -77,25 +63,39 @@ const uint32_t raw_sample_interval_us = (1000000 / raw_sample_rate_hz);
// Result wil be radians/sec
#define FLYMAPLE_GYRO_SCALE_R_S (1.0f / 14.375f) * (3.1415926f / 180.0f)
uint16_t AP_InertialSensor_Flymaple::_init_sensor( Sample_rate sample_rate )
AP_InertialSensor_Flymaple::AP_InertialSensor_Flymaple(AP_InertialSensor &imu) :
AP_InertialSensor_Backend(imu),
_have_gyro_sample(false),
_have_accel_sample(false),
_accel_filter_x(raw_sample_rate_hz, 10),
_accel_filter_y(raw_sample_rate_hz, 10),
_accel_filter_z(raw_sample_rate_hz, 10),
_gyro_filter_x(raw_sample_rate_hz, 10),
_gyro_filter_y(raw_sample_rate_hz, 10),
_gyro_filter_z(raw_sample_rate_hz, 10),
_last_gyro_timestamp(0),
_last_accel_timestamp(0)
{}
/*
detect the sensor
*/
AP_InertialSensor_Backend *AP_InertialSensor_Flymaple::detect(AP_InertialSensor &_imu)
{
// Sensors are raw sampled at 800Hz.
// Here we figure the divider to get the rate that update should be called
switch (sample_rate) {
case RATE_50HZ:
_sample_divider = raw_sample_rate_hz / 50;
_default_filter_hz = 10;
break;
case RATE_100HZ:
_sample_divider = raw_sample_rate_hz / 100;
_default_filter_hz = 20;
break;
case RATE_200HZ:
default:
_sample_divider = raw_sample_rate_hz / 200;
_default_filter_hz = 20;
break;
AP_InertialSensor_Flymaple *sensor = new AP_InertialSensor_Flymaple(_imu);
if (sensor == NULL) {
return NULL;
}
if (!sensor->_init_sensor()) {
delete sensor;
return NULL;
}
return sensor;
}
bool AP_InertialSensor_Flymaple::_init_sensor(void)
{
_default_filter_hz = _default_filter();
// get pointer to i2c bus semaphore
AP_HAL::Semaphore* i2c_sem = hal.i2c->get_semaphore();
@ -146,12 +146,17 @@ uint16_t AP_InertialSensor_Flymaple::_init_sensor( Sample_rate sample_rate )
hal.scheduler->delay(1);
// Set up the filter desired
_set_filter_frequency(_mpu6000_filter);
_set_filter_frequency(_imu.get_filter());
// give back i2c semaphore
// give back i2c semaphore
i2c_sem->give();
return AP_PRODUCT_ID_FLYMAPLE;
_gyro_instance = _imu.register_gyro();
_accel_instance = _imu.register_accel();
_product_id = AP_PRODUCT_ID_FLYMAPLE;
return true;
}
/*
@ -170,109 +175,46 @@ void AP_InertialSensor_Flymaple::_set_filter_frequency(uint8_t filter_hz)
_gyro_filter_z.set_cutoff_frequency(raw_sample_rate_hz, filter_hz);
}
/*================ AP_INERTIALSENSOR PUBLIC INTERFACE ==================== */
// This takes about 20us to run
bool AP_InertialSensor_Flymaple::update(void)
{
if (!wait_for_sample(100)) {
return false;
}
Vector3f accel_scale = _accel_scale[0].get();
Vector3f accel, gyro;
// Not really needed since Flymaple _accumulate runs in the main thread
hal.scheduler->suspend_timer_procs();
// base the time on the gyro timestamp, as that is what is
// multiplied by time to integrate in DCM
_delta_time = (_last_gyro_timestamp - _last_update_usec) * 1.0e-6f;
_last_update_usec = _last_gyro_timestamp;
_previous_accel[0] = _accel[0];
_accel[0] = _accel_filtered;
_accel_samples = 0;
_gyro[0] = _gyro_filtered;
_gyro_samples = 0;
accel = _accel_filtered;
gyro = _gyro_filtered;
_have_gyro_sample = false;
_have_accel_sample = false;
hal.scheduler->resume_timer_procs();
// add offsets and rotation
_accel[0].rotate(_board_orientation);
// Adjust for chip scaling to get m/s/s
_accel[0] *= FLYMAPLE_ACCELEROMETER_SCALE_M_S;
// Now the calibration scale factor
_accel[0].x *= accel_scale.x;
_accel[0].y *= accel_scale.y;
_accel[0].z *= accel_scale.z;
_accel[0] -= _accel_offset[0];
_gyro[0].rotate(_board_orientation);
accel *= FLYMAPLE_ACCELEROMETER_SCALE_M_S;
_rotate_and_offset_accel(_accel_instance, accel);
// Adjust for chip scaling to get radians/sec
_gyro[0] *= FLYMAPLE_GYRO_SCALE_R_S;
_gyro[0] -= _gyro_offset[0];
gyro *= FLYMAPLE_GYRO_SCALE_R_S;
_rotate_and_offset_gyro(_gyro_instance, gyro);
if (_last_filter_hz != _mpu6000_filter) {
_set_filter_frequency(_mpu6000_filter);
_last_filter_hz = _mpu6000_filter;
if (_last_filter_hz != _imu.get_filter()) {
_set_filter_frequency(_imu.get_filter());
_last_filter_hz = _imu.get_filter();
}
return true;
}
bool AP_InertialSensor_Flymaple::get_gyro_health(void) const
{
if (_last_gyro_timestamp == 0) {
// not initialised yet, show as healthy to prevent scary GCS
// warnings
return true;
}
uint64_t now = hal.scheduler->micros();
if ((now - _last_gyro_timestamp) >= (2 * raw_sample_interval_us)) {
// gyros have not updated
return false;
}
return true;
}
bool AP_InertialSensor_Flymaple::get_accel_health(void) const
{
if (_last_accel_timestamp == 0) {
// not initialised yet, show as healthy to prevent scary GCS
// warnings
return true;
}
uint64_t now = hal.scheduler->micros();
if ((now - _last_accel_timestamp) >= (2 * raw_sample_interval_us)) {
// gyros have not updated
return false;
}
return true;
}
float AP_InertialSensor_Flymaple::get_delta_time(void) const
{
return _delta_time;
}
float AP_InertialSensor_Flymaple::get_gyro_drift_rate(void)
{
// Dont really know this for the ITG-3200.
// 0.5 degrees/second/minute
return ToRad(0.5/60);
}
// This needs to get called as often as possible.
// Its job is to accumulate samples as fast as is reasonable for the accel and gyro
// sensors.
// Cant call this from within the system timers, since the long I2C reads (up to 1ms)
// with interrupts disabled breaks lots of things
// Therefore must call this as often as possible from
// within the mainline and thropttle the reads here to suit the sensors
// Note that this is called from gyro_sample_available() and
// accel_sample_available(), which is really not good enough for
// 800Hz, as it is common for the main loop to take more than 1.5ms
// before wait_for_sample() is called again. We can't just call this
// from a timer as timers run with interrupts disabled, and the I2C
// operations take too long
// So we are stuck with a suboptimal solution. The results are not so
// good in terms of timing. It may be better with the FIFOs enabled
void AP_InertialSensor_Flymaple::_accumulate(void)
{
// get pointer to i2c bus semaphore
@ -285,7 +227,7 @@ void AP_InertialSensor_Flymaple::_accumulate(void)
// Read accelerometer
// ADXL345 is in the default FIFO bypass mode, so the FIFO is not used
uint8_t buffer[6];
uint64_t now = hal.scheduler->micros();
uint32_t now = hal.scheduler->micros();
// This takes about 250us at 400kHz I2C speed
if ((now - _last_accel_timestamp) >= raw_sample_interval_us
&& hal.i2c->readRegisters(FLYMAPLE_ACCELEROMETER_ADDRESS, FLYMAPLE_ACCELEROMETER_ADXLREG_DATAX0, 6, buffer) == 0)
@ -300,7 +242,7 @@ void AP_InertialSensor_Flymaple::_accumulate(void)
_accel_filtered = Vector3f(_accel_filter_x.apply(x),
_accel_filter_y.apply(y),
_accel_filter_z.apply(z));
_accel_samples++;
_have_accel_sample = true;
_last_accel_timestamp = now;
}
@ -317,7 +259,7 @@ void AP_InertialSensor_Flymaple::_accumulate(void)
_gyro_filtered = Vector3f(_gyro_filter_x.apply(x),
_gyro_filter_y.apply(y),
_gyro_filter_z.apply(z));
_gyro_samples++;
_have_gyro_sample = true;
_last_gyro_timestamp = now;
}
@ -325,26 +267,4 @@ void AP_InertialSensor_Flymaple::_accumulate(void)
i2c_sem->give();
}
bool AP_InertialSensor_Flymaple::_sample_available(void)
{
_accumulate();
return min(_accel_samples, _gyro_samples) / _sample_divider > 0;
}
bool AP_InertialSensor_Flymaple::wait_for_sample(uint16_t timeout_ms)
{
if (_sample_available()) {
return true;
}
uint32_t start = hal.scheduler->millis();
while ((hal.scheduler->millis() - start) < timeout_ms) {
hal.scheduler->delay_microseconds(100);
if (_sample_available()) {
return true;
}
}
return false;
}
#endif // CONFIG_HAL_BOARD

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