Revert FIFO_TMST_FSYNC_EN to 0x01. ICM-56686 FIFO_CONFIG4 bit0 is TMST/FSYNC
and bit1 is compression (DS-000563 v1.1); the 45686 bit map does not apply.
Set FIFO_TMST_FSYNC_EN to bit1 (0x02). Power/settle and fifo_reset before FIFO_IF_EN so warmup samples are not retained.
Addresses review notes from tridge on PR #34368.
Follow-up to #33991. The ICM-56686 shares the ICM-456xy user-bank
layout (+4) but not the IREG SRC map. DS-000563 v1.1 places
GYRO_SRC_CTRL at IPREG_SYS1+0x9A (bits 3:2) and ACCEL_SRC_CTRL at
IPREG_SYS2+0x6D (bits 1:0); the 456xy 0xA6/0x7B writes left AAF at
reset.
FIFO_CONFIG2 reserved bits must keep reset 0x20 or checked-register
monitoring marks the IMU unhealthy. PWR_MGMT_AUX1 0x3 enables AUX1
on this part. SREG_CTRL only needs the endian bit cleared so 20-bit
FIFO_HIRES packets remain valid. Soft reset restores SPI pad
overrides. Do not poke 456xy-only IREG (STC, AUX_OVRD) on 56686.
The CoreWing F405 Wing Mini V2 is a compact variant of the
CoreWingF405WingV2. The hwdef inherits from the base target and only
overrides the Mini-specific hardware differences.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The CoreWing F405 Wing V2 is a fixed-wing and QuadPlane/VTOL flight
controller with an STM32F405 MCU, ICM-42688P or BMI270 IMU, SPA06-003
baro, AT7456E OSD, integrated PDB and a USB extender connector for an
optional BLE/WiFi telemetry module.
Co-authored-by: Henry Wurzburg <hwurzburg@yahoo.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
An entry needing exactly as many bytes as the payload holds was treated as
unsendable and dropped. It does fit: AP_HAL::Util::vsnprintf builds its
BufferPrinter with size-1 and then writes the terminator itself at
str[size-1], and the byte that overwrites is the entry's own trailing NUL,
so the encoding which lands in the buffer is the one intended.
Compare against the size rather than allowing it, in all three places, so
the two packing loops still agree on what can never be sent.
The path of the directory being listed is put in front of each entry's
name in order to stat it, with a "/" between. The root's path is already
just "/", so that produced "//name".
Most filesystems collapse that - FatFs skips duplicated separators
(ff.c:3019) and so does littlefs (lfs.c:1503) - but SITL's map_filename()
strips exactly one leading "/", so "//name" escapes to the host root. The
stat then fails, and a failed stat drops the entry, so every file in the
root went missing and the listing came back with directories only.
ArduPilot's own backend_by_path() also strips exactly one leading slash,
so a doubled separator would likewise miss a virtual backend.
The whole reply buffer went out whatever the reply's size, so a short
reply was padded with bytes which are not part of it.
Those bytes come from the same reply, not an earlier one: setup_reply()
clears the whole transaction, but list_dir()'s offset-skip loop then
formats each entry it skips into response.data as scratch, and a listing
which ends in an EndOfFile NAK sets only data[0] - leaving the last
skipped entry sitting behind the error code.
Copy only the bytes the reply says it has. The rest of the packet is
already zero, and since MAVLink 2 trims trailing zeros from a payload, a
short reply now goes out shorter as well.
The scratch reuse behind it is left as it is; not sending the bytes is
what keeps them off the air.
test Renode / cubeorangeplus-quadplane (push) Canceled after 0s
test scripts / build (astyle-cleanliness) (push) Canceled after 0s
test scripts / build (check_autotest_options) (push) Canceled after 0s
test scripts / build (logger_metadata) (push) Canceled after 0s
test scripts / build (param-file-validation) (push) Canceled after 0s
test scripts / build (param_parse) (push) Canceled after 0s
test scripts / build (python-cleanliness) (push) Canceled after 0s
test scripts / build (shellcheck) (push) Canceled after 0s
test scripts / build (validate_board_list) (push) Canceled after 0s
SmartAudio 2.1 reports a variable number of supported power levels. Validate the fixed fields, advertised level count, and CRC instead of requiring the maximum-size response struct.
AP_Baro_MS56XX::_init() fills in the device ID from devtype() before
AP_Baro_MS5837::_init() gets a chance to assign _subtype, so the
devtype byte of BARO*_DEVID was taken from an uninitialised member.
In practice it read back as 0, which ground stations decode as an
UNKNOWN sensor. Pressure was unaffected because _calculate() only runs
once _subtype has been set.
Pick the variant in devtype() from _cal_reg.c1, which the parent has
already read out of PROM by the time it stamps the ID, and drop
_subtype so there is only one source of truth.
Co-authored-by: Cursor <cursoragent@cursor.com>
Unlike the v3 IMUs, where the sensor ODR is programmed to the backend
rate, the v1 FIFO fills at the 8kHz sensor rate when fast sampling and
the backend rate is a software decimation. Reading a non-primary at 2x
loop rate left 20 samples in the FIFO between beats, and with bus
latency on top it reached the depth at which _read_fifo() already
expects corrupt samples: an MPU6000 in the second slot gave a
continuous stream of "stop at 8 of 48" and temperature resets.
Hold a fast-sampling non-primary at 1kHz, one read buffer of samples
per beat, so the FIFO stays well clear of that depth. The 2x loop rate
scaling now only applies without fast sampling, where the FIFO fills at
the backend rate as it does on v3.
Mirror the v3 driver's set_primary(): with the fast rate loop's dynamic
FIFO enabled a non-primary IMU is read at 2x loop rate, bounded to
400..1000Hz, and the primary at the full backend rate. Without the
override the v1 driver ignored primary changes and read every IMU at
the full backend rate.
Reparent airspeed_EAS and get_unconstrained_airspeed_EAS from
AP_AHRS_DCM to AP_AHRS_Backend so backends other than DCM can supply a
synthetic airspeed without DCM compiled in. As with the wind
estimation, the bodies are left in place in AP_AHRS_DCM.cpp - only the
class qualifier and the surrounding guard (AP_AHRS_DCM_ENABLED ->
AP_AHRS_ENABLED) change. _last_airspeed_TAS moves to the base class;
DCM still updates it from drift_correction.
The synthetic estimate is gated on the backend having a ground
velocity from a source independent of airspeed. Callers pass the
backend's published Estimates::have_velocity_source down through
airspeed_TAS/airspeed_EAS; DCM-internal callers pass have_gps()
directly, which is the same fact and the same value the old code
read. The AP::gps() test the base class would otherwise have needed
would be wrong for e.g. ExternalAHRS, which sources velocity from
its own device rather than the autopilot's GPS.
As with the wind-estimation move, the airspeed_sensor_enabled helpers
are now DCM's own (9ed23d57e1), so the moved code tests the airspeed
sensor directly - the same nullptr/use/healthy test, written the way
the frontend's _should_use_airspeed_sensor now does.
Add have_velocity_source to AP_AHRS_Backend::Estimates: true if the
backend has a ground-velocity source that is independent of airspeed
(e.g. GPS), so the value may be used for synthetic airspeed without
circularity. DCM publishes have_gps(). It may be true while
velocity_NED_valid is false (e.g. DCM with a 2D GPS fix).
Reparent the wind-triangle estimator (estimate_wind and
set_external_wind_estimate) from AP_AHRS_DCM to AP_AHRS_Backend so any
backend can run it without DCM compiled in. The method bodies are left
exactly where they are in AP_AHRS_DCM.cpp to preserve their history -
only the class qualifier changes and the surrounding guard switches
from AP_AHRS_DCM_ENABLED to AP_AHRS_ENABLED so they are compiled
whenever AHRS is. Supporting state moves to the base class; DCM keeps
its no-argument estimate_wind wrapper, which passes
_body_dcm_matrix.colx().
One adaptation: the airspeed_sensor_enabled helpers are now DCM's own
(9ed23d57e1), so the straight-flight branch tests the airspeed sensor
directly - the same nullptr/use/healthy test, written the way the
frontend's _should_use_airspeed_sensor now does.
Split estimate_wind into a no-argument wrapper and an implementation
taking the velocity and the fuselage forward direction. The matrix was
only ever used for _body_dcm_matrix.colx() (the trim-corrected body
forward axis in the earth frame), so pass that unit vector in directly
rather than the full attitude matrix. Callers pass
_body_dcm_matrix.colx(); the vector must be a unit vector and is not
normalised here.
original read-twice suffers from beat frequencies where the 50Hz update on the device and the 50Hz update rate of the backend drift relative to one another. The device appears dead when that happens.
guided_above_terrain_posvelaccel_sub.lua integrates its position target
forward by the time since the last callback. When a callback arrived
later than 2/RUN_HZ it substituted 1/RUN_HZ for the real interval:
if (dt > 2.0 / RUN_HZ) then
dt = 1.0 / RUN_HZ
end
so a callback 243ms late advanced the target by 50ms and the remaining
193ms was discarded. The position target then falls behind the clock,
and the vehicle - which tracks that target accurately - covers less
ground than the commanded speed implies.
Measured from a failing Sub.GuidedAboveTerrain run under autotest at
--parallel=16, over the 60 simulated seconds the test watches:
GUIP updates 1047 at 17.2Hz (nominal 20Hz)
late callbacks 76 of 1047 (7.3%), worst 243ms
time discarded 5.82s, so 55.08s integrated of 60.90s elapsed
distance 27.90m of an expected 30.00m, +-1.00m -> failed
The dataflash shows the loss is upstream of the controller, not in it:
the script commanded 0.495m/s and the position controller achieved
0.442m/s against a desired 0.443m/s - it tracked what it was given to
within 0.001m/s, and what it was given was slow.
Cap the step at a fixed MAX_DT instead, so ordinary jitter is
integrated honestly and only a real stall is bounded. Pinning the
simulation speedup was tried first and is not a fix: at
context_set_speedup(10) the run still lost ground, reaching 28.93m,
because it reduces how often callbacks are late without changing what
happens when they are.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Two optional-polish points from Tridge's AI review of this PR: the
imr_interface ternary was redundant (htonl(INADDR_ANY) is 0, same as
mcast_if_addr when unset), and the routing-background comment mostly
duplicated SITL_Multicast.h's own. Simplify and trim.
The review's third suggestion (set IP_MULTICAST_IF before connect(),
matching Socket.cpp's ordering) is not applied here: Socket.cpp reaches
that ordering by creating and connecting the socket inline, with two
separate fds (fd/fd_in) for the send and receive sides.
_udp_start_multicast() instead delegates to the shared
_udp_start_client() for the send-side socket, which creates and
connects _fd as one atomic step with no exposed hook point between
the two -- reordering would mean restructuring that shared helper
(used by other UDP client callers too) for a change the review already
confirmed is behaviour-neutral on both Linux and macOS. Not worth the
risk for a defensive-only change.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Peter Barker's SITL_MULTICAST_IF_ADDR mechanism (see SITL_Multicast.h)
already pins three of SITL's multicast paths -- CAN_Multicast,
SITL_Periph_State's SimMCast, and SITL_State's own general
multicast_state_send()/multicast_state_open() -- to one interface when
set, exactly so a test's result doesn't depend on the state of the
host's network. autotest.py already sets it to 127.0.0.1 for every
SITL it starts. UARTDriver::_udp_start_multicast() -- the generic
--serialN=mcast: transport, used for direct inter-vehicle MAVLink
telemetry by any multi-instance test -- was the one path left on
default (INADDR_ANY) routing.
Pin both directions the same way the existing three paths do: the
receive-side membership's imr_interface, and the send-side socket via
IP_MULTICAST_IF once _udp_start_client() has set _fd up.
I have not been able to fully verify end-to-end reception locally --
this Mac's current multicast routing is unreliable independent of this
change (confirmed via a raw, non-ArduPilot socket test), so local
results here aren't trustworthy either way. The fix is verified
correct by inspection and matches the existing, already-reviewed
pattern in Socket.cpp exactly; wants confirmation on a host with normal
multicast routing (or CI) before relying on it.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
_begin() used to call _set_nonblocking(_fd) unconditionally at the end,
covering every connection type including the UDP client and multicast
paths. b65870fbe7 ("avoid calling fcntl on -1") removed that call and
inlined the equivalent fcntl() at the one call site it actually needed
inlining for -- the physical UART path, where _fd can legitimately be
-1 if the open failed. The UDP paths (_udp_start_client(),
_udp_start_multicast()'s _mc_fd) create their own fd unconditionally
and never got the inlined replacement, so both have been blocking
sockets since that commit.
Restore non-blocking mode at each fd's own creation site rather than
reinstating the shared _begin()-time call, matching the spirit of
b65870fbe7's stated intent (set the mode close to where the fd is
opened) while actually covering all the UDP paths it left uncovered.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This reverts commit 6e7367b86f.
These reductions reduce the usage of the Lua stack, which is stored in
the heap. This reverts back to the stock Lua values; some complex
scripts may desire extra locals. There is some increased risk of memory
fragmentation and so forth but presumably such scripts are prepared.
The actual C stack depth can be limited by `LUAI_MAXCCALLS`.
Hardware revision 1 replaces the IIM-42653 with an LSM6DSV32X on the
same SPI1 CS and DRDY pins. Probe both devices so a single firmware
image supports both revisions.
this is an input to the EKF, but also populated based on the AHRS current state.
Make the data come from the sensor, not the *output* of the AHRS backends!
this is an input to the EKF, but also populated based on the AHRS current state.
Make the data come from the sensor, not the *output* of the AHRS backends!
this is an input to the EKF, but also populated based on the AHRS current state.
Make the data come from the sensor, not the *output* of the AHRS backends!
The Renode physics sidecar needs the SITL aircraft factory without running an ArduPilot vehicle executable. Expose the selected model and explicitly enable model command-line parsing for standalone frontends while preserving the existing example-program behavior. The frontend has static storage, so rely on its guaranteed zero-initialization rather than emitting a redundant member initializer.
The chunk-grouping condition compared msg.compid against
statustext_chunking.last_src_system instead of last_src_component. Since
last_src_component was otherwise write-only, any sender whose compid
differs from its sysid gets a fresh MSG.ID on every chunk, so long
STATUSTEXT messages never reassemble.
Fixes ArduPilot#34281
Each of these "define NAME value" lines creates a macro which no code,
script or ChibiOS source references, so they have no effect:
- ALLOW_ARM_NO_GPS (AeroCogito-H7Digital): no such macro (unlike
ALLOW_ARM_NO_COMPASS, which is consumed by AP_Arming_Copter.cpp)
- AP_BATTERY_TIBQ76952_I2C_DEVICE (VM-L431-BMS): driver uses
AP_BATTMON_TIBQ76952_BUS/_ADDR
- AP_COMPASS_IST8308_DEFAULT_ROTATION (GreenSightUltraBlue): no such
macro; rotation comes from the COMPASS line
- HAL_BLHELI_PASSTHROUGH_ENABLED/_UART and
HAL_ESC_TELEMETRY_UART/_ENABLED (NucleoH753ZI): no such macros
- HAL_CAN_ENABLED, HAL_CAN_NUM_DRIVERS (SkyRukh_Surge_H7): obsolete;
CAN interface count is derived from the CAN pin definitions
- HAL_HEATER3_GPIO_PIN, HAL_HEATER4_GPIO_PIN (rFCU): IMU_heater.cpp
only supports HAL_HEATER_GPIO_PIN and HAL_HEATER2_GPIO_PIN
- HAL_BL_IOMCU_FW_DETECT and HAL_IO_FMU_COMMS_TX_DMA_CHANNEL/
_RX_DMA_STREAM/_RX_DMA_CHANNEL (CubeRedSecondary-IO): iofirmware
only consumes HAL_IO_FMU_COMMS_TX_DMA_STREAM and
HAL_IO_FMU_COMMS_TX_IRQ_PRIORITY, which are retained
- HAL_LED_OFF (OrqaH7QuadCore, SkystarsH7HD bootloaders): bootloader
uses HAL_LED_ON and derives off as !HAL_LED_ON
- HAL_BOOTLOADER_NAME, HAL_BOOTLOADER_BOOT_FROM_SDCARD
(PilotGaeaSH7V1-bdshot): no such macros; SD-card boot would be
AP_BOOTLOADER_FLASH_FROM_SD_ENABLED
- HAL_BUZZER_ON (SIMPLIFLYH7): no buzzer-polarity macro exists
- HAL_NEOPIXEL_COUNT (KakuteF4): no such macro; LED count comes from
the NTF_LED_LEN parameter
- VDD_BRICK2_VALID (sparknavi-blue): only meaningful as a pin label,
which this board does not have; as a bare define it does nothing
- HAL_HEATER_MAG_OFFSET_RM3100 (ZeroOneX6): the consuming
HAL_HEATER_MAG_OFFSET define is commented out, and the offset
vector is zero in any case
All affected boards still process cleanly through chibios_hwdef.py.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
SIM_RATE_HZ is read into the physics step in exactly one place, the tail
of Aircraft::update_dynamics(). Five vehicle models derive from Aircraft
without calling it - they integrate their own simpler models and go
straight to update_position(); time_advance() - so rate_hz stayed at its
1200 default and they ignored both SIM_RATE_HZ and the --rate command
line option built on it: SimRover, BalanceBot, Sailboat and Tracker.
Blimp is a third variant: it assigned rate_hz = sitl->loop_rate_hz but
never recomputed frame_time_us, so time_advance() kept adding the stale
step while rate_hz reported the new value. It now uses the same call as
everything else, which updates both.
Measured on a rover before this change: identical SITL CPU (2.52s vs
2.52s) and identical cost per simulated second (55 sim-s per CPU-s) at
--rate 1200 and --rate 600, despite SIM_RATE_HZ reading back as 600.
After it, the rover gets 361.5 sim-s per CPU-s at 600 against 228.7 at
1200.
The line cannot simply move to update_model(), which every model reaches:
SIM_FlightAxis sets rate_hz in its constructor and a per-frame adjustment
there would slew it away. The external-FDM backends (JSBSim, Gazebo,
XPlane, Webots, Morse, SilentWings, Scrimmage, CRRCSim, JSON) pace
themselves and are deliberately left alone.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>